Крайне неэффективные циклы wordpress!


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

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

Код выглядит следующим образом:

<?php $args = array( 'post_type' => 'biographies', 'posts_per_page' => -1 ); ?>

    <ul class="no-bull hijax">
        <?php $biog = new WP_Query($args);
            if( $biog->have_posts() ) : while( $biog->have_posts() ) : $biog->the_post();
                $player = get_post_meta($post->ID, 'player', true);
                if ($player == 'yes') :
                    $instrument = get_post_meta($post->ID, 'instrument', true);
                    if ($instrument == 'violin') :
                    ?>
                        <li><a id="artist_id_<?php the_ID(); ?>" class="nb" href="<?php the_permalink(); ?>"><?php the_title(); ?></a> : <?php echo($instrument); ?></li>
                    <?php
                    endif;
                endif;
            endwhile; endif;
        wp_reset_query();
        $biog = new WP_Query($args);
            if( $biog->have_posts() ) : while( $biog->have_posts() ) : $biog->the_post();
                $player = get_post_meta($post->ID, 'player', true);
                if ($player == 'yes') :
                    $instrument = get_post_meta($post->ID, 'instrument', true);
                    if ($instrument == 'viola') :
                    ?>
                        <li><a id="artist_id_<?php the_ID(); ?>" class="nb" href="<?php the_permalink(); ?>"><?php the_title(); ?></a> : <?php echo($instrument); ?></li>
                    <?php
                    endif;
                endif;
            endwhile; endif;
        wp_reset_query(); 
        $biog = new WP_Query($args);
            if( $biog->have_posts() ) : while( $biog->have_posts() ) : $biog->the_post();
                $player = get_post_meta($post->ID, 'player', true);
                if ($player == 'yes') :
                    $instrument = get_post_meta($post->ID, 'instrument', true);
                    if ($instrument == 'cello') :
                    ?>
                        <li><a id="artist_id_<?php the_ID(); ?>" class="nb" href="<?php the_permalink(); ?>"><?php the_title(); ?></a> : <?php echo($instrument); ?></li>
                    <?php
                    endif;
                endif;
            endwhile; endif;
        wp_reset_query();

И т. Д. и т. Д. до тошноты. (в настоящее время на странице 12 циклов!!)

Это явно совершенно неэффективно, но довольно просто, я не знаю, как написать лучший код, чем этот, и мне нужна помощь!

Author: Richard Sweeney, 2011-03-03

3 answers

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

ОБНОВЛЕНИЕ: Следуя комментарию спрашивающего, вы все равно можете использовать один запрос и использовать rewind_posts() для повторения цикла столько раз, сколько вам нужно, т. Е. сделайте что-то подобное, чтобы получить пользовательскую сортировку..

<?php
// Add the instruments into the array below, in the order you want them in.
$instruments = array( 'violin', 'viola', 'cello' );

$args = array( 
    'post_type' => 'biographies', 
    'posts_per_page' => -1,
    'nopaging' => true,
    'surpress_filters' => true,
    'meta_query' => array(
        array(
            'key' => 'player',
            'value' => 'yes',
            'compare' => '=',
            'type' => 'CHAR'
        ),
        array(
            'key' => 'instruments',
            'value' => $instruments,
            'compare' => 'IN',
            'type' => 'CHAR'
        )
    ),
); 

$bios = new WP_Query( $args);
?>

<?php if( $bios->have_posts() ) : ?>

    <ul class="no-bull hijax">

    <?php
    foreach( $instruments as $instrument ) :

        while( $bios->have_posts() ) : $bios->the_post();

            $player_instrument = get_post_meta( get_the_ID(), 'instrument', true );

            if( $instrument != $player_instrument )
                continue;
        ?>

        <li><a id="artist_id_<?php the_ID(); ?>" class="nb" href="<?php the_permalink(); ?>"><?php the_title(); ?></a> : <?php echo $player_instrument; ?></li>

        <?php 

        endwhile; 
        rewind_posts();

    endforeach;
    wp_reset_query();
    ?>

    </ul>

<?php endif; ?>

Посмотрим, даст ли это желаемый эффект..:)

 2
Author: t31os, 2011-03-03 23:55:22

Я бы также рекомендовал использовать пользовательские таксономии. Пересечение таксономий "Инструмент" и "Игрок" позволило бы быстро справиться с этим. Но если это непрактично, возможно, это может сработать:

$args = array(
  'post_type' => 'biographies',
  'posts_per_page' => -1,
  'meta_key' => 'instrument',
  'orderby' => 'meta_value'
);

query_posts($args);

while(have_posts()) : the_post();
  $inst = get_post_meta($post_id, 'instrument', true);
  $player = get_post_meta($post_id, 'player', true);
  if ('yes' == $player) {
  ?>
    <li><a id="artist_id_<?php the_ID(); ?>" class="nb" href="<?php the_permalink(); ?>"><?php the_title(); ?></a> : <?php echo $inst; ?></li>
  <?php
  }

endwhile;
 4
Author: Dougal Campbell, 2011-03-03 16:42:37

Эм... вам не нужно писать цикл снова и снова. Работайте только над той частью, которая изменилась. Цикл все равно будет проходить через все наборы данных. Кстати: я бы не стал создавать для этого пользовательские поля. Таксономия "инструменты" с "скрипкой", "альтом" и т. Д. В качестве термина была бы намного проще и дала бы вам гораздо больше возможностей (а именно теги шаблонов), например. создание подаксов, таких как "духовые инструменты", "ударные инструменты" и т. Д. Вы также должны переместить оператор if внутрь элемента <li>, поскольку это тоже не меняется. Единственное, что есть if $instrument == '' и echo $instrument; (которые могут быть написаны без окружающего ()).

   if ($instrument == 'violin') : // only $instrument changes, right?
   ?>
     <li>
        <a id="artist_id_<?php the_ID(); ?>" class="nb" href="<?php the_permalink(); ?>">
           <?php the_title(); ?>
        </a> : <?php echo($instrument); ?>
     </li>
   <?php
   elseif ($instrument == 'violin') :
      // do stuff...
   endif;

Редактировать: Вы можете использовать пользовательскую таксономию с именем "инструменты", а затем отфильтровать запрос в нужном порядке:

// @link: http://codex.wordpress.org/Function_Reference/taxonomy_exists  
if ( taxonomy_exists('instruments') ) :
  // @link: http://codex.wordpress.org/Function_Reference/has_term
  if ( has_term( 'instruments', 'viola', get_post_ID() ) ): 
    # DO STUFF HERE, eg. echo term
  endif;
endif;

Просто сделайте один цикл, и внутри цикла while просто задайте вопрос о термине и эхо/отображении. Вы могли бы вместо использования if ( has_term( также использовать переключатель для большей читабельности.

Используя это решение позволяет избежать дальнейших вызовов БД с помощью get_post_meta() - afaik это вызывает БД, а не объект post - для каждого инструмента.

 0
Author: kaiser, 2011-03-04 00:13:40