如何从帖子中删除家长类别固定链接

时间:2017-05-28 作者:Recofa

简单地说,我想做这样的事情。

http://example.com/parent-category/child-category/post-name
变成

http://example.com/child-category/post-name
我找到了一些解决方案,但它们并不完美。例如,我发现这段代码做得几乎正确。

add_filter( \'post_link\', \'remove_parent_category\', 10, 3 );
function remove_parent_category( $permalink, $post, $leavename )
{
$cats = get_the_category( $post->ID );
if ( $cats ) {
    usort( $cats, \'_usort_terms_by_ID\' );
    $category = $cats[0]->slug;
    if ( $parent = $cats[0]->parent ) {
        // Find parent categories and replace them in the link
        $parentcats = get_category_parents( $parent, false, \'/\', true );
        $permalink = str_replace( $parentcats, \'\', $permalink );
    }
}
return $permalink;
}
由于str\\u replace,如果类别具有相似的名称,它会断开链接。喜欢

http://example.com/myhouse/house/post-title
它将从这两个类别中删除house。有人可以修复此代码以使用任何名称吗?

1 个回复
最合适的回答,由SO网友:hwl 整理而成

其中之一str_replacepreg_replace, 在用户端没有一些命名约定,或者在方法的指令中没有一些强大的工作(linked, you can read about patterns here, ), 您将遇到以下问题

House | My House | New House 场景;尤其是当你面对鼻涕虫时,如果那些鼻涕虫是myhousenewhouse.

然后问题就变成了“孙子怎么办?”,以及“如果帖子位于多个子类别中,有不同的家长,而错误的家长位于第一个位置,该怎么办?”$cats 大堆“”

可能的解决方案:过滤permalink以删除父类别对于我上面提到的场景,以下内容似乎对我有用,并且它避免了str_- 和preg_ -全部更换。

通过您的链接示例,我假设:

http://example.com/myhouse/house/post-title

你的permalinks结构是/%category%/%postname%/ 这里的目标是将permalink限制为类别家族和职位中最年轻的成员。所以example.com/child-cat/post-title/example.com/grandchild-cat/post-title

因为我们知道我们只想保留最后两个值,并且我们有永久链接,所以让我们解析它,将路径部分分解为一个数组,计算数组条目,保留最后一个和倒数第二个条目,然后改革永久链接并返回它。

当然,在我们确定要处理一个甚至有子类别的帖子之后。

Something like this maybe:

    add_filter( \'post_link\', \'remove_parent_category\', 10, 3 );
    function remove_parent_category( $permalink, $post, $leavename ) {

         $cats = get_the_category( $post->ID );

         if ( $cats ) {

             foreach ($cats as $cat => $parent) {

               $cat_parent_values[] = $parent->parent; 
             }

             if( array_sum( $cat_parent_values ) > 0 )  {

                 $url_array      = parse_url( $permalink );
                 $url_path       = array_filter( explode( \'/\', $url_array[\'path\'] ) );
                 $url_path      = array_values($url_path);
                 $url_path_count = count( $url_path );

                 $name_slot      = $url_path_count - 1;  
                 $child_cat_slot = $name_slot - 1;

                 $new_url_path[] = \'/\'. $url_path[ $child_cat_slot ];
                 $new_url_path[] = \'/\'. $url_path[ $name_slot ] .\'/\';

                 $new_permalink  = $url_array[\'scheme\'] .\'://\'. $url_array[\'host\'] . $new_url_path[0] . $new_url_path[1];

             }//end if sum > 0
         }//end if $cats

        return $new_permalink;
    }  
对它的初步测试似乎在我这边的新安装上起到了作用,它没有任何stru\\u替换,而是通过了House | MyHouse测试。我相信它可以改进,您必须真正测试它,确保没有任何其他问题/场景破坏它。很可能有一个更好的方法,不涉及过滤永久链接,但我不确定是否可以立即使用。

说明:

首先我们使用get_the_category 就像你已经得到了一个类别对象数组。我们验证我们有一些,然后我们做一个foreach循环array as $key => $value, 将每个值强制转换为新数组。

Wordpress存储parent 对于作为id的类别,该id是(int). 如果没有父级,则会得到0.因此,如果新数组中所有值的总和大于0, 我们至少有一个父类别。这意味着我们的永久链接中至少有一个路径部分需要删除,所以我们继续。

php的parse_url 将为我们提供\'scheme\' => \'http\', \'host\' => \'example.com\', \'path\' => \'/category/child-cat/postname/\'

我们explode() 那个$url_array, 在每个/ 这为我们提供了每个部分的数组。它还为我们提供了一些空数组值,因此我们将其包装在array_filter 希望它能帮我们解决这个问题$url_path. 我们可以使用[array_values()][5] 清除删除的任何丢失的数字键array_filter 给我们[0],[1],[2] 用于三个项目数组中的键。

如前所述,我们假设帖子的名称位于末尾,因此我们使用经过筛选和重新赋值的数组count() 要知道这个数组中有多少个键,并使用它通过减去“一”来查找我们的帖子名称,因为数组从[0]开始。然后从中减去一,我们就得到了“最年轻的类别”。

然后,我们将permalink放回一起,使用$url\\u数组和路径部分作为要保留的帖子名称和类别,忽略其他内容。

然后我们将其返回到post\\u link过滤器。

我在您的示例中注意到了其他可能的问题:您提供的示例还存在其他一些潜在问题:get_the_category() 将返回一个类别对象数组,但如果usort() 用于按其ID排列,如果创建的类别成为现有类别的父类别,则该数组的第一个位置,$cats[0], 不一定是父类别。(除非我误解了_usort_terms_by_id.

目前还不清楚$parent 变量输入if($parent = $cats[0]->parent) 设置为。

结束