【WordPress】カテゴリーリストを自作する方法

2018年11月8日
カテゴリーリスト

WordPressでカテゴリーリストを設置する際に、プラグインを使いたくなかったため自作した。

手順

カテゴリーリストを表示するクラスを定義する

下記のクラスをPHPファイルに定義する。

出力するタグやそれに付与する属性を任意で指定するため、wp_list_categories関数を使用せずに実装してある。

class CategoryList {
    const NEST_SIZE                 = 10;
    const RELATIONSHIP_NAME_LIST    = [
        'parent',
        'children',
        'grandchildren',
    ];

    private function __construct() {}

    public static function show() {
        echo '<section class="category-list">';
        self::show_title();

        echo '<div class="content">';

        $categories = get_categories( [ 'parent' => 0 ] );
        self::show_items( $categories, self::get_current_uri(), 0 );

        echo '</div></section>';
    }

    private static function show_title() {
        echo '<h3 class="title">カテゴリー</h3>';
    }

    private static function get_current_uri() {
        $protocol   = is_ssl() ? 'https://' : 'http://';
        $uri        = $protocol.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'];

        return $uri;
    }

    private static function show_items( $categories, $current_uri, $nest_count ) {
        $relationship_name = self::RELATIONSHIP_NAME_LIST[$nest_count];
        printf( '<ul class="%s">', $relationship_name );

        foreach ( $categories as $category ) {
            $child_categories   = get_categories( [ 'parent' => $category->cat_ID ] );
            $have_categories    = $child_categories !== [];

            self::show_item( $category, $nest_count, $current_uri );

            if ( $have_categories ) {
                self::show_items( $child_categories, $current_uri, $nest_count + 1 );
            }

            echo '</li>';
        }

        echo '</ul>';
    }

    private static function show_item( $category, $nest_count, $current_uri ) {
        $uri        = get_category_link( $category->cat_ID );
        $is_current = $uri === $current_uri;
        $classes    = $is_current ? 'item current' : 'item';
        $style      = sprintf( 'style="padding-left: %spx"', ( $nest_count + 1 ) * self::NEST_SIZE );
        $name       = $category->name;
        $count      = self::get_article_count( $category );

        echo <<< EOT
<a href="$uri">
    <div class="$classes" $style>
        <span class="text">$name</span><span class="count">$count</span>
    </div>
</a>
EOT;
    }

    private static function get_article_count( $category ) {
        $count              = $category->count;
        $child_categories   = get_categories( [ 'parent' => $category->cat_ID ] );

        foreach ( $child_categories as $child_category ) { 
            $count += self::get_article_count( $child_category );
        }

        return $count;
    }
}

表示させたい箇所で関数を呼ぶ

テンプレートファイルの表示させたい箇所で下記の関数を呼ぶ。

CategoryList::show();

これでその箇所に次のようなHTMLが出力される。

<section class="category-list">
	<h3 class="title">カテゴリー</h3>
	<div class="content">
		<ul class="parent">
			<a href="http://sample.com/category/hoge/">
    			<div class="item" style="padding-left: 10px">
					<span class="text">ほげ</span><span class="count">1</span>
				</div>
			</a>
			<a href="http://sample.com/category/fuga/">
    			<div class="item" style="padding-left: 10px">
        			<span class="text">ふが</span><span class="count">2</span>
				</div>
			</a>
			<a href="http://sample.com/category/piyo/">
				<div class="item" style="padding-left: 10px">
					<span class="text">ぴよ</span><span class="count">3</span>
				</div>
			</a>
		</ul>
	</div>
</section>

CSSで見た目を整える

後は出力されたHTMLの各要素に付いているクラスを用いて、CSSで見た目を整える。