带有PRE_GET_POST的WordPress自定义搜索表单不起作用

时间:2021-07-15 作者:Wolftrick

我正在设计我的第一个主题,我被自定义帖子类型的搜索功能所困扰。我创建了一个CPT“电影”,并用“存档电影”创建了存档页面。主题文件夹根目录中的php文件。在内部,我创建了一个基本的WP\\u查询

get_header();

// WP_Query arguments
$args = array(
    \'post_type\'     => array( \'movies\' ),
    \'post_status\'   => array( \'publish\' ),
    \'order\'         => \'DESC\',
    \'orderby\'       => \'date\',
);

// The Query
$query = new WP_Query( $args ); ?>

<div class="row gx-5">

<?php // The Loop
if ( $query->have_posts() ) : ?>
    
    <?php while ( $query->have_posts() ) : ?>
        <?php $query->the_post();
        
        // CODE

    <?php endwhile; ?>
<?php else : ?>
    <div class="col"><h2>Nessun film inserito</h2></div>
<?php endif ?>

</div>

<?php // Restore original Post Data
wp_reset_postdata();

get_footer();
并且电影显示正确。我在一个名为“搜索表单”的文件中创建了一个搜索表单。php”,通过标头中的get\\u template\\u part()加载。php文件原因表单必须在所有页面上始终可见。

<?php
$clienti = get_terms( array(
    \'taxonomy\'          => \'clients\',
    \'hide_empty\'        => false,
) );
if(!empty($clienti)) {
    $clients .= \'<option value="">-- Qualsiasi --</option>\';
    foreach($clienti as $cliente) {
        $clients .= \'<option value="\'.$cliente->term_id.\'">\'.$cliente->name.\'</option>\';
    }
} else {
    $clients .= \'Nessun cliente presente nel database\';
}
?>
<div id="search-form">
    <form method="get" class="row g-3" action="<?php echo get_post_type_archive_link(\'movies\'); ?>" role="search">
        <div class="col">
            <div class="form-floating">
                <input type="text" class="form-control" id="keyword" name="keyword" placeholder="Nome progetto">
                <label for="keyword">Nome progetto</label>
            </div>
        </div>
        <div class="col">
            <div class="form-floating">
                <select class="form-select" id="clients_list" name="clients_list" aria-label="Seleziona cliente">
                    <?php echo $clients; ?>
                </select>
                <label for="clients_list">Seleziona cliente</label>
            </div>
        </div>
        <div class="col">
            <div class="form-floating">
                <select class="form-select" id="status_list" name="status_list" aria-label="Seleziona cliente">
                    <option value="">-- Qualsiasi --</option>
                    <option value="aperto">Aperto</option>
                    <option value="chiuso">Chiuso</option>
                    <option value="pagato">Pagato</option>
                </select>
                <label for="status_list">Seleziona stato</label>
            </div>
        </div>
        <div class="col">
            <div class="form-floating">
                <select class="form-select" id="expired_date" name="expired_date" aria-label="Scadenza film">
                    <option value="">-- Qualsiasi --</option>
                    <option value="scadenza">In scadenza</option>
                    <option value="scaduto">Scaduto</option>
                </select>
                <label for="expired_date">Scadenza film</label>
            </div>
        </div>
        <div class="col">
            <div class="form-floating">
                <select class="form-select" id="expired_production" name="expired_production" aria-label="Scadenza produzione">
                    <option value="">-- Qualsiasi --</option>
                    <option value="scadenza">In scadenza</option>
                    <option value="scaduto">Scaduto</option>
                </select>
                <label for="expired_production">Scadenza produzione</label>
            </div>
        </div>
        <div class="col">
            <button type="submit" class="btn btn-outline-primary btn-lg">Cerca</button>
        </div>
    </form>
</div>
在主题函数中。相反,我插入了这段代码,试图使用pre\\u get\\u posts操作电影存档的WP\\u查询,但无论我尝试什么都不起作用,主查询没有修改,显示的CPT总是相同的。

