在浏览了可能有我的答案的问题后,我似乎仍然找不到我引用的后模板php文件。
我有两种自定义的帖子类型,我正试图将它们合并为一种帖子类型。我将把自定义帖子类型称为“Client”和“Project”。我所做的是创建一个“客户&;项目的自定义帖子类型,并将“客户端”中的每一个设置为父级,将后续的“项目”设置为“客户端”中的子级;“项目”。
我已经创建了PHP模板,它们可以单独用于每种帖子类型,但我不知道如何设置一个模板来为“客户端”(父帖子)加载,另一个模板来为“项目”(子帖子)加载。
文件的命名如下:
客户端将是客户端\\u项目\\u父级。php项目将是clients\\u Projects\\u child。php我找到了这个代码片段here, 但这并没有解决我的问题。
function switch_page_template() {
global $post;
// Checks if current post type is a page, rather than a post
if (is_page()){
// Checks if page is parent, if yes, return
if ($post->post_parent == 0)
return true;
else if ($post->post_parent != $post->ID){
$parent_page_template = get_post_meta($post->post_parent,\'_wp_page_template\',true);
$template = TEMPLATEPATH . "/{$parent_page_template}";
if (file_exists($template)) {
load_template($template);
exit;
}
}
}
}
add_action(\'template_redirect\',\'switch_page_template\');
我的最终希望是,每个父帖子和子帖子分别加载不同的PHP模板。
Update:
我在四处摸索,试着这样做:
add_action(\'template_redirect\', \'get_template\');
function get_template(){
global $wp;
global $wp_query;
if(is_page(\'client_project\') || \'0\' === $post->post_parent){
include(TEMPLATEPATH . \'/single-client_project.php\');
}elseif(is_page(\'client_project\') || $post->post_parent > 0){
include(TEMPLATEPATH . \'/single-client_project_child.php\');
}
else{
include(TEMPLATEPATH . \'/single-client_project.php\');
}
}
我在试图调用/重定向的模板中放置了一个条件语句,如下所示:
global $post;
if ( is_page(\'client_project\') || \'0\' == $post->post_parent ) {
echo "<h1>This is a parent page</h1>";
echo "<p>post parent = " . $post->post_parent . "</p>";
} else {
echo "<h1>This is a child page</h1>";
echo "<p>post parent = " . $post->post_parent . "</p>";
}
现在,当帖子加载时,每个帖子都从放置在模板文件中的回音循环中给出了正确的指示,即父帖子打印“这是一个父页面”,并给出了正确的帖子父编号,但模板仍然加载错误(即父模板或子模板并没有为每种类型加载每个帖子)。。。
我只是在似乎所有其他方法都失败后才尝试这种方法。我肯定我错过了什么,但我真的想不出来。
FINAL UPDATE:
我终于得到了要交换的模板。虽然这是我只能想象的最糟糕的方式。我基本上进入了“父”模板,并在页面的代码之前放置了一个if语句。看起来是这样的:
<?php
global $post;
if(is_page(\'client_project\') || $post->post_parent > 0){
include(TEMPLATEPATH . \'/single-client_project-child.php\');
}
?>
在我完成这项工作后,我读到TEMPLATEPATH被贬值了,所以我很可能会把它换掉,但我将把这个问题称为回答:@G.M。如果你愿意,我非常感谢你写下正确的方法,或者至少是更好的方法。我邀请所有遇到这个问题的人也这样做。奶酪!
最合适的回答,由SO网友:gmazzap 整理而成
最简单的方法是使用single_template
过滤器挂钩(其中一个{$type}_template
hooks).
WordPress会启动它来过滤找到的单个post请求的模板文件。
add_filter(\'single_template\', function($template) {
$queried = get_queried_object();
if ( $queried->post_type === \'clients_projects\' ) { // only for this CPT
// file name per OP requirements
$file = \'clients_projects_\';
$file .= $queried->post_parent ? \'child\' : \'parent\';
// using `locate_teplate` to be child theme friendly
return locate_template("{$file}.php") ? : $template;
}
return $template;
});
当您访问WordPress站点上的url时,WordPress将该url转换为一组查询参数,并使用它们触发数据库查询。
有不同类型的查询,针对页面、归档、帖子等。看看Conditional Tags page 在Codex上,对所有查询类型都有详尽的描述。
在你的情况下,你需要瞄准single 查询类型,因为您要更改在需要单个CPT时使用的模板。
触发查询后,WordPress会查看主题文件夹以查找用于显示查询结果的模板。看看template hierarchy 了解用于每种查询类型的文件。
当找到一个文件时,在实际包含该文件之前,WordPress会使用2个过滤器对其进行过滤。
"{$type}_template"
这是动态的,每种类型的查询都会发生变化\'template_include\'
这将为所有模板激发在上面的代码中,我使用了\'single_template\'
WordPress将加载用于更改模板的筛选器,从附加到该筛选器的回调返回不同的模板。但是,该过滤器是为every 单个请求,即使是标准帖子和其他CPT,所以在更改模板之前,我检查了当前查询的帖子是否是我们想要的目标CPT之一。获取我使用的当前查询帖子[get_queried_object()][6]
单数请求返回post对象。
如果当前帖子不是目标帖子类型,我只返回WordPress找到的文件,不做任何更改。
如果当前帖子是目标帖子类型之一,我将构建模板名称,查看post_parent
帖子属性:如果帖子有我构建的父级\'clients_projects_child.php\'
如果帖子没有父级,我将返回\'clients_projects_parent.php\'
.
在实际返回模板文件之前,我使用locate_template
查看该模板文件是否存在于主题(或子主题)中。如果存在,我返回它,用这种方式WordPress而不是加载默认模板加载自定义模板,如果模板不存在,我返回默认模板,即WordPress找到的模板。