5.WordPressテーマの記事一覧ページ(index.php・archive.php)とトップページ(home.php)を作成する

index.phpは、専用の記事一覧出力用のテンプレートが作成されていない場合に、代わりとなって表示される万能テンプレートで、他の記事一覧を作成する際のベースとなるテンプレートでもあります。
WordPressテーマ作成5では、記事一覧ページのベースとなる『index.php』を作成し、それをベースに記事一覧を出力するアーカイブページとTOPページを作成する方法をご紹介します。
記事一覧の要素を追加する
index.phpなどの記事一覧ページは、基本的にループ(繰り返し処理)を使用して記事一覧を出力します。
ループ内のコンテンツ部分は、作成中のWordPressテーマ内に『loop-content.php』というファイルを新たに作成しその中に記述します。
これは『home.php』や『archive.php』などの各記事一覧テンプレートでコンテンツを共通化し、ソースコードを修正・追記する場合に一つのファイルを触るだけ済むようにするためです。
※『loop-content.php』を作成しない場合は、『index.php』のループの中に直接記述してください。
index.phpにループを追加する
作成中のWordPressテーマ内に『loop-content.php』を追加したらindex.phpに要素を追加しましょう。
index.phpの<div class=”contents”>の後に追加
PHP<div class="article-list"> <?php if(have_posts()): while(have_posts()): the_post(); get_template_part('loop-content'); endwhile; endif; ?> </div>
index.phpは、URLに合わせて自動で記事一覧を生成するページなので、自動で記事を判別するメインループを使用します。
メインループ内には、先程作成した『loop-content.php』を呼び出すための記述を追加します。
※上記はテーマ直下に『loop-content.php』を設置した場合の記述です。
メインループとサブループ
index.phpを作成する前に、記事の一覧を呼び出すためのwordpressのループについて理解しておきましょう。
ループとは、WordPressのデータベースから記事のデータを抽出して表示する機能で、WordPressが自動的に処理を行うメインループと自分で抽出条件を選択するサブループが存在します。
WordPressで自動的にページを生成する上で、ループは絶対に欠かせない存在なのでメインループとサブループに分けて理解しておきましょう。
メインループ
メインループでは、呼び出されたURLなどから自動的にWordPressが必要なデータを判別し表示させるループです。表示させるコンテンツはWordPressが自動で判別するので、TOPページや記事ページ・カテゴリ、タグ、アーカイブページなどで使用します。
メインループのソース
PHP<?php if(have_posts()): while(have_posts()): the_post(); ?> ~ ループ内で表示させたい内容を記述 ~ <?php endwhile; endif; ?>
『have_posts』という関数を使って記事のデータがあるかないかを判別し、『while』より後に出力したい(タイトルやURL・コンテンツなど)を記述し、最後に『<?php endwhile; endif; ?>』でループの処理を終了させましょう。
メインループで呼び出す記事の数は、管理画面の『設定』→『表示設定』→『1ページで表示する最大投稿数』で指定できます。

