タグ別アーカイブ: 子ページ

親ページなら子ページのリストを、子ページなら記事本文を表示する

カスタム投稿タイプでいくつかのページを作ったけど、親ページには子ページのリストを表示したい!
ということで、下記の方法に辿り着いたわけだけど、なんか、もっと簡単な方法ないのかな。。。?

とりあえずはできてるのでメモ

テンプレートヒエラルキー抜粋

上図をみるとカスタム投稿は single-$posttype.php を見に行く。
そして、ブログ投稿は single-post.php を見る。

そこで、まず、single-post.php があるかどうか確認。
標準で存在するものと思っていたファイルだけれど、なかったので single.php を single-post.php としてコピー。

また、single.php は最終的に他のテンプレートからも参照される可能性があるので、カスタム投稿ファイル用に single-$posttype.php なるものを作るほうがベターかも。
これは、「親ページでは子ページのリストを表示したいカスタム投稿タイプ」のページ分、作る必要がありそう。

とはいえ、上図で single.php を参照するもう一つは「添付ファイル投稿」なので、直接 single.php を書き換えてしまっても良いのかな。
(実は、今のところ、直接 single.php を書き換えてたりする)

さて、これで「ブログ投稿」は「single-post.php」を参照、「カスタム投稿タイプ」は「sinle.php」を参照することになる。

ということは、single.php に手を加えれば、リスト表示ができる?

確かに、single.php にリスト化するスクリプトを記述すれば表示はされる。
けど、よく見るとコンテンツを表示するために「get_template_part()」が使われている。

「ブログ投稿」の場合には「get_template_part( 'content', get_post_format() );」となっていて
content-[post_format].php というファイルが読み込まれるようになっている。

であれば、「カスタム投稿タイプ」を表示する際には「single.php」を読み込み、さらにそこから「custom-xxxxx.php」といったファイルを読み込ませれば効率的。

この場合には「get_template_part( 'content', 'xxxxx' );」といった具合に。
xxxxxは任意で、今回は「custom」としてみようかと思う。

というわけで、content.php を content-custom.php とでもしてコピーし、下記内容に適宜書き換える。

 <?php if ( is_search() ) : // Only display Excerpts for Search ?>
  <div class=”entry-summary”>
   <?php the_excerpt(); ?>
  </div><!– .entry-summary –>
 <?php else : ?>
  <div class=”entry-content”>

// 親ページかどうかの判別。親ページは $post->post_parent が「0」
  <?php if ( is_single() && $post->post_parent == 0 ) : ?>
   <ul>
    <?php
    $all_lists = get_posts( array( 'post_type' => get_post_type($post),
                                   &#39orderby&#39 => 'menu_order',
                                   'order' => 'ASC',
                                   'posts_per_page' => 30));
    array_shift($all_lists);
    foreach($all_lists as $post) {
     setup_postdata($post);
    ?>
    <li>
     <a href=”<?php the_permalink() ?>”><?php the_title() ?></a>
    </li>
    <?php
    }
    ?>
   </ul>
  <?php else : // 子ページなら投稿記事本文を表示 ?>
   <?php the_content( __( 'Continue reading <span class=”meta-nav”>→</span>', 'twentytwelve' ) ); ?>
   <?php wp_link_pages( array( 'before' => '<div class=”page-links”>' . __( 'Pages:', 'twentytwelve' ), 'after' => '</div>' ) ); ?>
  <?php endif; ?>
  </div><!– .entry-content –>
 <?php endif; ?>

とまぁ、ざっと書いちゃったけど、大事なのは以下の部分かな。

    $all_lists = get_posts( array( 'post_type' => get_post_type($post),
                                   'orderby' => 'menu_order',
                                   'order' => 'ASC',
                                   'posts_per_page' => 30));

‘orderby’ => ‘menu_order’
‘order’ => ‘ASC’
で、「ページ属性」の「順序」通りに並び替える。

‘posts_per_page’ => 30
は、まぁ、適当に子ページが30を越えてるなら、50とか100にね。

array_shift($all_lists);
おそらく、親ページの「ページ属性」「順序」は「0」としているはず。
とすると、配列の先頭に親ページがくるので、array_shift()で先頭を取り出してしまう。
(親ページに子ページのリストを表示したいんだから、親ページは不要でしょ?)
もし、「ページ属性」「順序」「0」が他にもあるなら、期待した動作にならないので、要注意。
個人的には、親ページの順序は「0」子ページは「1」から振ってくようにしている。
(ただ、親ページを最初に作っておけば、「0」でも大丈夫みたいだけどね、念のため)

    foreach($all_lists as $post) {
     setup_postdata($post);
    ?>
    <li>
     <a href=”<?php the_permalink() ?>”><?php the_title() ?></a>
    </li>
    <?php
    }
    ?>
   </ul>

あとは、foreachで回して、タイトルとパーマリンクを使ってリストにする。

  <?php else : // 子ページなら投稿記事本文を表示 ?>
   <?php the_content( __( 'Continue reading <span class=”meta-nav”>→</span>', 'twentytwelve' ) ); ?>
   <?php wp_link_pages( array( 'before' => '<div class=”page-links”>' . __( 'Pages:', 'twentytwelve' ), 'after' => '</div>' ) ); ?>
  <?php endif; ?>
  </div><!– .entry-content –>
 <?php endif; ?>

ここは content.php の中身そのままなので、特筆なし。