使用嵌入式wp_query查询保留postdata?

时间:2012-12-12 17:34:30

标签: php wordpress

我正在使用Wordpress设计一个网站。该网站是其中一个视差网站,其中所有页面都打印在主页上,菜单滚动到主页。

据说我正在使用wp_query来提取主菜单中的所有页面。此外,我有一个短代码,我在内容中使用也需要使用wp_query。

我遇到的问题是短代码(嵌入式wp_query)搞砸了postdata。我知道在使用wp_query时你通常想要使用wp_reset_postdata但是在这种特殊情况下它不起作用,因为这个函数调用将恢复主页的postdata而不是当前运行的wp_query(对不起,如果我不清楚)

有没有办法拍摄postdata的快照然后在我的短代码后恢复?我正在寻找以下内容:

function my_shortcode() {
    save_postdata(); //saves the current postdata
    $query = new WP_Query();
    while( $query->have_posts() )   {
        $query->the_post();
        echo get_the_title();
    }
    my_wp_reset_postdata(); //restores the postdata to where it was before the loop
}

3 个答案:

答案 0 :(得分:1)

通过查看wp_reset_query()的来源,你会发现它的作用是它只是从另一个全局变量($wp_query - 恢复$wp_the_query全局变量 - 这是设置 - 与$wp_query的初始设置一起,因此它保存原始查询)。

您可以做的是简单地将$wp_query分配给不同的全局变量,然后再将其恢复。这是一个例子:

function _save_query( $var = '_wp_query' ) {
    $GLOBALS[ $var ] = $GLOBALS['wp_query'];
}

function _wp_reset_query( $var = '_wp_query' ) {
    $GLOBALS['wp_query'] = $GLOBALS[ $var ];
    wp_reset_postdata();
}

所以只需在覆盖查询之前调用_save_query()(您可以传递自定义变量名称 - 这样就可以存储多个WP_Query个对象:))。

一旦要恢复查询数据,请再次调用_wp_reset_query() - 您可以将字符串作为变量名称传递,以便还原此精确查询对象。

答案 1 :(得分:1)

这就是我设法让它发挥作用的方式,因为我的想法已经完成,所以归功于Nikola的问题。

function _save_query( $var = '_wp_query' ) {
    global $post;
    $GLOBALS[ $var ] = $post;
}

function _wp_reset_query( $var = '_wp_query' ) {
    global $post;
    $post = $GLOBALS[ $var ];
    setup_postdata( $post );
}

我查看了循环工作原理的文档here。我决定使用与Nikola的答案相同的设置,因为它符合我的标准,但我使用the_post的实现来恢复postdata。这可能不是非常有效,因为它使用的是setup_postdata函数(我认为它有点矫枉过正),但它确实解决了我的问题。

所以现在当我嵌入一个wp_query时,我可以执行以下操作:

_save_query();
$products = new WP_Query( $args );
if( $products->have_posts() ) {
    $ob .= '<ul class="group-posts">';
    while ( $products->have_posts() ) {
        $products->the_post();
        $ob .= '<li>'.get_the_title().'</li>';
    }
    _wp_reset_query();
    $ob .= '</ul>';
}

附带问题/注意:将答案标记为正确答案的礼仪是什么?当尼古拉帮助我达到目的时,我感觉不好接受我的答案是正确的吗?

答案 2 :(得分:0)

my_wp_reset_postdata不存在。您必须使用wp_reset_postdata()。但是在你必须链接多个wp_queries并返回旧的wp_queries的情况下,你可以将你的第一个查询存储在一个变量中,设置新的WP_query,然后重置它并返回旧的。

$ wp_query存储当前循环。所以你可以这样:

    $temp = $wp_query;
    $wp_query= null;
    $wp_query = new WP_Query($args);
    ...

    // then later 
    $wp_query = $temp;
    // And back on tracks !