带有固定链接的嵌套自定义帖子类型

时间:2012-08-07 作者:Dalton Rooney

我正在尝试使用permalinks设置一个多级自定义帖子类型结构authors/books/chapters, 作者、书籍和章节都设置为自己的自定义帖子类型。例如,此站点上的典型URL可能如下所示example.com/authors/stephen-king/the-shining/chapter-3/

每一章只能属于一本书,每一本书只能属于一位作者。我考虑过对作者和书籍使用分类法而不是CPT,但我需要将元数据与每个项目关联起来,我更喜欢使用post接口。

大多数情况下,我只需将每个自定义帖子设置为CPT一级中某个条目的子条目。例如,我创建了“Chapter 3”,并使用自定义元框将“The Shining”指定为父级。《闪灵侠》又以《斯蒂芬·金》为父母。我在建立这些关系方面没有遇到任何困难。

我在CPT Slug中使用重写标记,permalinks想要工作,但它们并不完全正确。使用重写分析器,我可以看到重写规则实际上是生成的,但它们的顺序似乎不正确,因此先处理其他规则。

Here's a screenshot of my rewrite analyzer.

以下是我注册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 过滤器,但这似乎是次要的,以获得正确的永久链接摆在首位。如果有人知道我在哪里可以找到该过滤器工作原理的全面概述,我将不胜感激。

3 个回复
最合适的回答,由SO网友:Rachel Carden 整理而成

如果你想把“作者”作为永久链接中的基本元素,例如示例。com/authors/stephenking/为“作者”CPT,示例。com/authors/stephenking/the shining/为“books”CPT和示例。com/authors/stephenking/the shining/chapter-3/对于“chapters”CPT,WordPress会认为几乎所有东西都是“authors”帖子或“authors”帖子的分级子帖子,但事实并非如此,WordPress最终会变得非常困惑。

话虽如此,有一个很基本的解决方法,但只要你的永久链接结构始终遵循相同的顺序,即“authors”一词后面总是跟一个author slug,它后面总是跟一个book slug,它后面总是跟一个chapter slug,那么你就应该很好了。

在这个解决方案中,不需要在“chapters”和“books”的自定义post类型定义中定义重写段塞,只需将“authors”重写段塞设置为简单的“authors”,在函数中放置以下代码。php文件并“刷新”您的重写规则。

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

SO网友:mannieschumpert

我个人对这种情况没有经验,但兰迪·霍伊特(RandyHoyt)上周末在旧金山WordCamp做了一个关于“下属职位类型”的演讲,听起来就像你所说的那样。

以下是他的演讲页面,其中包括他的演示幻灯片和他为处理下属帖子类型而构建的插件链接:http://randyhoyt.com/wordpress/subordinate-post-types/

SO网友:prettyboymp

这些规则将按照添加额外磁导率的顺序添加到WP\\u Rewrite的extra\\u rules\\u顶部。因此,切换注册帖子类型的顺序将切换生成的重写规则的顺序,使章节重写首先匹配。但是,由于您使用的是来自其他post\\u类型的query\\u var,因此wp\\u查询可能会在匹配所需章节之前,将其中一个作为查询的post名称进行匹配。

我会创建新的重写标记来表示父作者和父书籍的占位符,即:

add_rewrite_tag(\'%parent-book%\', \'([^/]+)\', \'parent_book=\');
执行此操作时,您必须筛选“query\\u vars”以将“parent\\u book”公开。然后,您需要为pre\\u get\\u posts添加一个过滤器,该过滤器将把设置为parent\\u book query\\u var的名称转换为post\\u id,并将其设置为“post\\u parent”。

结束

相关推荐

Permalinks Won't Work

由于某种原因,永久物不会起作用。我单击选项3的单选按钮,然后单击保存,但它会返回到选项1。发生什么事了?(这不应该是FTP问题-它有本地主机访问数据库的权限,我可以在Wordpress fine中下载插件。)