用于定制帖子类型的单个-{$POST_TYPE}-{slug}.php

时间:2012-02-02 作者:supertrue

Wordpress中我最喜欢的部分template hierarchy 是一种通过slug快速创建页面模板文件的能力,无需在Wordpress中编辑页面来选择模板。

我们目前可以这样做:

第-{slug}页。php

但我希望能够做到这一点:

单-{post\\u type}-{slug}。php

例如,在一个名为review, 我可以在single-review-my-great-review.php

以前有人设置过这个吗?single-{post_type}-{slug}.php

6 个回复
SO网友:kaiser

A) 如您所见,核心中的基础in the Codex 模板层次结构说明,single-{$post_type}.php 已支持。

扩展核心层次结构现在很高兴在里面有一些过滤器和挂钩/wp-includes/template-loader.php.

  • do_action(\'template_redirect\');
  • apply_filters( \'template_include\', $template )get_query_template( $type, ... ) 已命名:"$type}_template"
    • B.1)工作原理在模板加载器文件中,模板通过查询var/wp\\u查询条件加载:is_*().is_single() && $template = get_single_template()get_query_template( $type, $templates ), 哪里$typesingle"{$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.

      Trac票证

      由于目前不支持上述方法(您只能通过这种方式过滤绝对定位路径),以下是Trac票证列表:

SO网友:Shane

遵循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 检查

SO网友:skladany

最重要的答案(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 );
?>

SO网友:Gregory

在我的例子中,我有相册和曲目自定义帖子类型,它们由相册分类法链接。我希望能够为相册使用不同的单一模板,并根据相册分类法跟踪帖子。

基于以上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

SO网友:Brian Fegter

使用页面模板另一种可扩展性方法是在page 自定义帖子类型的帖子类型。

可重用代码中的重复不是一种好的做法。超时可能会导致代码库严重膨胀,从而使开发人员很难管理。您很可能需要一个可以重用的一对多模板,而不是一对一发布到模板,而不是为每个slug创建模板。

代码

# 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\');
这是一个有点晚的答案,但我认为这将是有价值的,因为据我所知,网络上没有人记录过这种方法。希望这能帮助别人。

SO网友:Mark

更新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;
}

结束

相关推荐

调用Function_Exist()比调用Apply_Filters()快还是慢

调用函数\\u exists()时,应用\\u filters()的速度是快还是慢。。。还是差异太小,不应该考虑?我在Kaiser的基础上做了一些测试,结果表明,在同时存在函数和过滤器的情况下,function\\u exists()的速度大约是3倍。如果过滤器不存在,速度将提高约11倍。没想到会这样。function taco_party() { return true; } add_filter( \'taco-party\', \'taco_party\'