我有2种自定义帖子类型
Offices
register_post_type(\'offices\',
[
\'labels\' => [
\'name\' => __( \'Offices\' ),
\'singular_name\' => __( \'Office\' )
],
\'description\' => \'Our Office.\',
\'public\' => true,
\'hierarchical\' => true,
\'has_archive\' => false,
\'menu_icon\' => \'dashicons-building\',
\'support\' => [\'title\', \'custom_fields\', \'page-attributes\']
]
);
Office members
//Team Members
register_post_type( \'office_members\',
[
\'labels\' => [
\'name\' => __( \'Team Members\' ),
\'singular_name\' => __( \'Team Member\' )
],
\'description\' => \'Team members for offices.\',
\'public\' => true,
\'hierarchical\' => false,
\'has_archive\' => \'offices/([^/]+)/members\',
\'show_in_menu\' => \'edit.php?post_type=offices\',
\'support\' => [\'title\', \'custom_fields\', \'page-attributes\']
]
);
我希望以下URL正常工作
example.com/offices
- 显示office存档页
example.com/offices/([^/]+)
- 显示单一办公室页面
example.com/offices/([^/]+)/members
- 显示成员存档页,其中父级为办公室
example.com/offices/([^/]+)/members/([^/]+)
- 显示单个成员页面
我对办公室成员有以下重写规则
add_permastruct(\'office_members\', \'/offices/%office%/members/%office_members%\', false, [\'walk_dirs\' => false]);
add_rewrite_tag(\'%office_members%\', \'([^/]+)\', \'office_members=\');
add_rewrite_rule(\'^offices/([^/]+)/members/([^/]+)?\',\'index.php?office_members=$matches[2]\',\'top\');
除“成员存档”页面外,我的所有URL都可用。它加载模板文件
archive-office_members.php
这很好,但它不会在url中检测到父办公室。因此,它不是只显示该办公室的成员,而是显示所有成员。
如何设置url,使其显示成员存档页,但仅显示基于office
在url中,所以我的所有4个url都可以工作?
最合适的回答,由SO网友:Sally CJ 整理而成
首先,您需要注册%office%
重写标记:
// First, add the rewrite tag.
add_rewrite_tag( \'%office%\', \'([^/]+)\', \'post_type=office_members&office_name=\' );
// Then call add_permastruct().
add_permastruct( \'office_members\', ... );
然后,添加自定义
office_name
arg到public查询变量,以便WordPress从URL读取/解析它:
add_filter( \'query_vars\', function ( $vars ) {
$vars[] = \'office_name\';
return $vars;
} );
并使用
pre_get_posts
挂钩以装载正确的
office_members
属于
offices
将段塞插入
office_name
参数:
add_action( \'pre_get_posts\', function ( $query ) {
if ( $query->is_main_query() &&
is_post_type_archive( \'office_members\' ) &&
$slug = $query->get( \'office_name\' )
) {
$arg = ( false !== strpos( $slug, \'/\' ) ) ? \'offices\' : \'name\';
$ids = get_posts( "post_type=offices&{$arg}=$slug&fields=ids" );
if ( ! empty( $ids ) ) {
$query->set( \'post_parent\', $ids[0] );
}
}
} );
现在,members archive页面应该显示正确的帖子,但我们需要修复该页面的分页,因此,我们可以使用
parse_request
挂钩:
add_action( \'parse_request\', function ( $wp ) {
if ( isset( $wp->query_vars[\'paged\'] ) &&
preg_match( \'#^offices/([^/]+)/members/page/(\\d+)#\', $wp->request, $matches )
) {
$wp->query_vars[\'paged\'] = $matches[2];
$wp->query_vars[\'office_name\'] = $matches[1];
}
} );
顺便说一句,你的
register_post_type()
args:您使用
support
, 但正确的参数名称是
supports
(请注意第二个“s”)。