2011-11-30 81 views
5

我目前正在编写一个WP插件并需要重写模板。WordPress template_include - 如何正确挂钩

我的过滤钩子看起来像 - 它执行:

add_filter('template_include', 'mcd_set_template',10); 

功能mcd_set_template()只返回所需的路径字符串 - 或者如果默认的WP模板的文件不存在。

我已经打了几个小时了,甚至可以包括替代模板(但它出现在页面的底部)。

所以我的问题是,如何强制WP 3.2.1加载另一个模板文件,而不是 - 哪些优先级是必需的?

更新: 此外,我使用的var_dump时发现......几乎输出在文件的结尾 - 但打开HTML标记之前应该出现......

根据这张票应该与template_include工作挂钩:http://core.trac.wordpress.org/ticket/11242

或者是将这些滤镜挂钩的唯一方法: http://codex.wordpress.org/Template_Hierarchy#Filter_Hierarchy

回答

3

您是否尝试过使用add_action?例如,你可能想尝试一些像在你的插件如下:

add_action('template_redirect', 'mcd_set_template'); 
//Redirect to a preferred template. 
function mcd_set_template() { 
    $template_path = TEMPLATEPATH . '/' . "templatename.php"; 
    if(file_exists($template_path)){ 
     include($template_path); 
     exit; 
    } 
} 

这是一个有益的参考:http://www.mihaivalentin.com/wordpress-tutorial-load-the-template-you-want-with-template_redirect/

+0

很抱歉,调用exit()或die()绝对不是一种选择 - 因为它会尽快杀死脚本中的一个查询... 需要过滤template_loader。php @ line 42 –

+2

请注意标题中的*正确*这个词 - 你粘贴的代码确实很蹩脚。为什么?由于hook template_redirect发生在模板加载器决定要加载哪个模板之前发生...... –

+0

我在BuddyPress bug-tracker中看到您之前使用过您的建议 - 但优先级为999--而不是默认值10. –

14

你可以使用template_redirect如上图所示,但也不需要退出,它不会践踏WordPress通常会做的所有事情来查找当前模板。您可能希望让这种情况发生,然后将逻辑应用到当前模板。

使用上述一些什么......

add_action('template_include', 'mcd_set_template'); 

function mcd_set_template() { 
    return locate_template('templatename.php'); 
} 

这是相当简单的,你也可以传递一个数组locate_template()来定义一个层次。如果你要使用'template_redirect'如上所示,你应该仍然使用locate_template,这是如何。

add_action('template_redirect', 'mcd_set_template'); 

function mcd_set_template() { 

     /** 
     * Order of templates in this array reflect their hierarchy. 
     * You'll want to have fallbacks like index.php in case yours is not found. 
     */ 
     $templates = array('templatename.php', 'othertemplate.php', 'index.php'); 

     /** 
     * The first param will be prefixed to '_template' to create a filter 
     * The second will be passed to locate_template and loaded. 
     */ 
     include(get_query_template('mcd', $templates)); 

     exit; 
} 

最后,最好的方法是过滤特定类型而不是整个层次结构。例如,您可以过滤'category_template'或'page_template'。这将是更为具体,这将避免与整个模板层次搞乱,如果你不想 - 它可以让WordPress的做多繁重的

例如:

add_filter('category_template', 'filter_category_template'); 
function filter_category_template($template){ 
    /* Get current category */ 
    $category = get_queried_object(); 

    /* Create hierarchical list of desired templates */ 
    $templates = array (
     'category.php', 
     'custom-category-template.php', 
     'category-{$category->slug}.php', 
     'category-{$category->term_id}.php', 
     'index.php' 
    ); 


    return locate_template($templates); 
} 

你可以的当您使用locate_template()时,可以创建分层模板阵列。使用这种方法,可以很容易地看出,作为本地模板层次结构的一部分或者与之分离,您可以轻松创建各种非常详细和特定的层次结构。

+1

' add_filter('single_template','filter_callback')'适用于自定义帖子类型。顺便说一句,从WP 3.4开始,WP会自动检查看起来像''customPostType-single-slug.php''的模板,因此不需要额外的代码来切换自定义帖子类型的模板 – yitwail

+0

我如何使用此代码来包含一个特定页面的页面模板,通过一个插件? –

+0

@GregL - 要定位特定页面,您不需要此自定义内容。您可以通过WordPresses [Template Hierarchy](http://codex.wordpress.org/Template_Hierarchy#Page_display)或者通过将您的模板选择为容易相似地命名的“[Page Templates](http ://codex.wordpress.org/Page_Templates)” – eddiemoya