让我的脑袋绕过WordPress过滤器

时间:2015-12-02 作者:pocockn

我正在学习一个教程,希望它能让我直接将插件中的模板插入WordPress。我正在使用template\\u include过滤器,我无法理解整个过滤过程是如何工作的。

这是代码。

public function view_project_template( $template ) {

    global $post;

    if (!isset( $this->templates[get_post_meta($post->ID, \'_wp_page_template\', true ) ] ) ) {
        return $template;
    }

    $file = plugin_dir_path(__FILE__) . get_post_meta( $post->ID, \'_wp_page_template\', true );

    if ( file_exists( $file ) ) {
        return $file;
    }
    else {
        echo $file;
    }

    return $template;

}
我知道过滤器只接受一个参数$template,但在最后返回$template时,我并没有影响它。这将如何影响过滤器?把这件事弄清楚就好了。

3 个回复
SO网友:Pieter Goosen

您错误地使用了过滤器,这就是您可能无法获得所需结果的原因。让我们先看看template_include 可以签出的筛选器wp-includes/template-loader.php当前版本4.3.1)

44  if ( defined(\'WP_USE_THEMES\') && WP_USE_THEMES ) :
45          $template = false;
46          if     ( is_404()            && $template = get_404_template()            ) :
47          elseif ( is_search()         && $template = get_search_template()         ) :
48          elseif ( is_front_page()     && $template = get_front_page_template()     ) :
49          elseif ( is_home()           && $template = get_home_template()           ) :
50          elseif ( is_post_type_archive() && $template = get_post_type_archive_template() ) :
51          elseif ( is_tax()            && $template = get_taxonomy_template()       ) :
52          elseif ( is_attachment()     && $template = get_attachment_template()     ) :
53                  remove_filter(\'the_content\', \'prepend_attachment\');
54          elseif ( is_single()         && $template = get_single_template()         ) :
55          elseif ( is_page()           && $template = get_page_template()           ) :
56          elseif ( is_singular()       && $template = get_singular_template()       ) :
57          elseif ( is_category()       && $template = get_category_template()       ) :
58          elseif ( is_tag()            && $template = get_tag_template()            ) :
59          elseif ( is_author()         && $template = get_author_template()         ) :
60          elseif ( is_date()           && $template = get_date_template()           ) :
61          elseif ( is_archive()        && $template = get_archive_template()        ) :
62          elseif ( is_comments_popup() && $template = get_comments_popup_template() ) :
63          elseif ( is_paged()          && $template = get_paged_template()          ) :
64          else :
65                  $template = get_index_template();
66          endif;
67          /**
68           * Filter the path of the current template before including it.
69           *
70           * @since 3.0.0
71           *
72           * @param string $template The path of the template to include.
73           */
74          if ( $template = apply_filters( \'template_include\', $template ) )
75                  include( $template );
76          return;
77  endif;
因为我们在一个真实的页面上$template 在第74行中传递给过滤器的值将是get_page_template()因为is_page() 返回true),该值可通过{$type}_template 过滤器位于get_query_template()由使用get_page_template())。

好的,我们可以用两种方法来解决这个问题template_includepage_template记住{$type}_template 过滤器,这里$type === \'page\')。如果你要用template_include, 您需要使用is_page() 条件仅针对真实页面。如果您使用page_template 过滤器(此处更需要它),您不需要此检查。

我不太清楚下面这一行应该做什么,也不知道为什么你的过滤器从来没有超出这一部分

if (!isset( $this->templates[get_post_meta($post->ID, \'_wp_page_template\', true ) ] ) ) {
    return $template;
}
因为你处理的是真实的页面,_wp_page_template 应该总是有一个值,所以我们真正需要做的就是检查模板是否存在于模板中,然后返回它

您可以尝试以下操作:

public function view_project_template( $template ) {

    // Use get_queried_object_id() to get page id, much more reliable
    $current_page_id = get_queried_object_id();

    $page_template = get_post_meta( 
        $current_page_id, // Current page ID
        \'_wp_page_template\', // Meta key holding the page template value
        true // Return single value
    );

    /**
     * You can add extra protection and make sure $page_template has a value
     * although it should not be really necessary
     */
    // if ( !$page_template )
        // return $template;

    $file = plugin_dir_path(__FILE__) . $page_template;

    // Check if file exists, if not, return $template
    if ( !file_exists( $file ) ) 
        return $template;

    // If we reached this part, we can include our new template
    return $template = $file; // Or you can simply do return $file;

}
然后,您应该按照如下方式钩住您的方法(,因为它位于类内部)

add_filter( \'page_template\', [$this, \'view_project_template\'] );
这里只是一个小小的想法,为什么不将该方法设置为私有的,因为您不希望它在类之外可用

SO网友:Nicolai Grossherr

你没有效果,因为你没有做任何$template - 你不必这么做。无论如何,它并不会真正影响过滤器,我更愿意说,过滤器为您提供了干预过程的可能性。另一方面,如果$file 存在和您return 它,那么你应该看到一个效果-前提是$file 不同于$template.

SO网友:Sabari

过滤器的内容-apply_filters($tag, $value) do is通过\'value\' 每个函数的参数\'hooked\' (使用add_filter) 输入指定的筛选器“tag”。每个函数对该值执行一些处理,并返回一个修改后的值,以传递给序列中的下一个函数。

在本例中,您正在检查模板文件是否存在,如果存在,则返回file. 在这种情况下,您告诉WordPress加载您的文件,而不是WordPress试图加载的原始模板。默认情况下,WordPress加载从过滤器输出的模板

相关推荐

无法在模板函数.php中使用IS_HOME

我试图在标题中加载一个滑块,但只在主页上加载。如果有帮助的话,我正在使用Ultralight模板。我正在尝试(在template functions.php中)执行以下操作:<?php if ( is_page( \'home\' ) ) : ?> dynamic_sidebar( \'Homepage Widget\' ); <?php endif; ?> 但这行不通。现在,通过快速的google,我似乎需要将请