在HAVE_POSTS()之前修改WP查询POST__

时间:2012-11-29 作者:Zach

我有一个插件,根据$_GET 数据(搜索辅助DB表)。我正试图加入标准have_posts() 在分类页面中调用函数以显示结果。因为数据是在实际页面上传入的,所以我不能使用普通pre_get_posts 待命,就像这样:

function finder_sort($query) {
    if ($query->is_main_query() && is_tax(array(\'location_type\')) && isset($_GET[\'finder_action\'])) {
        $query->set(\'post__in\', array(1,2,3,4,5));
    }
}
add_action(\'pre_get_posts\',\'finder_sort\');
因为返回的数据在$_GET 页面上已阅读请求。所以,我想知道在数据输出之前是否有什么可以过滤的东西。例如,以下是我所拥有的:

$locations_found = wp_list_pluck($locations, \'id\');
while(have_posts()) {
    the_post();
    echo \'<tr>\';
    finder_location_teaser_table();
    echo \'</tr>\';
}
$locations_found 有一个ID列表-所以我要做的是筛选have_posts 仅包括中列出的ID$locations_found.

此外,我需要订购这些帖子,因为它们在post__in. 由于WP 3.5将“修复”这一问题,我已经在Sort Query by Post In 功能修复:

if ( version_compare( floatval( get_bloginfo( \'version\' ) ), \'3.5\', \'<\' ) ) {

    add_filter( \'posts_orderby\', \'sort_query_by_post_in\', 10, 2 );
    function sort_query_by_post_in( $sortby, $thequery ) {
        if ( !empty($thequery->query[\'post__in\']) && isset($thequery->query[\'orderby\']) && $thequery->query[\'orderby\'] == \'post__in\' )
            $sortby = "find_in_set(ID, \'" . implode( \',\', $thequery->query[\'post__in\'] ) . "\')";
        return $sortby;
    }
}
所以,这将是一个混合识别post__in 然后指定order_by 这个神奇的过滤器中的参数。如有任何想法,将不胜感激。谢谢

澄清

我无法使用元键的原因(以及为什么我需要按照检索它们的相同顺序返回它们)是因为每个数据项都有一个依赖于另一个数据项的计算$_GET 变量(基于邮政编码的距离)。

添加信息添加了生成查询变量的显示函数

function finder_top_filter($term) {

    ob_start(); ?>

    <section id="sort">
        <form name="search" action="" method="get">
            <label for="finder_zipcode"><?php _e(\'Zip Code\', \'finder\'); ?></label>
            <input type="text" name="finder_zipcode" id="finder_zipcode" value="<?php echo isset($_GET[\'finder_zipcode\']) ? $_GET[\'finder_zipcode\'] : \'\'; ?>" />

            <label for="finder_distance"><?php _e(\'Radius\', \'finder\'); ?></label>
            <select name="finder_distance" id="finder_distance">
                <?php
                $finder_dist_options = apply_filters(\'finder_dist_options\', array(
                    \'5\'   => \'5\',
                    \'10\'  => \'10\',
                    \'25\'  => \'25\',
                    \'50\'  => \'50\',
                    \'100\' => \'100\',
                    \'200\' => \'200\'
                ));
                foreach ($finder_dist_options as $key=>$value) {
                    echo \'<option value="\' . $key . \'" \' . (isset($_GET[\'finder_distance\']) ? selected( $_GET[\'finder_distance\'], $key ) : \'\') . \'>\' . $value . \'</option>\';
                }
            ?>
            </select>

            <input type="hidden" name="finder_action" value="search" />
            <input type="submit" value="<?php _e(\'Show/Filter\', \'finder\'); ?>" />
            <span class="reset"><a href="<?php echo get_term_link($term); ?>">Reset</a></span>
        </form>
    </section>
    <?php
    echo ob_get_clean();
}
更新根据斯蒂芬·哈里斯的建议,我决定走JOIN 查询以更改传递给循环的数据。所以,我尝试的是:

function finder_join_locations($join) {
    global $wpdb;

    return \'\';
}
add_filter(\'posts_join\', \'finder_join_locations\');

$i = 0;
while(have_posts()) {
    the_post();
    echo \'<tr>\';
    finder_location_teaser_table(get_the_ID(), $locations[$i][\'distance\']);
    echo \'</tr>\';

    $i++;
}

remove_filter(\'posts_join\', \'finder_join_locations\');
查看是否无法显示任何内容,但该筛选器没有覆盖have_posts() 功能-有什么建议吗?我想做的是通过post__in param,所以在我通过这个初始凹凸之后,它会找出正确的SQL语句来包含我的数据(如$locations_found 包括我需要的所有帖子数据):

$locations_found = wp_list_pluck($locations, \'id\');

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

我可以看到这个有几种可能性。

首先,我不相信你不能使用pre_get_posts 尽管可能您必须重新组织代码。您不必等待主题模板使用$_GET. 尝试:

function tst() {
    // global $_GET; // sometimes necessary
    var_dump($_GET);
}
add_action(\'pre_get_posts\',\'tst\');
所以我想:

function finder_sort($query) {
    // I don\'t know what your complete code for processing $_GET is but
    // that would go here and set $pin
    if ($query->is_main_query() && is_tax(array(\'location_type\')) && isset($_GET[\'finder_action\'])) {
        $query->set(\'post__in\', $pin);
    }
}
add_action(\'pre_get_posts\',\'finder_sort\');
这是一种可能性,从我现在坐的位置来看,这是最好的一种。如果出于某种原因,这是不可能的,您可以始终执行以下操作:

$locations_found = wp_list_pluck($locations, \'id\');
while(have_posts()) {
    the_post();
    if (in_array($post->ID,$locations)) {
        echo \'<tr>\';
        finder_location_teaser_table();
        echo \'</tr>\';
    }
}
我对你的数据做了一些假设。你的问题没有让我百分之百自信地编写代码所需的所有信息,但这就是我的想法。

SO网友:Chip Bennett

不要依赖$_GET

我会推荐,而不是依赖$_GET 数据,将自定义查询参数添加到$query 对象,使用add_query_arg(), 然后使用get_query_var().

例如,您有一个查询变量\'foo\', 值为\'bar\', 以便:

`$_GET[\'foo\'] = \'bar\'`
您可以将该键/值对提供给$query 对象,如下所示:

add_query_arg( \'foo\', \'bar\' );
在当前附加的任何位置执行此操作&foo=bar 到URI。

现在,您可以检索\'foo\' 像这样:

$foo = get_query_var( \'foo\' );
使用pre_get_posts既然您现在可以独立于$_GET, 您可以在pre_get_posts 回调:

function finder_sort( $query ) {
    if ( $is_main_query() && is_tax( array( \'location_type\' ) ) && isset( get_query_var( \'finder_action\' ) ) ) {
        $query->set( \'post__in\', get_query_var( \'finder_action\' ) );
    }
}
add_action( \'pre_get_posts\',\'finder_sort\' );

结束

相关推荐

使用新的WP-Query()从循环中过滤后期格式;

嗨,我目前正在为我的博客构建一个主题。下面的代码指向最新的帖子(特色帖子)。因为这将有一个不同的风格比所有其他职位。然而我想过滤掉帖子格式:链接使用我在循环中定义的WP查询,因为它给我带来了更多的灵活性。我该怎么做呢? <?php $featured = new WP_Query(); $featured->query(\'showposts=1\'); ?> <?php while ($featured->have_post