/*=================================================
CUSTOM QUERY
=================================================== */
function custom_search_query_vars_filter( $vars ) {

    $vars[] .= \'keyword\';
    $vars[] .= \'clients_list\';
    $vars[] .= \'status_list\';
    $vars[] .= \'expired_date\';
    $vars[] .= \'expired_production\';
    return $vars;
}
add_filter( \'query_vars\', \'custom_search_query_vars_filter\' );

/*=================================================
SEARCH QUERY
=================================================== */
function movies_search( $query ) {
    if ( is_archive(\'movies\') && $query->is_main_query() && !is_admin() ) {

        $today = date(\'Y-m-d\');
        $lastweek = date(\'Y-m-d\', strtotime(\'-7 days\'));

        $keyword = get_query_var( \'keyword\', FALSE );
        $clients_list = get_query_var( \'clients_list\', FALSE );
        $status_list = get_query_var( \'status_list\', FALSE);
        $expired_date = get_query_var( \'expired_date\', FALSE);
        $expired_production = get_query_var( \'expired_production\', FALSE);

        // Keywords query
        $keyword ? $keyword : $keyword = null;

        $query->set(\'s\', $keyword);

        // Custom fields query
        $meta_query_array = array(\'relation\' => \'AND\');

        $status_list ? array_push($meta_query_array, array(\'key\' => \'status_job\', \'value\' => \'"\' . $status_list . \'"\', \'compare\' => \'LIKE\') ) : null ;

        if($expired_date== \'scadenza\' ) {
            array_push($meta_query_array, array(\'key\' => \'expired_date\', \'value\' => array($today, $lastweek), \'compare\' => \'BETWEEN\', \'type\' => \'DATE\'));
        } elseif($expired_date== \'scaduto\') {
            array_push($meta_query_array, array(\'key\' => \'expired_date\', \'value\' => $lastweek, \'compare\' => \'<\', \'type\' => \'DATE\'));
        } else {
            null;
        }

        if($expired_production == \'scadenza\' ) {
            array_push($meta_query_array, array(\'key\' => \'expired_production\', \'value\' => array($today, $lastweek), \'compare\' => \'BETWEEN\', \'type\' => \'DATE\'));
        } elseif($expired_production == \'scaduto\') {
            array_push($meta_query_array, array(\'key\' => \'expired_production\', \'value\' => $lastweek, \'compare\' => \'<\', \'type\' => \'DATE\'));
        } else {
            null;
        }

        $query->set( \'meta_query\', $meta_query_array );
        
        // Taxonomies query
        $tax_query_array = array(\'relation\' => \'OR\');

        $clients_list ? array_push($tax_query_array, array(\'taxonomy\' => \'clients\', \'field\' => \'term_id\', \'terms\' => $clients_list) ) : null ;

        $query->set( \'tax_query\', $tax_query_array);
    }
}
add_action( \'pre_get_posts\', \'movies_search\' );
即使我对所有查询都制定了一般规则,它似乎总是被忽略。

/*=================================================
SEARCH QUERY OVERRIDE
=================================================== */
function movies_search( $query ) {
    if ( $query->is_main_query() && !is_admin() ) {

        $query->set( \'s\', \'Name specific movie\' );

    }
}
add_action( \'pre_get_posts\', \'movies_search\' );
我不认为这是一个兼容性问题,因为没有安装插件,在我正在开发的主题中,除了使用pre\\u get\\u posts操作之外,没有其他功能。非常感谢。

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

首先,作为documented:

is_archive() 不接受任何参数。如果要检查这是否是自定义帖子类型的存档,请使用is_post_type_archive( $post_type )

因此,在代码中,使用is_post_type_archive( \'movies\' ) 而不是is_archive(\'movies\').

现在,关于主要问题:

未修改主查询,显示的CPT始终相同

我希望你能真正理解;“主查询”;它基本上是WP_Query 类和实例可通过全局$wp_query 变量WordPress在加载页面模板之前,在页面加载时运行主查询,因此主查询决定应该使用哪个模板。例如,如果你在example.com/movies (post-type存档页),然后WordPress加载archive-movies.php 样板if it exists.

我相信主查询实际上正在修改,但您从未在该查询中显示帖子,而是创建了一个自定义查询,然后在该查询中显示帖子(在while ( $query->have_posts() ) ... 部分),它返回相同的帖子,而不考虑搜索表单中的过滤器。

为什么会这样,是因为$query->is_main_query() 函数中的check(这很好)导致搜索过滤器仅应用于主查询,即当$query 是全球的$wp_query 变量但是,在您的模板中$query 不是主查询,而是的辅助/自定义实例WP_Query

因此,您应该像这样使用主循环:(这是一个非常简单的示例;请参阅The Loop in the theme developer handbook 有关循环的更多详细信息)

// In your archive-movies.php file:

while ( have_posts() ) {
    the_post();
    the_title( \'<h2>\', \'</h2>\' );
}
并删除自定义查询/循环(包括wp_reset_postdata(); 零件)。

请记住,主查询已经从数据库中检索到了正确的帖子,因此您应该只显示这些帖子,但如果您想更改每页的帖子数量,和/或只包括某些类别的帖子,则使用pre_get_posts 钩子更改主查询(参数),而不是通过新的WP_Query 例子

相关推荐

在WordPress上使用ElasticSearch

我是个傻瓜,所以感谢你的耐心:-)我正在尝试使用ElasticSearch和使用ElasticPress插件的Wordpress安装。所有配置和生产中。到目前为止取得了惊人的成绩。我对所有ES的使用位置感到困惑。“默认情况下,它仅在搜索页上工作。如果要使用它处理任何其他页,或索引、循环、主页、存档、税务(WP\\U查询),则必须添加到查询中:”“ep\\U integrate”“=>true”有人能帮我用代码片段实现这个吗?谢谢