taxsonomy-A.php 内に タクソノミーBで区切った表示をさせたい
-
カスタム投稿で「料理」を制作したとします。
タクソノミーに「食材」と「料理時間」を設定しました。食材(taxsonomy-A)
-肉(termA-1)
-魚(termA-2)
-野菜(termA-3)料理時間(taxsonomy-B)
-10分(termB-1)
-20分(termB-2)
-30分(termB-3)taxsonomy-A.phpの中で
termB-1に属する物だけ表示、termB-2に属する物だけ表示、termB-3に属する物だけ表示、
と教示するり方を教えていただけないでしょうか?taxsonomy-A.php で 肉が選択されている場合
taxsonomy-A.phpの中で以下のような表示をしたいと考えています。【肉料理】
10分
記事1/記事3/記事13
20分
記事4/記事6/記事20
30分
記事2/記事7/記事15
-
以下の方法で一応、肉-10分、20分、30分 等表示できました。
ただ、40分が加わった時にまた修正が必要なので、
引き続きループ処理で表示するやり方を模索中です。<h3>10分</h3>
<?php while (have_posts()) : the_post(); ?>
<?php
$cat = get_the_category();
$catslug = $cat[0]->category_nicename;
?>
<?php if ( is_object_in_term($post->ID, ‘taxsonomy-B’,’termB-1′) ): ?>
<h4>“><?php the_title_attribute(); ?></h4>
<?php endif; ?>
<?php endwhile; ?><h3>20分</h3>
<?php while (have_posts()) : the_post(); ?>
<?php
$cat = get_the_category();
$catslug = $cat[0]->category_nicename;
?>
<?php if ( is_object_in_term($post->ID, ‘taxsonomy-B’,’termB-2′) ): ?>
<h4>“><?php the_title_attribute(); ?></h4>
<?php endif; ?>
<?php endwhile; ?><h3>30分</h3>
<?php while (have_posts()) : the_post(); ?>
<?php
$cat = get_the_category();
$catslug = $cat[0]->category_nicename;
?>
<?php if ( is_object_in_term($post->ID, ‘taxsonomy-B’,’termB-3′) ): ?>
<h4>“><?php the_title_attribute(); ?></h4>
<?php endif; ?>
<?php endwhile; ?>いろいろ方法はあると思いますが、こちらはメインループでは投稿を並び替えるだけにし、サブループで表示するという方法です。
<?php $post_lists = array(); // メインループ while ( have_posts() ): the_post(); $the_terms = get_the_terms($post, 'taxsonomy-B'); $the_term = reset($terms); if ( empty($post_lists[$the_term->term_id]) ): $post_lists[$the_term->term_id] = array($the_term->name); endif; $post_lists[$the_term->term_id][] = $post; endwhile; // サブループ foreach ( $post_lists as $term_id => $post_list ): // ターム毎のループ foreach ( $post_list as $key => $_post ): if ( $key === 0 ): ?> <h3><?php echo $_post; ?></h3> <?php else: <h4><a href="<?php echo esc_url(get_permalink($_post)); ?>"><?php echo strip_tags(get_the_title($_post)); ?></a></h4> <?php endif; endforeach; endforeach; ?>
まずメインループ内で
$post_lists
に、タクソノミーBのタームごとに投稿データを格納していき、多次元配列を作ります。
この時、ターム名もついでに取得しておきます。
次にサブループを作り、ターム毎にさらにループを組んで表示します。
サブループ内でタームの情報が必要なら$term_id
にタームIDが格納されています。
投稿がもし複数のタームを持つなら、(タームID順で)最初のタームにしか表示されません。動作確認はしていませんが、参考にしてください。
お礼遅くなりました。
ありがとうございます。いろいろ工夫してみましたが、
本質を理解できていないので修正に至りませんでした。<h3><?php echo $_post; ?></h3>
が空っぽになるのが直せませんでした。ありがとうございました。
ごめんなさい、コードの7行目の変数名が普通に間違ってました。
reset($terms)
ではなくreset($the_terms)
ですね。
それと、19行目(下から6行目)のelse:
のあとで?>
を書くのを忘れていました。
初歩的なミスばかりですみません、動作確認はするものですね……
ただ、これらのミスだと<h4>
も正しく表示されないはずですが、大丈夫でしたか?それと、上記のコードだと万一投稿がタームを持たない場合にエラーになりそうなので、修正してみました。
<?php $post_lists = array(); // メインループ while ( have_posts() ): the_post(); $the_terms = get_the_terms($post, 'taxsonomy-B'); if ( ! $the_terms ): continue; endif; $the_term = reset($the_terms); $the_term_id = $the_term->term_id; if ( empty($post_lists[$the_term_id]) ): $post_lists[$the_term_id] = array($the_term->name); endif; $post_lists[$the_term_id][] = $post; endwhile; // サブループ foreach ( $post_lists as $term_id => $post_list ): // ターム毎のループ foreach ( $post_list as $key => $_post ): if ( $key === 0 ): ?> <h3><?php echo $_post; ?></h3> <?php else: ?> <h4><a href="<?php echo esc_url(get_permalink($_post)); ?>"><?php echo strip_tags(get_the_title($_post)); ?></a></h4> <?php endif; endforeach; endforeach; ?>
これでどうでしょうか。
ものすごく細かくて意地悪な話かと思いますが、少しだけ進言させてください。
postなど環境準備語とそれに近いものは独自用途での変数名に使用しないほうがいいとおもいます。
PHPのプログラミングについてのお話なのでワードプレス本体とは離れてしまうので簡単にお話できればと思うのですが
foreach の書き方で私が実践しているものをご紹介いたします。
ちょっと初心者むけでいらっとするかとおもいますが、もしか初心者の方にも目に留まれば参考いただけるといいなと思い、かきます。foreach(配列変数を最初から最後までひとつづつ代用して終了するループ)
foreach($post_list(対象となる配列変数) as(当該位置のデータを次の変数に代入する) $key(連想配列の配列名) => $_post(連想配列のデータ名) )なのですが、一般的なトレンドは
foreach ( $arrayed_data as $key => $value )
です。このKEYとVALUEはループ内でしか利用できない一時的な変数なのでこの名前で問題ないと思います。
ただこれをさらにループの中におさめるなどの多段になると同じ名前が利用できません。
なので毎回、一段であってもforeach ( $arrayed_data as $key_ad(arrayed_dataの略) => $value_ad )
と対象の変数の略語をつけるようにしています。ロシアの人の名前で「父親の名前をミドルネームにする」みたいなものです。
すると一時変数だけども用途が可視化されるのでプログラミングが捗ると思います。foreachの中に同じ変数でforeachをまわすとどっちのデータかわからない、というかあとから入れた変数がはいってしまうので
ごちゃまぜになり思った結果がでなくなると思いますのでそれを回避もできます。同じようにスーパーグローバルといった環境で準備されている変数名などに一時的なデータをいれてしまうと
全体がへんなことになってしまう可能性があります。
$post はワードプレスが記事を読みだしたときにループ用でよくつかっているのをみかける変数ですね。
$_POSTはPHPがPOST形式でデータが転送されてきたときの受信変数に使用されます。いかがでしょうか。
勉強になります。
foreach ( $arrayed_data as $key => $value )
という書き方は普段は使っていますが、ここではあえて、何の変数かわかりやすいように書きました。
$_post
という変数名については、WordPressのソースファイルのあちこちで使われているので、おそらくグローバル変数や準備語の類ではないと考えておりました。
もちろん避けられる問題は避けるに越したことはないので、変数名を変えるのもやぶさかではありません。2週間経ってしまいましたが、やっと着手&8割型うまくいきました!
ありがとうございます!もし、どなたかにこのメッセージが届いたらで良いのですが、
タームの「説明」の欄に番号を付け足したので、
その番号でソートして一覧を出力する方法を教えていただけないでしょうか?‘orderby’ => ‘description’
をどこに挟めば良いか、お手数ですがお教えください。
よろしくお願いします。もしかして、なのですが、そのアイデアはこの記事が元ネタですか?
http://labe.wp.xdomain.jp/post/367
違ったらごめんなさい。ちなみにこの記事を書いたのは俺です。ところで、俺がこのトピックの上記で紹介した方法は、その
orderby
とは全く異なる方法でデータを処理しているため、残念ながらその方法は使えません。
しかし、タームの「説明」が“PHPの配列のキー名として使用可能な文字”(半角英数字など)のみで記述されており、かつ各ターム間で重複がないなら、少し修正すれば実現可能です。<?php $post_lists = array(); // メインループ while ( have_posts() ): the_post(); $the_terms = get_the_terms($post, 'taxsonomy-B'); if ( ! $the_terms ): continue; endif; $the_term = reset($the_terms); $the_term_id = (int) $the_term->description; if ( empty($post_lists[$the_term_id]) ): $post_lists[$the_term_id] = array($the_term->name); endif; $post_lists[$the_term_id][] = $post; endwhile; // サブループ ksort($post_lists); foreach ( $post_lists as $term_id => $post_list ): // ターム毎のループ foreach ( $post_list as $key => $_post ): if ( $key === 0 ): ?> <h3><?php echo $_post; ?></h3> <?php else: ?> <h4><a href="<?php echo esc_url(get_permalink($_post)); ?>"><?php echo strip_tags(get_the_title($_post)); ?></a></h4> <?php endif; endforeach; endforeach; ?>
前回のコードから2ヶ所だけ変わっています。
11行目が変わっているのと、17行目と18行目の間に1行追加しています。
- トピック「taxsonomy-A.php 内に タクソノミーBで区切った表示をさせたい」には新たに返信することはできません。