我正在添加这样一个自定义帖子类型(名称已更改以保护无辜者):
add_action(\'init\', \'my_post_types\');
function my_post_types() {
register_post_type(\'publication\',
array(
\'labels\' => array(...),
\'rewrite\' => array(
\'slug\' => \'publications/%year%\',
\'with_front\' => true
),
\'public\' => true,
\'menu_position\' => 21,
\'supports\' => array(\'title\', \'editor\', \'author\', \'excerpts\', \'revisions\', \'thumbnail\'),
\'show_ui\' => true,
));
}
通过这些设置,我希望给定出版物的URL为:
/publications/2012/name-of-publication
但是,生成的URL
get_permalink()
具体表现为:
/publication/name-of-publication
WordPress可以识别所需的URL模式,但只需重定向到较低的URL即可。此URL确实显示所需的页面。
我尝试了常见的建议解决方案:
确保register_post_type
在init
操作,所以创建它不会太晚通过访问永久链接设置页面刷新重写规则。我还尝试在每个页面上使用$wp_rewrite->flush_rules()
, 但那是pointlessly expensive 事实上更改的值with_front
没有效果。我没想到会这样,因为网站位于/
, 不在子文件夹中取出%year%
slug的一部分也没有效果,因此它不会导致重写规则失败我没有安装重定向插件。这是一个已知的URL麻烦制造者如有必要,我可以截取WordPress的路由并强制其提供正确的页面,并使用过滤器从中返回正确的URLget_permalink
, 但这似乎是错误的解决方案。在注册帖子类型时设置重写规则是正确的解决方案。我做错什么了吗?
SO网友:Marcus Downing
我在问题中提到的不受欢迎的答案是拦截WordPress的路由和URL生成。使用以下内容操作URL:
add_filter(\'post_type_link\', \'my_post_link\', 10, 3);
function my_post_link($permalink, $post, $leavename) {
if ($post->post_type == \'publication\') {
$year = date(\'Y\', strtotime($post->post_date));
return site_url("/publications/$year/$post->post_name");
}
return $permalink;
}
然后拦截路由:
add_action(\'template_redirect\', \'my_template_redirect\');
function my_template_redirect() {
if (preg_match(\'!^/publications/([0-9]+)/([a-z0-9-]+)/?!i\', $uri, $matches)) {
$year = $matches[1];
$publication = $matches[2];
$ps = get_posts(array(
\'post_type\' => \'publication\',
\'year\' => $year,
\'name\' => $publication,
\'numberposts\' => 1,
));
if (!empty($ps)) {
global $post;
$post = array_shift($ps);
setup_postdata($post);
global $wp_query;
$wp_query->is_404 = false;
include(get_stylesheet_directory().\'/single-publication.php\');
exit;
}
}
}
这是可行的,但是
ugly and nasty!. 还有其他的方法,包括使用WordPress的重写表,但这些方法也不太理想。如果可能的话,我想找到一个更好的解决方案。