在使用“%s”查询参数的同时利用现有页面

时间:2021-06-24 作者:Chris Heath

我试图加载/利用现有的页面模板(templates/results.php),同时使用;s“;(搜索)查询参数。例如:示例。com/结果?s=lorem

目前,这导致404。

我有一个过滤器template_includes, 然而,该页面似乎已经是;“已决定”;在挂钩/过滤器之前(is_search(), is_page(\'results\') 均为false),然后加载模板。我可以根据一些其他参数加载模板文件,但之后我必须将标题和其他内容设置为远离404页面。

这个pagenames 字段在global $wp_query\'的原始查询变量,因此它只是一个;“决定”;在命中模板之前,查询实际上是什么。

可以显示自定义帖子类型的筛选帖子集的用例;列表;。Listings archive已经显示了列表,并自动过滤为;“打开”;,并可根据其分类进行筛选,以及;s“;用于任何搜索。我会让结果页面做同样的事情,能够提取与其归档对应的相同的可选查询参数。

如何在仍使用内置模板的情况下加载页面并使用现有页面模板s 查询参数?

answer\'s解决方案1提到将默认的“s”查询变量替换为自定义变量,旨在避免这种情况,希望在WordPress决定在结果页中搜索“s”字符串之前进行筛选/挂接。

当前如何使用页面/查询:

Template file:

<?php

// get_header() and the_post() related parts have already been called in the main template file.

// Temporary query to replace the main one so we can utilise pagination, etc.
global $post;
global $wp_query;

$listing_results_query = new WP_Query( [
    \'listing_type\'           => get_query_var( \'listing_type\' ),
    \'pricing\'                => get_query_var( \'pricing\' ),
    \'s\'                      => get_query_var( \'s\' ),
    \'paged\'                  => get_query_var( \'paged\', 1 ),
    \'post_type\'              => \'listing\',
    \'query_id\'               => \'listing-results\',
    \'listing_status_compare\' => \'!=\'
] );

$temp_query = $wp_query;
$wp_query   = NULL;
$wp_query   = $listing_results_query;
?>

<span>Various HTML and get_template_part() calls being used to load the archive</span>

<?php
// Reset main query object
$wp_query = NULL;
$wp_query = $temp_query;
?>
Hook/function file (equivalent of functions.php)
我删去了一些检查/其他查询部分,以简化此处的操作。在调用此挂钩(pre\\u get\\u posts)时,$query->is_404 已设置为true.

function wpse_390935_modify_listing_archive_query( $query ) {
    $is_listing_archive_results = ! is_admin() && ( $query->query[\'query_id\'] ?? false ) === \'listing-results\';

    if ( $is_listing_archive_results ) {
        $page_no        = $query->query[\'paged\'] ?? 1;
        $listing_type   = $query->query[\'listing_type\'] ?? \'\';
        $pricing        = $query->query[\'pricing\'] ?? \'\';
        $search         = $query->query[\'s\'] ?? \'\';
        $status_compare = $query->query[\'listing_status_compare\'] ?? \'=\';
        $meta_query     = [];

        // Search
        if ( $search ) {
            $query->set( \'s\', sanitize_text_field( $search ) );
        }

        // Other custom field/taxonomy query bits
    }
}
add_action( \'pre_get_posts\', \'wpse_390935_modify_listing_archive_query\', 10, 1 );

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

自定义查询变量移动s 在显式请求页面时调用自定义查询变量应该足够简单:

function wpse390935_set_page_search_qv( $wp ) {
  $qvs = $wp->query_vars;

  if( empty( $qvs[\'s\'] ) || ( empty( $qvs[\'pagename\'] ) && empty( $qvs[\'page_id\'] ) ) )
    return;

  $wp->query_vars[\'page_search\'] = $qvs[\'s\'];
  unset( $wp->query_vars[\'s\'] );
}
add_action( \'parse_query\', \'wpse390935_set_page_search_qv\' );
这可以防止它被分解到主查询中,而使它以后可以通过get_query_var( \'page_search\' ), 并继续将变量表示为s 最终用户。

如果绝对需要保留在s 在内部,您可以使用一些黑客并删除s 来自请求的query_vars 使用parse_request 操作挂钩,然后在查询执行后再次添加它。

我在这里用了一节单身课s 挂钩之间的值。

class WPSE390935_Search_Param_Passthrough {
  private static $instance = null;

  private $search = \'\';

  public static function get_instance() {
    if( is_null( self::$instance ) )
      self::$instance = new self();

    return self::$instance;
  }

  private function __construct() {
    add_action( \'parse_request\', [ $this, \'stash_query_var\' ], 2 );
  }

  public function is_page_search() {
    if( is_admin() )
      return false;

    if( did_action( \'parse_request\' ) > 0 )
      return ! empty( $this->search );
    
    throw new Error( \'Too early to determine is_page_search() condition.\' );
  }

  public function restore_query_var() {
    set_query_var( \'s\', $this->search );
  }

  public function stash_query_var( $wp ) {
    $qvs = $wp->query_vars;

    if( ( empty( $qvs[\'pagename\'] ) && empty( $qvs[\'page_id\'] ) ) || empty( $qvs[\'s\'] ) )
      return;
    
    $this->search = $qvs[\'s\'];

    unset( $wp->query_vars[\'s\'] );

    add_action( \'wp\', [ $this, \'restore_query_var\' ], 2 );
  }
}

function is_page_search() {
  return WPSE390935_Search_Param_Passthrough::get_instance()->is_page_search();
}

WPSE390935_Search_Param_Passthrough::get_instance();
我强烈建议不要将搜索值添加回主查询,而是在需要时从类中检索它。这样,主查询的查询变量的状态就不会歪曲主查询的实际情况。

为了达到类似的目的,我还提供了另一个条件谓词,其形式为is_page_search(). 当你可以设置$wp_query->is_search = truerestore_query_var() 方法,我会担心可能产生的任何副作用。无论是在核心还是任何插件中,都取决于核心谓词。

相关推荐

Conditional action hooks

我正在开发一个使用AJAX的插件,但我在控制代码流方面遇到了困难。我想在运行条件后挂接函数。我的钩子在控制结构内部添加时不会启动,但在外部会启动。我还有一个触发AJAX请求的事件,这只能在用户点击触发事件后,在加载所有DOM之后发生。AJAX请求告诉PHP函数设置cookie。它设置了cookie,但在阅读关于cookie的PHP文档时,我发现它们只能在发送任何输出后设置,但我还是做到了这一点?我读过WordPress初始化序列,但这并没有帮助我解决这个问题。这是我的密码:add_action(\'wp_