【WordPress】様々なループ編(その3:固定ページの子ページの一覧を取得する方法)

迷える黒猫くん
迷える黒猫くん

固定ページに親子関係を作った場合に、親ページでその子ページの一覧を取得したいのニャ。。

初めに

固定ページの子ページの一覧を取得する方法としてわざわざ独立して解説ページを設けましたが、基本的には以前解説したサブループの応用の一つです。

以前解説したサブループの解説はこちらからご覧ください。

またトップから固定ページの子ページの一覧(トップから見ると孫ページに当たる一覧)の取得方法も併せて解説していきたいと思います。

解説に至る経緯

この解説をわざわざ他のサブループと分けて解説したかった理由はまさにここにありまして、以前WordPress学習におすすめの本として紹介させていただいた「ビジネスサイトを作って学ぶ WordPressの教科書」において、私が一番理解に詰まった項目だからです。
またこの書籍では、トップから固定ページの子ページの一覧(トップから見ると孫ページに当たる一覧)の取得方法の解説コードに誤りがあったりで、解説のコード通りに記入しても表示されないといったこともあり、つまずきのポイントになっているかと思います(一応公式から訂正情報が出ておりますので貼っておきます。→「ビジネスサイトを作って学ぶWordPressの教科書 Ver. 6.x対応版」訂正情報)。
現在では書籍でも訂正されているのかもしれませんが、実際お悩みになった方もいらっしゃる方もいらっしゃるかもしれませんのでこちらの解説をしたいと思います。

固定ページにおいて子ページの一覧を取得する方法

コード

<?php
$parent_id = get_the_ID();
$args = array(
    'posts_per_page' => -1, // -1で全件表示(その他表示したい数があればその数を指定)
    'post_type' => 'page',
    'orderby' => 'menu_order',
    'order' => 'ASC',
    'post_parent' => $parent_id,
);
$child_pages = new WP_Query($args);
if ($child_pages->have_posts()) :
    while ($child_pages->have_posts()) : $child_pages->the_post();
    <!-- ここにループしたいコンテンツを記述 -->
    endwhile;
    wp_reset_postdata();
endif;
?>

サブループを使った比較的オーソドックスな記述かと思います。当ページが親となっているページの子ページを取得するために

$parent_id = get_the_ID();

としてこちらのページのIDを取得、

'post_parent' => $parent_id,

こちらで、自身のページを親とする子ページを取得するようにしています。
わかりやすいように$parent_idという変数にIDの値を格納していますが、変数に格納せず直接

'post_parent' => get_the_ID();

としてもかまいません。

「ビジネスサイトを作って学ぶ WordPressの教科書」においてはこの子ページの情報を取得する部分を以下のように関数化しfunctions.phpにて記述を加えています。

// 子ページを取得する関数
function get_child_pages($number = -1) // -1で全件表示(その他表示したい数があればその数を指定)
{
    $parent_id = get_the_ID();
    $args = array(
        'posts_per_page' => $number,
        'post_type' => 'page',
        'orderby' => 'menu_order',
        'order' => 'ASC',
        'post_parent' => $parent_id,
    );
    $child_pages = new WP_Query($args);
    return $child_pages;
}

そのため先ほどのコードは以下のようになり見通しがよくなります。

<?php
$common_pages = get_child_pages();
if ($common_pages->have_posts()) :
    while ($common_pages->have_posts()) : $common_pages->the_post();
    // ここにループしたいコンテンツを記述
    endwhile;
    wp_reset_postdata();
endif;
?>

ただ今後トップでもこの固定ページの子ページの一覧(トップページから見た孫ページの一覧)を取得するときにもfunctions.phpに追記したget_child_pages();という関数を使用するため、こちらのコードを改変することになります。さらに、固定ページとトップページでのコードの違いも理解する必要がありやや複雑になるので、私としては関数化はせず、いったん最初のやり方で進めてみたいと思います。
もちろん理解できた段階において関数化することはコードの見通しもよくなるのでおすすめですが、便宜的にいったん関数化はせずに見て行きたいと思います。

トップページで固定ページの子ページの一覧を取得する方法

コード

<?php
$shop_obj = get_page_by_path('shop');
$parent_id = $shop_obj->ID;
$args = array(
    'posts_per_page' => -1, // -1で全件表示(その他表示したい数があればその数を指定)
    'post_type' => 'page',
    'orderby' => 'menu_order',
    'order' => 'ASC',
    'post_parent' => $parent_id,
);
$shop_pages = new WP_Query($args);
if ($shop_pages->have_posts()) :
    while ($shop_pages->have_posts()) : $shop_pages->the_post();
?>
    <!-- ここにループしたいコンテンツを記述 -->
<?php
    endwhile;
    wp_reset_postdata();
endif;
?>

さきほどは自分が親ページにあたるので親ページのIDは

get_the_ID();

で取得できましたが今回呼び出しているのがトップページなのでget_the_ID();で取得できるのはトップページのIDになってしまいます。そのため取得したい孫ページの親ページを(今回の場合はスラッグが’shop’のページ)をget_page_by_path(‘shop’);で呼び出し、変数$shop_objに格納、$shop_obj->ID;でIDを取得。その後の流れは先ほどと変わりません。

このように比較すると案外単純で、子ページを取得するところを関数化してしまうよりも違いも同じ個所も明確であるように思います。

さてここからは「ビジネスサイトを作って学ぶ WordPressの教科書」で躓いた方に向けた解説になります。

書籍内では関数化しているほか以下のような記述がループ前にあります。

ループ前

<?php
$post = get_page_by_path('shop');
setup_postdata($post);
$shop_title = get_the_title();
?>
<span class="section-title-en"><?php the_field('english_title'); ?></span>
<h2 class="section-title"><?php the_title(); ?></h2>
<p class="section-lead"><?php echo get_the_excerpt(); ?></p>
<?php wp_reset_postdata(); ?>

ループの前でも固定ページである、スラッグ’shop’の固定ページからページの情報を持ってくる必要があるためです。投稿情報を$postという変数に格納(setup_postdata()に渡す引数の変数名は$postで固定されているため他の変数名はNG!)し、setup_postdata($post); ~ wp_reset_postdata();の間で指定した投稿情報を取得しています。

その後、

ループ

<?php
$shop_pages = get_child_pages(-1, get_the_ID()); // -1で全件表示(その他表示したい数があればその数を指定)
if ($shop_pages->have_posts()) :
    while ($shop_pages->have_posts()) : $shop_pages->the_post();
?>
        <!-- ここにループしたいコンテンツを記述 -->
<?php
    endwhile;
    wp_reset_postdata();
endif;
?>

このようにループをスタートさせているのですが、ここで注目すべきところは

$shop_pages = get_child_pages(-1, get_the_ID());

get_child_pagesという関数をつかっていることで分かりにくいのですが、そこに引数としてget_the_ID()を使うことで、取得したい子ページの親ページであるスラッグ名’shop’のではなく、トップページのIDを取得してしまっておりこのままでは子ページの一覧情報は取得できません。正しく親ページであるスラッグ名’shop’のIDを取得するためには以下のように書き換える必要があります。
※以下変更点のみ記述しています。

ループ前

<?php
$shop_obj = get_page_by_path('shop');
$post = $shop_obj;

としたうえで

ループ

$shop_pages = get_child_pages(-1, $shop_obj->ID); // -1で全件表示(その他表示したい数があればその数を指定)

こちらでトップページではなく取得したい子ページ一覧の親ページのIDを取得することができました!

コメント

タイトルとURLをコピーしました