如何阻止WordPress进行默认查询?

时间:2014-06-13 作者:Luca Reghellin

我的目标是根据一些新的重写规则重定向到自定义模板,但不需要wordpress进行无用的查询。

我的代码:

function add_rewrite_rules() {

    add_rewrite_rule(
        \'^settore/([^/]*)/?$\',
        \'index.php?settore=$matches[1]\',
        \'top\'
    );

  add_rewrite_tag(\'%settore%\',\'(caldareria|tessile)\');
}
add_action( \'init\', \'add_rewrite_rules\' );

function set_root_category_template($template){
    $settore = get_query_var(\'settore\');
    if($settore != \'\') $template = locate_template(\'root-taxonomy.php\');
    return $template;
}
add_filter(\'template_include\',\'set_root_category_template\',99);
它重定向得恰到好处,但如果我在根分类法中选中$wp\\u query->posts。php,我看到一个常规帖子列表。相反,在该页面中,我将进行一个自定义查询,询问一些特定的分类术语数据,因此,默认查询完全无用。我怎样才能阻止它?毕竟,我并没有将任何默认查询变量传递给索引。php,所以我无法理解wp仍在执行查询的原因。。

2 个回复
最合适的回答,由SO网友:gmazzap 整理而成

停止WordPress运行主查询很难:你必须深入WordPress的内心深处。

WordPress前端工作流:

  1. wp-blog-header.php 调用函数wp()
  2. wp() 函数创建的实例wp class, 和电话main() it上的方法main() 方法代码:

    public function main($query_args = \'\') {
      $this->init();
      $this->parse_request($query_args); // build query vars starting from url
      $this->send_headers();
      $this->query_posts();  // run main query via WP_Query using built query vars
      $this->handle_404(); // if query has no results set 404 headers and WP_Query props
      $this->register_globals();
    }
    
  3. wp-blog-header.php 包括template-loader.php 基于查询加载模板文件

    所以停止主查询的唯一方法是阻止wp() 运行。

    这是可以做到的,尽早上钩,做你需要的事,最后exit().

    这种方法的问题是wp() 为了运行,您还阻止wp类解析请求,因此您添加的重写内容不会被解析。

    因此,与其添加重写标记和重写规则,不如直接查看url 选择是否应该触发自定义操作。

    首先,让我们编写一个函数,只返回url的相对部分,例如,如果当前url类似于example.com/wp/path/to/somewhere?foo=bar 您的主页url是example.com/wp/ 函数返回path/to/somewhere :

    function get_relative_url() {
      $home_path = rtrim( parse_url( home_url(), PHP_URL_PATH ), \'/\' );
      $path = trim( substr( add_query_arg( array() ), strlen( $home_path ) ), \'/\' );
      $qs = array_keys( $_GET );
      if ( ! empty( $qs ) ) {
        $path = remove_query_arg( $qs, $path );
      }
      return $path;
    }
    
    现在,我们可以使用早期挂钩查看url,只有当它包含所需的路径时,我们才会设置$settore 变量,加载模板并退出:

    add_action( \'wp_loaded\', function() { // \'wp_loaded\' hook happen before wp() is ran
    
      $path = get_relative_url();
      $url_parts = explode( \'/\', $path );
      if (
        isset( $url_parts[1] )
        && $url_parts[0] === \'settore\'
        && in_array( $url_parts[1], array( \'caldareria\', \'tessile\' ), TRUE )
      ) {
        // ok the current url is something like example.com/settore/tessile
        // and \'tessile\' is in the variable $url_parts[1]
        $template = locate_template( \'root-taxonomy.php\' );
        if ( empty( $template ) ) return; // do nothing if template not found
        global $settore;
        $settore = $url_parts[1]; // in the template you can access to $settore variable.
        require_once $template;
        exit(); // prevent WordPress to do anything else
      }
    
    } );
    
    仅此而已。

    在上面的代码中,了解当前url是否正确,并设置$settore 变量很简单,因为url结构很简单,对于更复杂的url结构,您可能需要正则表达式匹配,并且可能需要使用Symfony routing component 将url与某些变量匹配。

    这种方法就是我在Cortex, 如果你打算经常做这样的事情,看看那里。

    如您所见,主查询(global $wp_query) 在我发布的代码中没有使用,在你的模板中它将是空的WP_Query 对象,因此任何内容都将引用主查询,例如模板标记,如is_tax(), is_archive() 或诸如此类,都不会起作用。

    这也适用于页眉和页脚,因为很可能在您的“根分类法”中。php“您将使用get_header()get_footer().

    此外,一些插件可能无法正常工作,例如,如果您使用任何基于查询设置标题标签的SEO插件,那么它将出现问题。

    一种可能的解决方案是手动设置访问的主要查询属性global $wp_query 或使用自定义标题,例如。get_header(\'root-tax\'), 用于自定义模板和句柄header-root-tax.php 自定义标题标签和/或任何其他问题。

SO网友:Web-Entwickler

为什么不这样呢?

add_action( \'pre_get_posts\', \'my_post_queries\' );
function my_post_queries( $query ) {
    if ($query->is_main_query() && !is_admin()) {
        // maybe check for specific page here
        // if (is_tax(\'your-taxonomy\') { 
        $query = false;
        remove_all_actions ( \'__after_loop\');
        // }
    }
}
还是我误解了这个问题?

结束

相关推荐

1 post, 2 templates

我想能够呈现两种不同的风格(2个模板)后。例如,假设我有post ID 133,我希望有两个url来访问它,因此它会呈现不同模板应用的位置。洛雷姆。com/render1/133。com/render2/1333,例如。。。或者可能是这样的:洛雷姆。com/post/133和lorem。com/post/133?模板=2您将如何操作?