サブループ
サブループは、WordPressのデータベースから抽出する記事の条件を任意に指定することができます。記事の属性や、呼び出す記事数など様々な条件を付けて呼び出すことができるので様々な場面で活躍します。
サブループには、『WP_Query』『get_posts』『query_posts(非推奨)』の3つの形式がありますが、今回は一番取得できる情報量が多く複雑な処理が可能な『WP_Query』の使い方をご紹介します。
サブループのソース
PHP<?php $args = array(ここに出力する記事の条件を記述); $the_query = new WP_Query($args); while($the_query->have_posts()): $the_query->the_post(); ?> - ループ内で表示させたい内容を記述 - <?php endwhile; wp_reset_postdata(); ?>
『array()』の中の配列で、様々な記事の抽出条件を指定することで、好きな条件の記事を出力することができます。
出力する記事の条件を指定するパラメーターについては、コーデックスに詳しく記述されていますので参考にしてください。
サブループを使用する場合は、ループ終了後に『wp_reset_postdata();』を記述して必ずループをリセットしてください。ループのリセット処理を行わないと、後のループに悪影響を与えてしまうので忘れないように注意しましょう。
サブループを自動で作成できる『WordPressサブループ自動作成ツール』を公開しました。ページネーションも自動で出力でき、カテゴリ・タグ・著者・ターム・日付・投稿・固定ページ・カスタムフィールドなど、様々な条件をセレクトボックスで選択するだけでサブループを出力するためのコードを自動で作成することができますので、ぜひ利用してみてください。
loop-content.phpに要素を追加する
ループを記述したら『loop-content.php』内に、ループ内で繰り返し出力する各要素を記述していきます。
loop-content.phpを記述
PHP<div class="article-item"> <a href="<?php the_permalink(); ?>"> <div class="img-wrap"> <?php //サムネイル if(has_post_thumbnail()) { the_post_thumbnail('large'); } else { echo '<img src="'.get_template_directory_uri().'/images/no-image.gif" alt="no-img">'; } ?> </div><!--end img-wrap--> <div class="text-wrap"> <?php //カテゴリ if(!is_category() && has_category()) { $postcat = get_the_category(); echo '<span class="article-cat">'.$postcat[0]->name.'</span>'; } //投稿日 echo '<time datetime="'.get_the_date('Y-m-d').'" class="article-date"><i class="material-symbols-outlined">schedule</i>'.get_the_date().'</time>'; ?> <!--タイトル--> <h2><?php the_title(); ?></h2> </div><!--end text-wrap--> </a> </div><!--end article-item-->
『リンク』『サムネイル画像』『カテゴリ』『記事の投稿日』『タイトル』を出力することができます。
各要素の記述が完了したら、一度ブラウザを更新して要素がきちんと入ったかを確認してみましょう。

