问题描述

我正在尝试建立一个 multi-level 自定义后置类型结构,其固定链接看起来像 authors/books/chapters,作者,书籍和章节都设置为自己的自定义帖子类型。例如,此网站上的典型网址可能如 example.com/authors/stephen-king/the-shining/chapter-3/

每章只能属于一本书,每本书只能属于一位作者。我考虑使用分类法而不是 CPT 作为作者和书籍,但是我需要将元数据与每个项目相关联,我更喜欢这个帖子界面。

我最喜欢的方式是简单地将每个自定义帖子设置为 CPT 一个级别的条目的孩子。例如,我创建 「第 3 章」,并使用自定义 meta-box 将”The Shining” 分配为父级。 “The Shining” 依次将”Stephen King” 作为母公司。创造这些关系我没有任何麻烦。

我在 CPT s’m 中使用重写标签,并且固定链接想要工作,但是它们并不完全正确。使用 re-write 分析器,我可以看到重写规则实际上是生成的,但是它们似乎没有正确的顺序,因此先处理其他规则。

以下是我注册了 CPT 的方式:

function cpt_init() {

  $labels = array(
    'name' => 'Authors'
   );

  $args = array(
    'labels' => $labels,
    'public' => true,
    'publicly_queryable' => true,
    'show_ui' => true, 
    'show_in_menu' => true, 
    'query_var' => true,
    'rewrite' => array(
        'slug' => 'author',
        'with_front' => FALSE,
    ),
    'with_front' => false,
    'capability_type' => 'post',
    'has_archive' => false, 
    'hierarchical' => true,
    'menu_position' => null,
    'supports' => array( 'title', 'editor' )
  ); 

  register_post_type('authors',$args);

  $labels = array(
    'name' => 'Books'
  );

  $args = array(
    'labels' => $labels,
    'public' => true,
    'publicly_queryable' => true,
    'show_ui' => true, 
    'show_in_menu' => true, 
    'query_var' => true,
    'rewrite' => array(
        'slug' => 'author/%authors%',
        'with_front' => FALSE,
    ),
    'with_front' => false,
    'capability_type' => 'post',
    'has_archive' => false, 
    'hierarchical' => true,
    'menu_position' => null,
    'supports' => array( 'title', 'editor' )
  ); 

  register_post_type('books',$args);


  $labels = array(
    'name' => 'Chapters'
   );

  $args = array(
    'labels' => $labels,
    'public' => true,
    'publicly_queryable' => true,
    'show_ui' => true, 
    'show_in_menu' => true, 
    'query_var' => true,
    'rewrite' => array(
        'slug' => 'author/%authors%/%books%',
        'with_front' => FALSE,
    ),
    'with_front' => FALSE,
    'capability_type' => 'post',
    'has_archive' => false, 
    'hierarchical' => true,
    'menu_position' => null,
    'supports' => array( 'title', 'editor' )
  ); 

  register_post_type('chapters',$args);

}

add_action( 'init', 'cpt_init' );

那么有什么办法可以改变我的重写规则的优先级,以便作者,书籍和章节都首先匹配?

我也知道我将要添加一个 post_type_link 过滤器,但这似乎是次要的获得固定链接在第一位。如果有人知道在哪里可以找到关于该过滤器如何工作的全面概述,那将不胜感激。

最佳解决方案

如果你想保持’ 作者’ 为固定链接的基础,例如 example.com/authors/stephen-king/为’ 作者’CPT,example.com/authors/stephen-king/the-shining/为’ 书’CPT 和例子.com /authors /stephen-king /the-shining /chapter-3 /对于 「章节」CPT,WordPress 会认为几乎所有的都是 「作者」 帖子或 「作者」 帖子的等级小孩,因为不是这样 WordPress 最终变得非常困惑。

就这样说,有一个相当基本的解决方法,但是只要你的永久链接结构总是遵循相同的顺序,即’authors’ 这个词总是跟着一个作者的 s,,后面是一个书呆子,它总是跟着一个一章 s lug,那么你应该很好去。

在此解决方案中,无需在’chapters’ 和’books’ 的自定义后期类型定义中定义重写段,但将’authors’ 重写块作为简单的’authors’ 设置,将以下代码放在您的 functions.php 文件和”flush” 中您的重写规则。

add_action( 'init', 'my_website_add_rewrite_tag' );
function my_website_add_rewrite_tag() {
    // defines the rewrite structure for 'chapters', needs to go first because the structure is longer
    // says that if the URL matches this rule, then it should display the 'chapters' post whose post name matches the last slug set
    add_rewrite_rule( '^authors/([^/]*)/([^/]*)/([^/]*)/?','index.php?chapters=$matches[3]','top' );
    // defines the rewrite structure for 'books'
    // says that if the URL matches this rule, then it should display the 'books' post whose post name matches the last slug set
    add_rewrite_rule( '^authors/([^/]*)/([^/]*)/?','index.php?books=$matches[2]','top' );   
}

// this filter runs whenever WordPress requests a post permalink, i.e. get_permalink(), etc.
// we will return our custom permalink for 'books' and 'chapters'. 'authors' is already good to go since we defined its rewrite slug in the CPT definition.
add_filter( 'post_type_link', 'my_website_filter_post_type_link', 1, 4 );
function my_website_filter_post_type_link( $post_link, $post, $leavename, $sample ) {
    switch( $post->post_type ) {

        case 'books':

            // I spoke with Dalton and he is using the CPT-onomies plugin to relate his custom post types so for this example, we are retrieving CPT-onomy information. this code can obviously be tweaked with whatever it takes to retrieve the desired information.
            // we need to find the author the book belongs to. using array_shift() makes sure only one author is allowed
            if ( $author = array_shift( wp_get_object_terms( $post->ID, 'authors' ) ) ) {
                if ( isset( $author->slug ) ) {
                    // create the new permalink
                    $post_link = home_url( user_trailingslashit( 'authors/' . $author->slug . '/' . $post->post_name ) );
                }
            }

            break;

        case 'chapters':

            // I spoke with Dalton and he is using the CPT-onomies plugin to relate his custom post types so for this example, we are retrieving CPT-onomy information. this code can obviously be tweaked with whatever it takes to retrieve the desired information.
            // we need to find the book it belongs to. using array_shift() makes sure only one book is allowed
            if ( $book = array_shift( wp_get_object_terms( $post->ID, 'books' ) ) ) {

                // now to find the author the book belongs to. using array_shift() makes sure only one author is allowed
                $author = array_shift( wp_get_object_terms( $book->term_id, 'authors' ) );

                if ( isset( $book->slug ) && $author && isset( $author->slug ) ) {
                    // create the new permalink
                    $post_link = home_url( user_trailingslashit( 'authors/' . $author->slug . '/' . $book->slug . '/' . $post->post_name ) );
                }

            }

            break;

    }
    return $post_link;
}

Learn more about the CPT-onomies plugin

次佳解决方案

我没有这样的场景的个人经验,但 Randy Hoyt 上周末在 WordCamp San Fran 做了一个演讲,就像你在说的 「下属类型」 一样。

这是他的演讲页面,其中包括他的演示幻灯片和链接到一个插件,他为下属的职位类型工作:http://randyhoyt.com/wordpress/subordinate-post-types/

参考文献

注:本文内容整合自 Google/Baidu/Bing 辅助翻译的英文资料结果。如果您对结果不满意,可以加入我们改善翻译效果:薇晓朵技术论坛。