Wordpress中我最喜欢的部分template hierarchy 是一种通过slug快速创建页面模板文件的能力,无需在Wordpress中编辑页面来选择模板。
我们目前可以这样做:
第-{slug}页。php
但我希望能够做到这一点:
单-{post\\u type}-{slug}。php
例如,在一个名为review
, 我可以在single-review-my-great-review.php
以前有人设置过这个吗?single-{post_type}-{slug}.php
Wordpress中我最喜欢的部分template hierarchy 是一种通过slug快速创建页面模板文件的能力,无需在Wordpress中编辑页面来选择模板。
我们目前可以这样做:
第-{slug}页。php
但我希望能够做到这一点:
单-{post\\u type}-{slug}。php
例如,在一个名为review
, 我可以在single-review-my-great-review.php
以前有人设置过这个吗?single-{post_type}-{slug}.php
single-{$post_type}.php
已支持。扩展核心层次结构现在很高兴在里面有一些过滤器和挂钩/wp-includes/template-loader.php
.
do_action(\'template_redirect\');
apply_filters( \'template_include\', $template )
get_query_template( $type, ... ) 已命名:"$type}_template"
is_*()
.is_single() && $template = get_single_template()get_query_template( $type, $templates ), 哪里$type
是single
"{$type}_template" 筛选解决方案,因为我们只想用一个在实际"single-{$object->post_type}.php"
模板,我们将截取层次结构并向模板数组的开头添加一个新模板。// 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 );
注意:(如果要使用默认对象slug以外的其他对象),则必须进行调整$slug
根据你的permalink结构。只要使用全球(object) $post
.遵循Template Hierarchy image, 我看不出有这样的选择。
所以我想这样做:
Solution 1 (Best in my opinion)
制作模板文件并将其与审阅关联 <?php
/*
Template Name: My Great Review
*/
?>
将模板php文件添加到主题目录中,它将作为模板选项显示在帖子的编辑页面中。Solution 2
这可能通过使用template_redirect
钩在函数中。php文件:
function my_redirect()
{
global $post;
if( get_post_type( $post ) == "my_cpt" && is_single() )
{
if( file_exists( get_template_directory() . \'/single-my_cpt-\' . $post->post_name . \'.php\' ) )
{
include( get_template_directory() . \'/single-my_cpt-\' . $post->post_name . \'.php\' );
exit;
}
}
}
add_action( \'template_redirect\', \'my_redirect\' );
EDIT
已添加file_exists
检查最重要的答案(4年前)不再有效,但WordPress codexhas the solution here:
<?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 );
?>
在我的例子中,我有相册和曲目自定义帖子类型,它们由相册分类法链接。我希望能够为相册使用不同的单一模板,并根据相册分类法跟踪帖子。
基于以上Kaiser的回答,我编写了这段代码。它工作得很好
注意。我不需要add\\u操作()。
// Add an additional template option to the template hierarchy
add_filter( \'single_template\', \'add_albumtrack_taxslug_template\', 10, 1 );
function add_albumtrack_taxslug_template( $orig_template_path )
{
// at this point, $orig_template_path is an absolute located path to the preferred single template.
$object = get_queried_object();
if ( ! (
// specify another template option only for Album and Track post types.
in_array( $object->post_type, array( \'gregory-cpt-album\',\'gregory-cpt-track\' )) &&
// check that the Album taxonomy has been registered.
taxonomy_exists( \'gregory-tax-album\' ) &&
// get the Album taxonomy term for the current post.
$album_tax = wp_get_object_terms( $object->ID, \'gregory-tax-album\' )
))
return $orig_template_path;
// assemble template name
// assumption: only one Album taxonomy term per post. we use the first object in the array.
$template = "single-{$object->post_type}-{$album_tax[0]->slug}.php";
$template = locate_template( $template );
return ( !empty( $template ) ? $template : $orig_template_path );
}
我现在可以创建名为single gregory cpt track tax serendipity的模板。php和gregory cpt专辑《税务意外》。php和WP将自动使用它们;\'“税务意外”是首个专辑分类术语的鼻涕虫。作为参考,“single\\u template”过滤器挂钩在中声明:
/wp includes/theme。php:get_query_template()
感谢Kaiser提供的示例代码。
干杯Gregory
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\');
这是一个有点晚的答案,但我认为这将是有价值的,因为据我所知,网络上没有人记录过这种方法。希望这能帮助别人。更新Brians代码时,我发现当没有使用下拉框时,“default”模板选项被保存到wp\\u page\\u模板中,这导致它尝试查找名为default的模板。此更改仅在保存时检查“default”选项,并删除post meta(如果您将模板选项更改回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; }
调用函数\\u exists()时,应用\\u filters()的速度是快还是慢。。。还是差异太小,不应该考虑?我在Kaiser的基础上做了一些测试,结果表明,在同时存在函数和过滤器的情况下,function\\u exists()的速度大约是3倍。如果过滤器不存在,速度将提高约11倍。没想到会这样。function taco_party() { return true; } add_filter( \'taco-party\', \'taco_party\'