我正在为一家文学杂志创建一个相当复杂的网站。对于其自定义的post类型Issue和Event,我需要与post不同的permalink结构(这是基本的http://example.com/%postname%).
我的任务并不容易,我已经设法想出了一个解决方案,尽管这是一个非常扭曲的问题。由于我不确定这是否理想,我很想听听WP用户的意见,他们了解内部$wp_query
比我做得好。如果WP Stackexchange不适合进行代码审查,请在其他地方向我咨询。
我需要实现以下目标:
URL反映与CPT相关的日期,例如http://example.com/event/%eventyear%/%eventmonth%/%postname% 和http://example.com/event/%year%/%issue-num%可以复制URL的最后一部分,例如http://example.com/issue/2016/5 和http://example.com/issue/2015/5http://example.com/issue/2012.
$cpt_args = array(
\'label\' => \'Issue\',
\'hierarchical\' => false,
\'has_archive\' => true,
\'rewrite\' => array(\'slug\' => \'issue/%issueyear%\'),
);
然后,我注册了我的重写标签:
add_action(\'init\', function() use ($tags) {
add_rewrite_tag("%issueyear%");
});
然后,我已将我的“%issueyear%”的“重写标记翻译”注册到自定义元值:
$func = function($permalink, $post) {
if (strpos($permalink, "%issueyear%")) {
$tags_used[] = $t;
}
$issue_start = get_post_meta($post->ID, \'t_issue_start\', true);
$old = basename($permalink);
$new = $this->date->get_time(\'Y\', $issue_start);
$permalink = str_replace($old, $new, $permalink);
return $permalink;
};
add_action(\'post_link\', $func, 10, 2);
add_action(\'post_type_link\', $func, 10, 2);
然后,我添加了重写规则,将元值传递给URL。
add_action(\'init\', function() {
add_rewrite_rule(
"^issue/([0-9]{4})/([0-9]{1,})/?",
\'index.php?post_type=issue&year=$matches[1]&cibulka_key=cibulka_slug&cibulka_val=$matches[2]\',
\'top\'
);
};
add_action(\'query_vars\', function($vars) {
$vars[] = \'cibulka_key\';
$vars[] = \'cibulka_val\';
return $vars;
});
URL地址
http://example.com/2016/5
会给我档案。php模板。因此,我包括了单个模板,如果
$wp_query
有
cibulka_key
设置
include_template_with_var
是我的函数,允许向模板传递参数。
/** Archive.php */
global $wp_query;
if (isset($wp_query->query[\'cibulka_key\'])) {
$meta_value = $wp_query->query[\'cibulka_val\'] . \'_\' . $wp_query->query[\'year\'];
$args = array(
\'post_type\' => $wp_query->query[\'post_type\'],
\'meta_key\' => $wp_query->query[\'cibulka_key\'],
\'meta_value\' => $meta_value,
\'posts_per_page\' => 1
);
$posts = get_posts($args);
if (!empty($posts)) {
$data = array(
\'id\' => $posts[0]->ID,
\'post\' => $posts[0]
);
} else {
$data = array();
}
include_template_with_var(\'single.php\', $data);
} else {
// Do normal archive stuff
}
帖子的单个模板
$data[\'id\']
提供而不是存档。php。
Note: 这不是我的实际代码,为了回答我的问题,我对它进行了很多简化。
这达到了我需要达到的所有4点,但我不确定这是否是正确的方法-从性能角度(将有很多事件)、标准角度等等。因此,在我坚持使用此解决方案之前(因为它将产生相当严重的后果,正如设置URL方案一样),我想听听一些意见。
到目前为止,我发现了这些注意事项:
WP识别上的内容http://example.com/issue/5 作为archive
, 即使它应该是single
. 所以is_single()
, is_single(\'issue\')
回来false
以及body_class()
令人困惑当更多的人出现时,我会将他们添加到这里。
提前多谢了!
编辑1我已从存档中删除了条件。php并将其替换为过滤器。这解决了警告1,并从我的模板中删除了逻辑。耶!
// Change global `wp_query` to retrieving the post by meta query AND mark it as single (not archive)
add_action(\'pre_get_posts\', function() {
global $wp_query;
if (!isset($wp_query->query[\'cibulka_key\'])) { return; }
switch ($wp_query->query[\'post_type\']) {
case \'issue\':
$meta_value = $wp_query->query[\'cibulka_val\'] . \'_\' . $wp_query->query[\'year\'];
break;
}
$wp_query->set(\'meta_key\', $wp_query->query[\'cibulka_key\']);
$wp_query->set(\'meta_value\', $meta_value);
$wp_query->is_singular = true;
$wp_query->is_single = true;
$wp_query->is_archive = false;
remove_all_actions ( \'__after_loop\');
});
// Use single.php rather than archive.php, if global `$wp_query` contains my custom properties
add_filter(\'template_include\', function($template) {
global $wp_query;
if (!isset($wp_query->query[\'cibulka_key\'])) { return $template; }
$single_tmplt = locate_template(\'single.php\');
return $single_tmplt;
});
出于某种原因
body_class()
不增加
single-issue
CSS类,但这没什么。。。
add_filter(\'body_class\', function($body_class) {
if (is_single() && get_post_type() === \'issue\') {
$body_class[] = \'single-issue\';
}
return $body_class;
}, 11, 1);
。。。无法修复。:)