使用自定义分类的永久链接结构CPT失败

时间:2016-04-01 作者:NielsPilon

我对使用自定义分类法为Cutom帖子类型设置正确的URL结构感到非常沮丧。

我有一个自定义的帖子类型,叫做courses 使用名为course-type.

  1. The URL structure should be:site.com/courses/course-type/course-single-post/.
  2. For example: site.com/courses/science/rocket-to-the-moon/
我已经设法做到了这一点,但并不是所有URL部分都能正常工作。

  • site.com/courses/ - 返回404site.com/courses/science/ - 显示一个存档页面,其中包含该自定义分类法中正确的所有帖子site.com/courses/science/rocket-to-the-moon/ - 显示了单个自定义帖子类型,该类型也正确,我不知道为什么site.com/courses/ 返回404而不是显示列出所有自定义帖子类型的存档页。。。?

    This is the code that I\'ve used:

    <?php 
    
    /*Courses Custom Post Type*/
    function my_custom_post_courses() {
    $labels = array(
        \'name\'               => _x( \'Courses\', \'post type general name\' ),
        \'singular_name\'      => _x( \'Course\', \'post type singular name\' ),
        \'add_new\'            => _x( \'New course\', \'reis\' ),
        \'add_new_item\'       => __( \'Add new course\' ),
        \'edit_item\'          => __( \'Edit course\' ),
        \'new_item\'           => __( \'New item\' ),
        \'all_items\'          => __( \'All courses\' ),
        \'view_item\'          => __( \'View courses\' ),
        \'search_items\'       => __( \'Search courses\' ),
        \'not_found\'          => __( \'Nothing found  \' ),
        \'not_found_in_trash\' => __( \'Nothing found in the trash\' ),
        \'parent_item_colon\'  => \'\',
        \'menu_name\'          => \'Courses\'
    );
    $args = array(
        \'labels\'        => $labels,
        \'description\'   => \'Enter a new course\',
        \'public\'        => true,
        \'menu_position\' => 5,
        \'supports\'      => array( \'title\', \'editor\', \'thumbnail\', \'excerpt\', \'comments\' ),
        \'has_archive\'   => true,
        \'hierarchical\'  => true,
        \'rewrite\'       => array(\'slug\' => \'courses/%course-type%\',\'with_front\' => false),
        \'query_var\'     => true,
        //\'rewrite\'     => true,
        //\'publicly_queryable\' => false,
    );
    register_post_type( \'courses\', $args );
    }
    add_action( \'init\', \'my_custom_post_courses\' );
    
    /* Courses custom taxonomy */
    function my_taxonomies_course_type() {
    $labels = array(
        \'name\'              => _x( \'Course type\', \'taxonomy general name\' ),
        \'singular_name\'     => _x( \'Course type\', \'taxonomy singular name\' ),
        \'search_items\'      => __( \'Search course types\' ),
        \'all_items\'         => __( \'All course types\' ),
        \'parent_item\'       => __( \'Parent course type\' ),
        \'parent_item_colon\' => __( \'Parent course type:\' ),
        \'edit_item\'         => __( \'Edit course type\' ),
        \'update_item\'       => __( \'Update course type \' ),
        \'add_new_item\'      => __( \'Add new course type\' ),
        \'new_item_name\'     => __( \'New course type\' ),
        \'menu_name\'         => __( \'Course type\' ),
    );
    $args = array(
        \'labels\' => $labels,
        \'hierarchical\'  => true,
        \'public\'        => true,
        \'query_var\'     => \'course-type\',
        \'rewrite\'       =>  array(\'slug\' => \'courses\' ),
        \'_builtin\'      => false,
    );
    register_taxonomy( \'course-type\', \'courses\', $args );
    }
    add_action( \'init\', \'my_taxonomies_course_type\', 0 );
    
    /* Permalink filter Courses */
    add_filter(\'post_link\', \'course_permalink\', 1, 3);
    add_filter(\'post_type_link\', \'course_permalink\', 1, 3);
    
    function course_permalink($permalink, $post_id, $leavename) {
    if (strpos($permalink, \'%course-type%\') === FALSE) return $permalink;
        // Get post
        $post = get_post($post_id);
        if (!$post) return $permalink;
    
        // Get taxonomy terms
        $terms = wp_get_object_terms($post->ID, \'course-type\');
        if (!is_wp_error($terms) && !empty($terms) && is_object($terms[0]))
            $taxonomy_slug = $terms[0]->slug;
        else $taxonomy_slug = \'no-course-type\';
    
    return str_replace(\'%course-type%\', $taxonomy_slug, $permalink);
    }
    

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

背景has_archivetrue 使WordPress使用重写slug为归档文件生成重写规则,这不是您想要的。相反,将归档段塞显式指定为字符串,并将生成正确的规则:

$args = array(
    \'has_archive\'   => \'courses\',
    \'rewrite\'       => array(\'slug\' => \'courses/%course-type%\',\'with_front\' => false),
    // the rest of your args...
);
register_post_type( \'courses\', $args );

SO网友:Michael Ecklund

使用所需的永久链接URL结构。。。WordPress会自动为您输入的内容创建重写规则(courses/%course-type%) 为您的Post Type slug。当然,您必须修改Post-Type链接,以用实际值替换placeholder(正如您已经做的那样)。

然而,WordPress并不期望Post类型slug中出现这种行为。WordPress通常会期望一些简单的东西,比如courses (而不是courses/%course-type%).

不过没关系,WordPress凭借其惊人的灵活性和定制功能,让我们能够适应几乎任何情况。

您所需要做的就是调整重写规则,以处理Post类型slug的“基”(courses).

这可以通过两个可以粘贴到当前激活的主题中的函数来完成functions.php 文件(或者更理想的情况是…到插件文件中。)

步骤1-调整重写规则

在此步骤中,您请求将新的重写规则添加到现有的重写规则中。在中自动创建新的重写规则mbe_get_new_rewrite_rules(); 作用

if ( ! function_exists( \'mbe_adjust_rewrite_rules\' ) ) {

    function mbe_adjust_rewrite_rules( $rules ) {

        if ( ! function_exists( \'mbe_get_new_rewrite_rules\' ) ) {
            return $rules;
        }

        $new_rules = mbe_get_new_rewrite_rules( \'courses\' );

        return ( $new_rules + $rules );

    }

    add_action( \'rewrite_rules_array\', \'mbe_adjust_rewrite_rules\', 100 );

}
步骤2-创建新的重写规则请注意:此函数需要帖子类型的名称作为参数。

此函数将采用指定的Post类型名称,并自动检索其重写slug(在Post类型注册期间指定)。

然后,此函数将继续检查Post类型slug中是否有任何斜杠。如果找到了一个,它将在第一个斜杠(又名基段塞)之前完成所有操作,并为您的帖子类型的基段塞生成适当的重写规则。(就像您只需指定courses 在后期类型注册期间,而不是courses/%course-type%.)

if ( ! function_exists( \'mbe_get_new_rewrite_rules\' ) ) {

    function mbe_get_new_rewrite_rules( $post_type = \'\' ) {

        $new_rules = array();

        $post_type_object = get_post_type_object( $post_type );

        if ( ! $post_type_object ) {
            return $new_rules;
        }

        $post_type_slug      = $post_type_object->rewrite[\'slug\'];
        $post_type_slug_base = substr( $post_type_slug, 0, strpos( $post_type_slug, \'/\' ) );

        if ( ! empty( $post_type_slug_base ) ) {
            $new_rules["{$post_type_slug_base}/?$"] = "index.php?post_type={$post_type}";
        }

        return $new_rules;

    }

}
给你。三个有效且有效的URL。根据您的要求。

  1. domain.com/courses/
  2. domain.com/courses/course-type/
  3. domain.com/courses/course-type/course-name/
请记住以编程方式刷新重写规则,或访问:Dashboard -> Settings -> Permalinks 使新的重写规则生效。

相关推荐

Force pretty permalinks?

我正在构建一个插件,该插件将用于单个站点,并依赖于add_rewrite_rule 要工作,需要打开永久链接。打开它们并不困难,因为它只是一个站点,但我担心其中一个管理员可能会在不知道自己在做什么的情况下关闭它,并破坏该站点。如何以编程方式强制保持漂亮的永久链接?