2011-11-30 82 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