我们目前可以执行以下操作:
/>
页面-{slug} .php
但是我希望能够做到这一点:
single- {post_type}-{slug} .php
因此,例如,在名为
review
的帖子类型中,我可以为名为“我的伟大”的帖子制作模板请参阅single-review-my-great-review.php
上的“评论”。以前有人设置过吗?
single-{post_type}-{slug}.php
#1 楼
A)核心基础在Codex模板层次结构说明中可以看到,已经支持
single-{$post_type}.php
。B)扩展核心层次结构
现在很高兴在
/wp-includes/template-loader.php
内有一些过滤器和钩子。 B.1)工作方式
在模板加载器文件中,模板由条件var / wp_query查询加载:
do_action('template_redirect');
。然后条件触发(如果是“单个”模板):
apply_filters( 'template_include', $template )
然后触发
get_query_template( $type, ... )
,其中"$type}_template"
是is_*()
那么我们有了
is_single() && $template = get_single_template()
过滤器C)解决方案
由于我们只想使用在实际
get_query_template( $type, $templates )
模板之前加载的一个模板扩展层次结构,因此我们将拦截层次结构并将新模板添加到模板数组的开头。// Extend the hierarchy
function add_posttype_slug_template( $templates )
{
$object = get_queried_object();
// New
$templates[] = "single-{$object->post_type}-{$object->post_name}.php";
// Like in core
$templates[] = "single-{$object->post_type}.php";
$templates[] = "single.php";
return locate_template( $templates );
}
// Now we add the filter to the appropriate hook
function intercept_template_hierarchy()
{
add_filter( 'single_template', 'add_posttype_slug_template', 10, 1 );
}
add_action( 'template_redirect', 'intercept_template_hierarchy', 20 );
<注释:(如果您要使用默认对象以外的其他东西),则必须根据固定链接结构调整$type
。只需使用全局single
中的任何内容即可。火车票清单:使用post_type-> slug扩展层次结构
引入
"{$type}_template"
的过滤器过滤整个层次结构-最有希望票证&lBarr; @scribu以cc
的身份将此票关注
评论
我想对此进行测试,但看起来您的add_filter行最后缺少一些内容。
–超真实
2012年2月2日在20:45
@supertrue好抓住。 :)在过滤器中发现另一个缺少的)。固定。也许您想在模板内的嵌条之前用下划线替换破折号。只是为了在查看模板时使后缀更加突出。
– kaiser
2012年2月2日在22:01
在整个网站上导致此错误:警告:array_unshift()[function.array-unshift]:第一个参数应该是[包含array_unshift的行中的一个数组
–超真实
2012年2月4日,0:02
好的,但是接下来还有其他事情要拦截核心模板。该函数可以正常工作,并且$ templates是一个数组。请参阅此pastebin中的核心功能(无有效期)。确保使用不带插件和默认主题的安装进行测试。然后一个接一个地激活,看看错误是否仍然出现。
– kaiser
2012年2月4日在0:47
是的,我调试了这个,我得到了第一个找到的模板的最终绝对路径作为字符串。在更改答案之前,我将不得不与一些核心开发人员进行讨论。另外:我混合了一些东西:子词仅适用于术语和分类法。您应该用适合您的永久链接结构的方式替换$ post-> post_name。当前,无法根据情况永久地自动执行此操作,这取决于您的永久结构和重写规则。期待另一个更新。
– kaiser
2012年2月4日在1:19
#2 楼
在“模板层次结构”图像之后,我看不到这样的选项。以下是我的处理方法:
解决方案1(我认为最好)
制作模板文件并将其关联到评论
<?php
/*
Template Name: My Great Review
*/
?>
将模板php文件添加到主题目录中,它将作为模板选项出现在帖子的编辑页面中。
解决方案2
可以使用
template_redirect
钩子来实现。编辑添加了
file_exists
检查评论
你为什么要退出?那里?
– kaiser
2012年2月2日在18:26
@kaiser一定在我当时遵循的任何教程中,如果没有必要,我将其删除。
– Shane
2012年2月2日,19:48
@kaiser:exit()对于防止加载默认模板是必需的。
–抄写员
2012年2月3日,0:30
解决方案1仅适用于页面,不适用于帖子。
–IXN
2015年11月7日,12:18
#3 楼
最佳答案(来自4年前)不再起作用,但是WordPress代码库在此处提供了解决方案:<?php
function add_posttype_slug_template( $single_template )
{
$object = get_queried_object();
$single_postType_postName_template = locate_template("single-{$object->post_type}-{$object->post_name}.php");
if( file_exists( $single_postType_postName_template ) )
{
return $single_postType_postName_template;
} else {
return $single_template;
}
}
add_filter( 'single_template', 'add_posttype_slug_template', 10, 1 );
?>
#4 楼
使用页面模板另一种可扩展性的方法是将
page
帖子类型上的页面模板下拉功能复制为自定义帖子类型。 可重用的代码
代码中的重复不是一个好习惯。超时会导致代码库严重膨胀,从而使开发人员难以管理。除了很可能不需要为每个块创建模板之外,您还可能需要可以重用的一对多模板,而不是一对一的后置模板。
代码
# Define your custom post type string
define('MY_CUSTOM_POST_TYPE', 'my-cpt');
/**
* Register the meta box
*/
add_action('add_meta_boxes', 'page_templates_dropdown_metabox');
function page_templates_dropdown_metabox(){
add_meta_box(
MY_CUSTOM_POST_TYPE.'-page-template',
__('Template', 'rainbow'),
'render_page_template_dropdown_metabox',
MY_CUSTOM_POST_TYPE,
'side', #I prefer placement under the post actions meta box
'low'
);
}
/**
* Render your metabox - This code is similar to what is rendered on the page post type
* @return void
*/
function render_page_template_dropdown_metabox(){
global $post;
$template = get_post_meta($post->ID, '_wp_page_template', true);
echo "
<label class='screen-reader-text' for='page_template'>Page Template</label>
<select name='_wp_page_template' id='page_template'>
<option value='default'>Default Template</option>";
page_template_dropdown($template);
echo "</select>";
}
/**
* Save the page template
* @return void
*/
function save_page_template($post_id){
# Skip the auto saves
if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE )
return;
elseif ( defined( 'DOING_AJAX' ) && DOING_AJAX )
return;
elseif ( defined( 'DOING_CRON' ) && DOING_CRON )
return;
# Only update the page template meta if we are on our specific post type
elseif(MY_CUSTOM_POST_TYPE === $_POST['post_type'])
update_post_meta($post_id, '_wp_page_template', esc_attr($_POST['_wp_page_template']));
}
add_action('save_post', 'save_page_template');
/**
* Set the page template
* @param string $template The determined template from the WordPress brain
* @return string $template Full path to predefined or custom page template
*/
function set_page_template($template){
global $post;
if(MY_CUSTOM_POST_TYPE === $post->post_type){
$custom_template = get_post_meta($post->ID, '_wp_page_template', true);
if($custom_template)
#since our dropdown only gives the basename, use the locate_template() function to easily find the full path
return locate_template($custom_template);
}
return $template;
}
add_filter('single_template', 'set_page_template');
这是一个较晚的答案,但我认为这将是有价值的,因为据我所知,网络上尚无人记录这种方法。希望这可以帮助某人。
#5 楼
就我而言,我具有“专辑”分类法链接的“专辑”和“曲目”自定义帖子类型。我希望能够根据专辑分类法对专辑和曲目帖子使用不同的“单张”模板。基于上面Kaiser的回答,我编写了此代码。效果很好。
注意。我不需要add_action()。 -cpt-album-tax-serendipity.php和WP将自动使用它们; “ tax-serendipity”是第一个“专辑”分类法术语的标语。
作为参考,“ single_template”过滤钩在以下位置声明:
谢谢Kaiser提供示例代码。
干杯,
格雷戈里
评论
嗨,格雷格-欢迎来到WPSE。请仅将答案发布为问题的答案,而不是后续问题。如果您有一个现有答案无法回答的问题,且太大而无法发表评论,请打开另一个问题:)
–斯蒂芬·哈里斯(Stephen Harris)
2012年4月18日在15:07
字符串/数组问题已删除:-)
–格雷戈里
2012年4月18日在16:04
“谢谢Kaiser提供示例代码。” - 别客气。
– kaiser
2012年10月23日下午13:01
对你起作用吗?首先,'$ template'不应在您的代码中被注释..我认为应该以'$ object-> post_name'代替'$ album_tax [0]-> slug',不是吗?
–regregmatys
13年11月18日在14:14
修复了$ template行。谢谢。 $ object-> post_name?没有。那会返回帖子的内容,但是我需要帖子链接到的相册的内容。
–格雷戈里
13年11月18日在23:21
#6 楼
更新Brians代码后,我发现当不使用下拉框时,“默认”模板选项被保存到wp_page_template中,这导致它尝试查找名为default的模板。此更改仅在保存时检查选项“ default”,然后删除帖子元(如果您将模板选项更改为默认值,则很有用)elseif(MY_CUSTOM_POST_TYPE === $_POST['post_type']) { if ( esc_attr($_POST['_wp_page_template']) === "default" ) : delete_post_meta($post_id, '_wp_page_template'); else : update_post_meta($post_id, '_wp_page_template', esc_attr($_POST['_wp_page_template'])); endif; }
评论
以前从未使用过这样的设置,但是如果它太复杂了,为什么不制作一个模板文件并将其与相关的评论相关联呢?WP 3.4自动获取单个{{post_type}-{slug} .php,因此升级到WP 3.4是另一种选择。