web-dev-qa-db-ja.com

非常に非効率なワードプレスループ!

私は現在、オーケストラのためにサイトに取り組んでいます。彼らの楽器によると、さまざまなメンバーをリストする必要があります。メンバーにはカスタム投稿タイプのバイオグラフィーがあり、カスタムフィールドを介して商品の価値を把握しています。

関連するセクションに関連する人々を表示する方法を理解する唯一の方法は、カスタム投稿タイプを何度も繰り返して、メタ値を比較して特定の楽器を演奏する人々を表示することです。

コードは次のようになります。

<?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のループがあります!!)

これは明らかに全く非効率的ですが、ごく簡単に言うと、これより良いコードを書く方法がわからないし、助けが必要です!

1
Richard Sweeney

あなたはそれを1つのループで行うことができます、あなたはちょうど正しいソート順が必要ですか?ある楽器を持っているプレイヤー、それに続くものなど。

UPDATE:質問者のコメントに従うと、それでも1つのクエリを使用して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
t31os

カスタム分類法の使用もお勧めします。 'Instrument'と 'Player'のタクソノミの間の共通部分はこれを短くします。しかし、それが現実的でない場合は、おそらくこれでうまくいく可能性があります。

$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
Dougal Campbell

うーん...繰り返しループを書く必要はありません。変更された部分にのみ取り組んでください。ループはとにかくすべてのデータセットを通過します。ところで:私はこれのためにカスタムフィールドを作りません。用語として「バイオリン」、「ビオラ」などを使用した「楽器」分類法は、はるかに簡単になり、より多くの可能性を与えるでしょう (つまりテンプレートタグ) 。 "管楽器"、 "打楽器"などのサブタクスを作成することもできます。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;

編集: "Instruments"という名前のカスタム分類法を利用してから、希望の順序でクエリをフィルタリングできます。

// @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;

ただ1つのループを作り、while-loopの内側で、単に用語とecho/displayのことを疑問に思うようにしてください。 if ( has_term(を使用する代わりに、読みやすくするためにスイッチを使用することもできます。

このソリューションを使用すると、get_post_meta()を使用したそれ以上のDB呼び出しが回避されます。これは、すべてのインストゥルメントについて、postオブジェクトではなくDBを呼び出すのと同じです。

0
kaiser