我正在尝试使用permalinks设置一个多级自定义帖子类型结构authors/books/chapters
, 作者、书籍和章节都设置为自己的自定义帖子类型。例如,此站点上的典型URL可能如下所示example.com/authors/stephen-king/the-shining/chapter-3/
每一章只能属于一本书,每一本书只能属于一位作者。我考虑过对作者和书籍使用分类法而不是CPT,但我需要将元数据与每个项目关联起来,我更喜欢使用post接口。
大多数情况下,我只需将每个自定义帖子设置为CPT一级中某个条目的子条目。例如,我创建了“Chapter 3”,并使用自定义元框将“The Shining”指定为父级。《闪灵侠》又以《斯蒂芬·金》为父母。我在建立这些关系方面没有遇到任何困难。
我在CPT Slug中使用重写标记,permalinks想要工作,但它们并不完全正确。使用重写分析器,我可以看到重写规则实际上是生成的,但它们的顺序似乎不正确,因此先处理其他规则。
以下是我注册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
过滤器,但这似乎是次要的,以获得正确的永久链接摆在首位。如果有人知道我在哪里可以找到该过滤器工作原理的全面概述,我将不胜感激。
最合适的回答,由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