Почему мой WP_Query производит мои записи дважды?

Я использую маленький shortcode для вывода списка названий фильмов, расположенных десятилетиями. decades моя пользовательская таксономия с условиями как 1930s 1940s и т.д.

Вот мой shortcode:

[fashionfilms type=fashionfilms  tax=decades]

и вот то, как это shortcode анализируется:

add_shortcode('fashionfilms', 'cw_output_fashion_films');

function cw_output_fashion_films($atts){

    $post_type = $atts['type'];
    $tax = $atts['tax'];
    $tax_terms = get_terms($tax);

    if ($tax_terms) {
      echo "<ul>";
      foreach ($tax_terms  as $tax_term) {
        $args=array(
          'post_type' => $post_type,
          "$tax" => $tax_term->slug,
          'post_status' => 'publish',
          'posts_per_page' => -1,
          'ignore_sticky_posts'=> 1
        );

        $my_query = null;
        $my_query = new WP_Query($args);
        if( $my_query->have_posts() ) {
          echo "<li class='letter'>" . $tax_term->name . "</li>";
          while ($my_query->have_posts()) : $my_query->the_post(); ?>
            <li><a href="<?php the_permalink() ?>" rel="bookmark" title="Permanent Link to <?php the_title_attribute(); ?>"><?php the_title(); ?></a></li>
            <?php
          endwhile;
        }
        wp_reset_query();
      } //end foreach loop
      echo "</ul>";
    }
}

Проблема, я получаю удвоенный вывод для своих записей.

Для наблюдения удвоенного outout проверьте мою активную ссылку здесь.

Вот мой код шаблона страницы также:

<div class="span9">
            <?php while ( have_posts() ) : the_post(); ?>
            <div <?php post_class(); ?>>
                <h1><?php the_title();?></h1>
                <div class="content">
                    <?php the_content() ?>
                </div>
            </div><!-- /.post_class -->
        <?php endwhile; ?>
        <?php bootstrapwp_content_nav('nav-below');?>

</div><!-- /.span9 -->

Что я делаю неправильно? Как я могу зафиксировать это?

0
14.01.2014, 18:53
4 ответа

Вы использовали wp_reset_query, однако, необходимо использовать wp_reset_postdata.

wp_reset_query берет текущий объект запроса и заменяет его основным запросом. Проблема здесь однако, то, что Вы используете WP_Query, который является отдельным объектом отдельного запроса, основной запрос не был затронут и не нужен в сохранении.

Это означает, что мы не должны звонить wp_reset_query, поскольку запрос никогда не изменяется.

Мы действительно звонили $my_query->the_post как бы то ни было. Это означает, что текущие данные сообщения от Вашего пользовательского запроса и сброса потребностей, так вот почему мы звоним wp_reset_postdata.

Вызов wp_reset_query то, когда Вы не имеете к, может иметь непреднамеренные последствия в этом дублировании случая Ваших сообщений

1
19.02.2020, 23:37

Проблема не wp_reset_query() отдельно. Однако как @TomJNowell указал, и @hampusn, первоначально предложенный, Вы должны, должен использовать wp_reset_postdata() поскольку Вы не изменяете основной запрос, таким образом, он не должен быть сброшен.

Что делает wp_reset_query...

Вдобавок к вызову wp_reset_postdata(), wp_reset_query() просто заменяет основной запрос $wp_query с $wp_the_query (сохраненная копия). Эти два связаны ссылкой и так должны быть идентичными..., если связь не разорвана и $wp_query изменяется query_posts() (для который wp_reset_query() предназначается).

Что происходит когда query_posts() используется...

Вот то, где проблемы запускаются. query_posts() изменяет запрос $wp_query и повреждает ссылку. Это - то, что Вы циклично выполняете через. Позволяет предполагают, что первое сообщение в этом новом цикле является тем с помощью shortcode. В Вашем обратном вызове вызова Вы используете wp_reset_query().

