Крайне неэффективные циклы 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 циклов!!)
Это явно совершенно неэффективно, но довольно просто, я не знаю, как написать лучший код, чем этот, и мне нужна помощь!
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; ?>
Посмотрим, даст ли это желаемый эффект..:)
Я бы также рекомендовал использовать пользовательские таксономии. Пересечение таксономий "Инструмент" и "Игрок" позволило бы быстро справиться с этим. Но если это непрактично, возможно, это может сработать:
$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;
Эм... вам не нужно писать цикл снова и снова. Работайте только над той частью, которая изменилась. Цикл все равно будет проходить через все наборы данных. Кстати: я бы не стал создавать для этого пользовательские поля. Таксономия "инструменты" с "скрипкой", "альтом" и т. Д. В качестве термина была бы намного проще и дала бы вам гораздо больше возможностей (а именно теги шаблонов), например. создание подаксов, таких как "духовые инструменты", "ударные инструменты" и т. Д. Вы также должны переместить оператор 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 - для каждого инструмента.