要素の記述が間違いなければ、上記の画像のように各要素が出力されます。
ループの中に記述する各要素
投稿へのリンク
PHP<?php the_permalink(); ?>
投稿ページのURLを出力します。
サムネイル(アイキャッチ)画像
PHP<?php if(has_post_thumbnail()) { the_post_thumbnail('large'); } else { echo '<img src="'.get_template_directory_uri().'/images/no-image.gif" alt="no-img">'; } ?>
『has_post_thumbnail()』は、サムネイルセットされている場合はtrueを返す条件分岐です。サムネイルが設定されていない場合に、処理をスキップするためにif関数と組み合わせて条件分岐を行っています。elseを使用して、サムネイル画像がセットされていないときの代替画像も指定します。
『the_post_thumbnail()』は、imgタグ(<img src=”~”>)付きでサムネイル画像のURLを出力します。引数をセットすることで任意のサイズを指定することもできます。(thumbnail, medium, large, full)
カテゴリー
PHP<?php if(!is_category() && has_category()) { $postcat = get_the_category(); echo '<span class="article-cat">'.$postcat[0]->name.'</span>'; } ?>
『is_category()』は、カテゴリー一覧ページの場合は、trueを返す関数です。否定区である『!』をつけて『!is_category()』とするとカテゴリーページではない場合はtrueを返すようになります。
『has_category()』は、カテゴリーがセットされている場合はtrueを返す関数です。カテゴリーが設定されていない場合に、処理をスキップするためにif関数と組み合わせて条件分岐を行っています。
上記のように『if(!is_category() && has_category()) {~}』と組み合わせて使用することで、カテゴリー一覧ページじゃない場合かつカテゴリがセットされている場合といった条件分岐になります。
『get_the_category()』は、投稿にセットされているカテゴリすべてを配列で返します。$postcatに格納し、『$postcat[0]->name』でカテゴリの名前を一つだけ取り出します。
投稿日
PHP<?php echo get_the_date( 'Y-m-d' ); ?>
記事が投稿された日付を取得します。表示形式を変更したい場合は、管理画面の『設定』→『一般』→『日付のフォーマット』を変更するか、関数の引数に任意の日付のフォーマットを入力しましょう。
投稿のタイトル
PHP<?php the_title(); ?>
投稿のタイトルを出力します。
抜粋
PHP<?php the_excerpt(); ?>
投稿の抜粋欄に記述した内容を『<p>~</p>』で囲まれた一つの段落として出力します。※デモテーマでは出力しません。
記事一覧のデザインをCSSで反映する
『WordPressテーマ作成2』で作成したデザインをベースにCSSを整えていきましょう。
style.cssに記述
CSS.article-list { display: grid; gap: 2rem; grid-template-columns: repeat(2, 1fr); } .article-list .article-item { position: relative; z-index: 1; border: 1px solid #ddd; } .article-list .article-item a { display: block; text-decoration: none; color: #333; } .article-list .article-item img { display: block; width: 100%; aspect-ratio: 3/2; object-fit: cover; } .article-list .article-item .text-wrap { padding: 1rem; } .article-list .article-item .article-cat { font-size: .875rem; line-height: 1; display: inline-block; margin-right: .5rem; padding: .25rem .5rem; vertical-align: middle; text-decoration: none; color: #fff; background-color: #03162f; } .article-list .article-item .article-date { font-size: .875rem; display: inline-block; vertical-align: middle; color: #888; } .article-list .article-item .article-date i { font-size: 1rem; position: relative; top: .1875rem; margin-right: .125rem; } .article-list .article-item .text-wrap h2 { font-size: 1rem; font-weight: 500; margin-top: .5rem; } @media(max-width: 480px) { .article-list { display: block; gap: none; grid-template-columns: none; } .article-list .article-item { margin-bottom: 2rem; } }

デモのCSSをそのまま記述して表示すると、上の画像のようなデザインになります。
各記事は『display: grid』で横2列に並べます。また、サムネイル画像は様々なサイズでアップロードされることを想定し、CSSの『aspect-ratio: 横の比率/縦の比率;』を使用して画像のアスペクト比を固定しておきましょう。
display: gridを使用して要素を並べる
display: gridを使用すると、グリッドレイアウトで様々なレイアウトを構成することができますが、要素を横並びに規則的に繰り返す方法をご紹介します。
下記のようなhtmlがあるとします。
HTML<div class="item-wrap"> <div class="item">要素1</div> <div class="item">要素2</div> <div class="item">要素3</div> <div class="item">要素4</div> <div class="item">要素5</div> <div class="item">要素6</div> </div>
上記のhtmlの『.item』要素を横2列で並べたい場合は、display: gridを使用することで簡単に横2列にすることができます。
CSS.item-wrap { display: grid; gap: 3rem 2rem; grid-template-columns: repeat(3, 1fr); }
『.item』を囲む親要素に、上記の用にCSSを記述するだけで簡単に横並びレイアウトを作ることができます。

gap
各要素同士の余白を指定することができます。
CSS//値を一つ指定 gap: 縦横共通の余白; //値を2つ指定 gap: 縦の余白 横の余白;
grid-template-columns
要素を繰り返し配置する回数を指定できます。
CSSgrid-template-columns: repeat(繰り返しの回数, 1fr);
上記の繰り返しの回数の箇所を適宜書き換えることで、指定した回数横に要素が繰り返されます。
ページネーションを追加する
記事の一覧が出力できたら、最新の記事だけでなく全ての記事をユーザーが見ることができるように、ページネーション(ページ送り)を作成しましょう。
ページネーションの要素をindex.phpに追加する
メインループで記事を出力するときに使用するページネーションは、WordPressのデフォルトで用意されている関数を使用して出力します。
index.phpの.article-listの終了タグ</div>の後に記述
PHP<div class="pagination"> <?php echo paginate_links( array( 'type' => 'list', 'mid_size' => '1', 'prev_text' => '<i class="material-symbols-outlined">arrow_back_ios</i>', 'next_text' => '<i class="material-symbols-outlined">arrow_forward_ios</i>' ) ); ?> </div>
『paginate_links()』関数を使用することで、メインループに連動してページネーション要素を取得することができます。引数を調整することで取得形式を変更することもできるためデザインに合わせて取得しましょう。

上記のように、ページネーションの要素が出力されたら、きちんと動くか動作確認をしてください。
※記事の数が不足している場合は、ページネーションは出力されません。『設定 > 表示設定 > 1ページに表示する最大投稿数』で設定されている数より多い数の記事を追加しておきましょう。
ページネーションのCSSを追加する
『WordPressテーマ作成2』で作成したデザインをベースにCSSを整えてください。
style.cssに記述
CSS.pagination { margin: 4rem 0; text-align: center; } .pagination ul { font-size: 0; } .pagination ul li { font-size: 1rem; display: inline-block; margin-right: .75rem; } .pagination ul li:last-child { margin-right: 0; border: 0; } .pagination ul li a, .pagination ul li .current { font-weight: 600; line-height: 1; display: block; padding: .75rem .875rem; border: 1px solid #ddd; } .pagination ul li a { text-decoration: none; color: #555; } .pagination ul li .current { color: #fff; background-color: #1d2d43; } .pagination ul li .prev, .pagination ul li .next { padding: .75rem .5rem; border: 0; } .pagination ul li i { font-size: 1rem; color: #1d2d43; } @media (max-width: 480px) { .pagination { margin: 3rem 0; } .pagination ul li a { padding: .5rem; } }

デモのCSSをそのまま記述して表示すると、上の画像のようなデザインになります。
ページネーションは、出力される要素数が固定ではない(記事数が増えるとそれに合わせて増える)ため、『display: inline-block』を使って要素を横に並べています。
以上で、ページネーションの作成は完了です。
archive.phpを作成する
記事一覧の要素を追加したら、続いてarchive.phpを作成します。
テーマフォルダ内の『index.php』を複製し『archive.php』を追加してください。
index.phpのままでもきちんと動作はしますが、他のテンプレートを作るときのベースとして純粋な記事一覧を残しておくため、archive,phpに分岐しておくことをおすすめします。
archive.phpを作成したら、アーカイブページに要素を追加しましょう。
アーカイブのタイトルを追加する
アーカイブのタイトルの要素は、『WordPressテーマ作成3』のpage.php(固定ページ)作成時に追加した、タイトル要素を流用して作成します。
<div class=”wrapper”>の直下に追加
PHP<?php if(is_category() || is_tag()) { $cat = get_queried_object(); $archive_title = $cat->name.'の記事'; } elseif(is_year()) { $archive_title = get_the_time("Y年").'の記事'; } elseif(is_month()) { $archive_title = get_the_time("Y年n月").'の記事'; } elseif(is_day()) { $archive_title = get_the_time("Y年n月j日").'の記事'; } elseif(is_author()) { $author_id = get_query_var('author'); $author_name = get_the_author_meta('display_name', $author_id); $archive_title = $author_name.'が投稿した記事'; } else { $archive = '記事アーカイブ'; } ?> <div class="page-title-wrap"> <div class="page-title"> <div class="text-warp"> <h1><?php echo $archive_title ?></h1> </div> </div> </div>
「カテゴリ」「タグ」「日付」「ユーザー」等の各記事一覧に合わせたタイトルが出力されるように条件分岐を使用して、アーカイブタイトルをそれぞれ定義しておきましょう。

タイトル要素を追加したら、各ページでエラーが表示されずにきちんと意図した通りに出力されているかを確認しましょう。
エラーなくきちんとタイトルが表示されたら、アーカイブページの作成は完了です。
TOPページ(home.php)を編集する
記事一覧を構築したら、続いてTOPページを構築しましょう。TOPページは、独自でデザインされるかたも多いかと思います。その場合は、独自でhome.phpを編集し下記はスキップしてください。
TOPページの要素をhome.phpに追加する
home.phpにはファーストビュー画像とアーカイブページと同じように記事一覧を追加します。
<div class=”wrapper”>の直下に追加
PHP<div class="home-fv-wrap"> <img src="<?php echo get_template_directory_uri(); ?>/images/home-fv.jpg"> </div>
<div class=”contents”>の直下に追加
PHP<div class="home-article-list article-list"> <?php if(have_posts()): while(have_posts()): the_post(); get_template_part('loop-content'); endwhile; endif; ?> </div> <div class="pagination"> <?php echo paginate_links( array( 'type' => 'list', 'mid_size' => '1', 'prev_text' => '<i class="material-symbols-outlined">arrow_back_ios</i>', 'next_text' => '<i class="material-symbols-outlined">arrow_forward_ios</i>' ) ); ?> </div>
ファーストビュー画像は、テーマフォルダのimagesファイルに予めアップしておきましょう。
記事の一覧は、アーカイブページのCSSを流用しつつTOPページ独自のCSSも追加するために『class=”home-article-list article-list”』とTOPページ用のclassと既存のclassの2つを設置します。
TOPページのCSSを追加する
『WordPressテーマ作成2』で作成したデザインをベースにCSSを整えてください。
style.cssに記述
CSS.home-fv-wrap { margin-bottom: 2rem; } .home-fv-wrap img { display: block; width: 100%; height: min(31.25rem, 46.5vw); object-fit: cover; } @media(min-width: 1921px) { .home-fv-wrap img { height: auto; } } @media(min-width: 821px) { .home-article-list { grid-template-columns: repeat(3, 1fr); } }

デモのCSSをそのまま記述して表示すると、上の画像のようなデザインになります。
ファーストビューは、ブラウザ幅がメインコンテンツの幅である1080pxまでは画像の高さはそのままで左右がカットされてき、1080pxを下回った場合は1080pxのときのアスペクト比のまま小さくなっていくように、画像の高さを『min()』を使用して調整しています。また、逆にフルHD画質以上でサイトを見られた場合は、高さの固定を解除しておかないと画像の上下が切れてしまうため注意してください。
記事の一覧は、アーカイブページのサイドバーが横並びになっているブラウザ幅まで(821px)記事を横3列にし、それ以降のブラウザ幅になった場合は、アーカイブページと共通のレイアウトになるようにします。
サイズを比較して自動で適応する min(), max(), clamp()
CSSのmin()やmax()関数を使用することで、()内の数値を比較してサイズを指定するとこができます。
min()関数
min関数は、()内の引数の中で一番小さい値が反映されます。つまり最大値(max-width)を指定することができます。
CSS要素A { width: min(50%, 400px); }
のように指定すると、幅50%が400pxを下回るまでは、要素Aの幅は400pxで固定され下回ったら要素の値は50%で可変します。

max()関数
max関数は、()内の引数の中で一番大きい値が反映されます。つまり最小値(min-width)を指定することができます。
PHP要素A { width: max(50%, 400px); }
のように指定すると、幅50%が400pxを上回るまでは、要素Aの幅は400pxで固定され上回ったら要素の値は50%で可変します。

clamp()関数
max関数は、()内の引数の中で最小値(min-width)と最大値(max-width)を指定できます。
CSS要素A { width: clamp(200px, 50%, 500px); }
のように指定すると、幅50%が500pxを下回るまでは、要素Aの幅は500pxで固定され下回ったら要素の値は50%で可変します。更に、50%が200pxを下回ると要素の幅は200pxで固定されます。

テーマのスクリーンショットを追加する
TOPページの作成が完了したら、テーマ一覧で表示されるスクリーンショットを作成しましょう。
テーマのスクリーンショットとは、『外観 > テーマ』でテーマの一覧や詳細が表示される際に、テーマに合わせて表示される画像です。

特に設定しなくても機能的には問題ありませんが、ひと目見てどんなテーマかがすぐに判別できるようになるので設定しておきましょう。
スクリーンショット画像の作り方
スクリーンショットに使用する画像は、どんな画像でも問題ありません。サイトや作成者のロゴマークでも、TOPページのスクリーンショット画像でも大丈夫です。わかりやすく判別しやすい画像を設定しておきましょう。
画像に関しては特にどんな画像でも問題ないのですが、Wordpressスクリーンショット機能を使う場合は下記のルールに沿って作成する必要があります。
- ファイル名を「screenshot.png」にする
- 画像のアスペクト比は『4:3』で作成する(1200px×900px や 880px×660px)
上記2点だけを守って画像を準備してください。
スクリーンショット画像をテーマにアップする
スクリーンショット画像ができたら、Wordpressテーマにアップロードしましょう。アップする一は、スクリーンショットを設定したいテーマフォルダの直下です。
例:デモテーマの場合は、
『wp-content/themes/wp_theme/screenshot.png』
になります。

上記のように、テーマの一覧と詳細に作成したスクリーンショット画像を追加されれば、設置完了です。
以上で、WordPressテーマのアーカイブページの構築は完了です。次の記事では、検索エンジンやSNS拡散する際に、正確な情報を伝えるためのheadタグの中身の記述方法をご紹介します。
下記より記事で作成したところまでのテーマファイルを下記よりダウンロードできます。