$wp_query теперь задержан к исходному запросу - который был для сообщения, которое мы только что распечатали. Таким образом, цикл по существу сбрасывается (в этом моем комментарии к вопросу, был немного неправильный*) к исходному запросу. Этот цикл печатает содержание сообщения и достигает конца.

Почему делает использование wp_reset_postdata 'решить' его?

Если Вы используете query_posts() и результатом является просто одно сообщение, которое Вы, после - это приведет к дублированию.

Почему не делает использования wp_reset_postdata 'решить' его?

Если Вы используете query_posts() и результат включает другие сообщения затем, первичная обработка цикла будет включать эти другие сообщения.

Решение:

Короче говоря использование настоящей проблемы query_posts(). Не используйте его. Используя wp_reset_postdata, хотя корректная вещь использовать в этом случае, просто маскирует ошибку.

Но я не использую query_posts()...

Я не могу быть уверен, что нет других ошибок, которые вызвали бы то, что Вы видите. Но на 'чистой' установке - Вы не должны видеть его с Вашим выше кода (я протестировал).

*Если $wp_query и $wp_the_query все еще связаны ссылкой затем, мой комментарий на самом деле корректен.

3
19.02.2020, 23:37

Как предложено @hampsun выше, добавляя wp_reset_postdata() устраненный двойная выходная проблема. Пользовательский цикл теперь читает:

[...]

function cw_output_fashion_films($atts){

    $post_type = $atts['type'];
    $tax = $atts['tax'];
    $tax_terms = get_terms($tax);

    if ($tax_terms) {
      echo "<ul>";
      foreach ($tax_terms  as $tax_term) {
        $args=array(
          'post_type' => $post_type,
          "$tax" => $tax_term->slug,
          'post_status' => 'publish',
          'posts_per_page' => -1,
          'ignore_sticky_posts'=> 1
        );

        $my_query = null;
        $my_query = new WP_Query($args);
        if( $my_query->have_posts() ) {
          echo "<li class='letter'>" . $tax_term->name . "</li>";
          while ($my_query->have_posts()) : $my_query->the_post(); ?>
            <li><a href="<?php the_permalink() ?>" rel="bookmark" title="Permanent Link to <?php the_title_attribute(); ?>"><?php the_title(); ?></a></li>
            <?php
          endwhile;
        }
        wp_reset_postdata();
      } //end foreach loop
      echo "</ul>";
    }
}

Никакая идея после того, чтобы читать документацию относительно того, почему это работает: http://digwp.com/2011/09/3-ways-to-reset-the-wordpress-loop/#wp_reset_postdata

0
19.02.2020, 23:37
  • 1
    Вы все еще используете echo. Это неправильно в shortcode обработчике. большое спасибо –  fuxia♦ 08.10.2012, 17:04

В то время как другие ответы более конкретны, у Вас есть несколько более срочная проблема:

Shortcodes не должен создавать вывод.

Которым, я подразумеваю, что Ваша shortcode функция-обработчик никогда не должна, "повторять" что-либо. Это должно создать строку и возвратить его. shortcode код обработки будет заботиться о вставке его в содержание правильно и echo'ing он для Вас.

Если Вы повторите вещи сами, то Ваш shortcode будет несовместимым с партиями и большим количеством других вещей. Shortcodes не обрабатываются только при выводе содержания они могут быть обработаны другим кодом также.

Повторение во время shortcode (или фильтр) будет иногда заставлять Ваш вывод быть произведенным дважды, или больше, потому что Ваш shortcode может быть выполнен дважды (или больше) на той же загрузке страницы.

Измените свою функцию для возврата строки вместо того, чтобы повторить содержание, которое Вы пытаетесь произвести.

Подробнее: http://ottopress.com/2011/actions-and-filters-are-not-the-same-thing/

4
19.02.2020, 23:37

Теги

Похожие вопросы