脱wordpress初心者!親カテゴリー別で子カテゴリー別の複雑な記事一覧を出力する方法

こんにちは、Webエンジニアのカズキです。

普段は、Webサービスを開発したり、初心者プログラマー向けにプログラミングの解説などしています。

今日はアコギの練習をずっとしてました。

食事中にワインを飲みながらギターで弾き語りをして、なんかオシャレな感じもするけど、よく考えると行儀悪いよね。

そんな一日の締めにブログを仕上げていきたいと思います。

今回のブログ記事の内容はwordpressについてです。

プログラミング初心者が、wordpressでよくつまずいてしまいがちな、複雑なループの出力について解説していきたいと思います。

親子関係のあるカテゴリー一覧別に記事一覧を出す

言葉で説明すると意味わかりませんが、htmlタグにするとこんな感じ。

<ul>
    <li>親カテゴリー1
        <ul>
            <li>子カテゴリー1-1
                <ul>
                    <li>テスト投稿8</li>
                    <li>テスト投稿7</li>
                    <li>テスト投稿6</li>
                    <li>テスト投稿5</li>
                    <li>テスト投稿4</li>
                </ul>
            </li>
            <li>子カテゴリー1-2
                <ul>
                    <li>テスト投稿8</li>
                    <li>テスト投稿7</li>
                    <li>テスト投稿6</li>
                    <li>テスト投稿5</li>
                    <li>テスト投稿4</li>
                </ul>
            </li>
        </ul>
    </li>
    <li>親カテゴリー2
        <ul>
            <li>子カテゴリー2-1
                <ul>
                    <li>テスト投稿8</li>
                    <li>テスト投稿7</li>
                    <li>テスト投稿6</li>
                    <li>テスト投稿5</li>
                    <li>テスト投稿4</li>
                </ul>
            </li>
            <li>子カテゴリー2-2
                <ul>
                    <li>テスト投稿8</li>
                    <li>テスト投稿7</li>
                    <li>テスト投稿6</li>
                    <li>テスト投稿5</li>
                    <li>テスト投稿4</li>
                </ul>
            </li>
        </ul>
    </li>
</ul>

どうやってループさせるかわかりますか?

wordpressを使い始めたばかりの初心者プログラマーにとっては複雑だなって思うかもしれません。

しかし、冷静になって処理を分割して考えれば、きっとわかるはずです。

まず、親カテゴリーだけの配列を取得してループさせます。

get_terms()というwordpressの関数にタクソノミー(category)と親カテゴリーだけを指定する引数(array('parent' => 0))を設定することで親カテゴリーの配列を取得できます。

取得した親カテゴリーの配列をforeachでループさせるおとによて、親カテゴリーのカテゴリ名の一覧を出力させることができます。

$parents = get_terms('category', array('parent' => 0));
if (! empty($parents) && ! is_wp_error($parents)) {
    foreach ($parents as $parent) {
        print '<li>'.$parent->name . '</li>';
    }
    unset($parent);
}

親カテゴリーに属した子カテゴリー一覧出力

親カテゴリー一覧のループの中でterm_idを利用して、親カテゴリーに属した子カテゴリーの配列を取得します。

$parent->nameでカテゴリー名を取得できましたが、$parent->term_idとすれカテゴリーのIDが取得できます。

先程と同じようにget_termsを利用して子カテゴリー一覧を取得してループさせrます。

$children = get_terms('category', array('parent' => $parent->term_id));
if (! empty($children) && ! is_wp_error($children)) {
    foreach ($children as $child) {
        print '<li>' . $child->name . '</li>';
    }
    unset($child);
}

子カテゴリーに属する投稿記事一覧を出力

さらに同じように、子カテゴリー一覧のループの中で$child->term_idを利用して投稿記事も取得していきます。

投稿一覧を取得するwordpressの関数はget_posts()です。

get_postsの引数に子カテゴリーに属した記事一覧だけを配列で取得する場合は、こんな感じに書きます。

$post_data = get_posts(array(
    'posts_per_page' => -1,
    'category' => $child->term_id
));

ループさせて、出力も書くとこうなります。

//投稿のループ
$post_data = get_posts(array(
    'posts_per_page' => -1,
    'category' => $child->term_id
));
if ($post_data) {
    foreach ($post_data as $data) {
        printf('<li><a href="%s">%s</a></li>', get_the_permalink($data->ID), $data->post_title);
    }
    unset($data);
}

get_the_permalink()もwordpressの関数で、投稿のIDを指定することでリンクを返してくれます。

全部まとめるとこうなる

<ul>
    <?php
        //親カテゴリーのループ
        $parents = get_terms('category', array('parent' => 0));
        if (! empty($parents) && ! is_wp_error($parents)) {
            foreach ($parents as $parent) {
                print '<li>'.$parent->name . '<ul>';

                //子カテゴリーのループ
                $children = get_terms('category', array('parent' => $parent->term_id));
                if (! empty($children) && ! is_wp_error($children)) {
                    foreach ($children as $child) {
                        print '<li>' . $child->name . '<ul>';

                        //投稿のループ
                        $post_data = get_posts(array(
                            'posts_per_page' => -1,
                            'category' => $child->term_id
                        ));
                        if ($post_data) {
                            foreach ($post_data as $data) {
                                printf('<li><a href="%s">%s</a></li>', get_the_permalink($data->ID), $data->post_title);
                            }
                            unset($data);
                        }
                        print '</ul></li>';
                    }
                    unset($child);
                }
                print '</ul></li>';
            }
            unset($cat);
        }
    ?>
</ul>

これで一応完成ですが、ちょっと見にくいですよね。

関数にして見やすくするとこうなる

<ul>
<?php
    //関数実行
    cats_list_posts();

    //親カテゴリー、子カテゴリー、投稿一覧出力する関数
    function cats_list_posts()
    {
        print parents_cats();
    }

    //親カテゴリーのループ
    function parents_cats()
    {
        $html = '';
        $parents = get_terms('category', array('parent' => 0));
        if (! empty($parents) && ! is_wp_error($parents)) {
            foreach ($parents as $parent) {
                $html .= '<li>'.$parent->name . '<ul>';
                $html .= children_cats($parent);
                $html .= '</ul></li>';
            }
            unset($cat);
        }
        return $html;
    }

    //子カテゴリーのループ
    function children_cats($parent)
    {
        $html = '';
        $children = get_terms('category', array('parent' => $parent->term_id));
        if (! empty($children) && ! is_wp_error($children)) {
            foreach ($children as $child) {
                $html .= '<li>' . $child->name . '<ul>';
                $html .= children_cats_posts($child);
                $html .= '</ul></li>';
            }
            unset($child);
        }
        return $html;
    }

    //投稿のループ
    function children_cats_posts($child)
    {
        $html = '';
        $post_data = get_posts(array(
            'posts_per_page' => -1,
            'category' => $child->term_id
        ));
        if ($post_data) {
            foreach ($post_data as $data) {
                $html .= sprintf('<li><a href="%s">%s</a></li>', get_the_permalink($data->ID), $data->post_title);
            }
            unset($data);
        }
        return $html;
    }
?>
</ul>

使いまわしをしたい場合は、functions.phpに関数を書いて、利用してください。

わかりましたでしょうか?

質問などありましたら気軽にどうぞ。

正社員という奴隷制度に中指を立てるWebエンジニアです。PHPが得意。繋がれた鎖を断ち切るために、自由を取り戻すために、プログラミングスキルを磨く日々です。プログラミングと個人でもできるビジネスについて、情報発信しています。

詳しくはこちら