2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

【初心者向け】Wordpressテーマを自作する[archive.php][category.php][taxonomy.php]

Posted at

ここでは、WPのテーマを作る上で必須のarchive.phpのコードを交えた解説を行います。
タイトルにはcategory.phpとも入れていますが、現時点ではどちらも同じものと考えていただいていいです。
基本的な考え方は他ページとあまり変わりませんが、archive.phpだからこそ注意したいことなどありますので、最後まで読んでいただけると幸いです。

ファイルの構造や解説等、Wordpress(以下、WP)のテーマを自作する際の基本的な部分は、こちらの記事で紹介しています。

とりあえず解説はいいからコードだけ、の方は以下をどうぞ。

コード(HTMLとPHP)

<?php /*
==========================================
Theme Name: Archive + Category
==========================================
*/
get_header(); ?>
<div class="wrap">
<main id="archive">
<div class="breadcrumb-area">
    <?php output_breadcrumb(); ?>
</div><!--//class="breadcrumb-area"-->
<?php
//先頭辞を非表示
add_filter( 'get_the_archive_title_prefix', function($prefix) {
    $prefix = ''; //空文字代入
    return $prefix;
});
$archtitle = get_the_archive_title();
echo '<h1 class="en-txt under-line">' .$archtitle. '</h1>';
?>
<?php
	if(have_posts()) :
?>
    <div class="archive-frame">
<?php
		while (have_posts()) : the_post();
?>
    <section class="archive-box">
	<a href="<?php the_permalink(); ?>">
		<?php
		if(has_post_thumbnail()){
			echo '<figure class="thumb-img4">' .get_the_post_thumbnail(). '</figure>';
		} else {
			echo '<figure class="thumb-img4"><img src="' .get_template_directory_uri(). '/images/noimages.png"></figure>';
		}
		?>
		<h4><?php the_title(); ?><span class="moddate en-txt"><?php the_modified_date('Y/m/d') ?></span></h4>
        <?php
        //本文を文字数制限表示
        if(mb_strlen($post->post_content,'UTF-8')>50){
            $content= str_replace('\n', '', mb_substr(strip_tags($post-> post_content), 0, 50,'UTF-8'));
            echo '<div class="txt-box">' .$content.'……'. '</div>';
        }else{
            echo '<div class="txt-box">' .str_replace('\n', '', strip_tags($post->post_content)). '</div>';
        }
         ?>
	</a>
	</section><!--//class="archive-box"-->
<?php
		endwhile;
?>
    </div><!--//class="archive-frame"-->
    <?php
    //ページネーション
    the_posts_pagination(array(
        'prev_text' => 'PREV',
        'next_text' => 'NEXT'
    ));
    ?>
<?php
	endif;
?>
</main>
<?php get_sidebar(); ?>
    </div><!--// class="wrap"-->
<?php
get_footer(); ?>

そもそも「アーカイブ」(Archive)ってなに?

「アーカイブ」と検索すると「データをまとめて保存しておくこと」とあります。
WPでは、「アーカイブ」と言うと「記事一覧」のことを指します。

例えば、企業サイトでよくある、新着情報等を一覧で表示したり、特定のカテゴリを一覧表示する時に「アーカイブ」と言います。

解説

archive.phpとは

WPのテーマを自作する際の必須ファイルです。
カテゴリ毎category.php タクソノミー毎taxonomy.php ユーザー毎author.php、日付毎date.php、タグ毎date.phpのアーカイブ表示がある場合、archive.phpは不要です。
と言う事は、上記ファイルは全部archive.phpで兼用できると言う事になります。
必須テンプレートは公式Codexにも掲載されていますので確認してください。

別記事でも書いていますが、私はテーマファイルは最小構成にしたいと考えており、デザインがシンプルであるなら、兼用できるものは兼用してしまおう、数行の条件分岐で済むなら1ファイルにまとめてしまおうと考えています。
ですので、タイトルにはarchive.php category.php taxonomy.phpと3種類のテンプレート名を入れています。この3つは上述したことを踏まえた上で、archive.phpに集約することができます。

以前私が書いた記事ではシンプルで最小のファイル構成を書いています。参考にどうぞ。

ただ、「集約する」ことが必ずしもいいことではない場合もありますので、状況に合わせてファイルは分けて使うようにしてください。
特にカスタム投稿は、カスタム投稿タイプアーカイブ カスタムタクソノミーアーカイブとあるため、初見は分かりにくいです。
WPの良い所は、表示したいアーカイブ専用のテンプレートを用意すれば、コードの間違えやファイル名の付け方を間違えなければ、簡単に表示されることだと思っているので、どの条件どのテンプレートが表示されるのかを理解して活用していただければと思います。

必須なコード

ヘッダーを読み込むget_header();、フッターを読み込むget_footer();loop<?php if(have_posts()) : while(have_posts()) : the_post(); ?>がないと始まらないですね。
<?php endwhile; endif; ?>loopを終わらせるのも忘れずに。

既に【初心者向け】Wordpressテーマを自作する[singular.php][single.php][page.php]をご覧になっている方は、最初に記載しているコードのloopの位置が違う事に気づかれたと思います。
以下では、それも含めて細かくコードの解説をします。

コードの説明

下記の部分は、プラグインなしの自作「パンくずリスト」を独自の関数で読み込んでいます。

<div class="breadcrumb-area">
    <?php output_breadcrumb(); ?>
</div><!--//class="breadcrumb-area"-->

プラグインだと、更新されないとセキュリティホールになったり、余計な機能が付いていてサーバの容量を圧迫したり、自分の思った挙動にならなかったりと面倒なことが起きがちですが、自分で書いたシンプルなコードであれば、テーマファイルを読み込んだタイミングで有効化され、カスタマイズも簡単にできます。

コードはこちらで記事にしていますので参考にどうぞ。

Loopを始める前に

WPのテンプレートと言えば「とにかく何を置いてもloopを書く」だと思うのですが、アーカイブのタイトルは記事名ではなく、カテゴリ名やタクソノミー名なので、それらを取得し表示します。

<?php
//先頭辞を非表示
add_filter( 'get_the_archive_title_prefix', function($prefix) {
    $prefix = ''; //空文字代入
    return $prefix;
});
$archtitle = get_the_archive_title();
echo '<h1 class="en-txt under-line">' .$archtitle. '</h1>';
?>

本来アーカイブで表示するタイトルはthe_archive_title();という関数で表示しますが、この関数で表示すると名称の先頭に「 カテゴリー:」や「 タグ: 」と言う文言が自動で付与されます。
閲覧する方々には、カテゴリーとタグを区別する必要性はないかなという事で私はadd_filterを使って表示しないようにしています。

add_filter( 'get_the_archive_title_prefix', function($prefix) {
    $prefix = ''; //空文字代入
    return $prefix;
});

で先頭辞を非表示にし、

$archtitle = get_the_archive_title();
echo '<h1 class="en-txt under-line">' .$archtitle. '</h1>';

add_filterで先頭辞を非表示にしたタイトルを変数$archtitleに入れて、echoで表示します。
アーカイブページのタイトルなのでh1タグで囲んでいます。
ここでは変数に入れていますが、変数に入れずに

echo '<h1 class="en-txt under-line">' .get_the_archive_title(). '</h1>';

としても先頭辞なしで表示されます。

Codexにもある様に、 get_the_archive_title();は、タクソノミーやタームのアーカイブでもタイトルを取得できるので、もしテンプレートをtaxonomy.phpとして分ける場合でもそのまま使えます。

Loopのはじまり

Loopのはじまりと言えば、

<?php
if(have_posts()) :
    while(have_posts()) : the_post();
?>

ですが、archive.phpだとちょっと違う書き方をします。

<?php
	if(have_posts()) :
?>
    <div class="archive-frame">
<?php
		while (have_posts()) : the_post();
?>

if(have_posts()) :while (have_posts()) : the_post();の間にdivが入っています。
<div class="archive-frame">は、アーカイブページで表示する記事の大枠です。
私はdisplay: flex;(横並び)を使う際に使うことがほとんどです。
下図でいう所の赤枠の部分が<div class="archive-frame">です。
Qiita_archive.jpg
ざっくりとした感じでいうとif(have_posts()) :記事があるかを確認する、while (have_posts()) : the_post();記事があったら繰り返し表示するというコードです。
初めてアーカイブページを作るという方良くやりがちなのが、page.phpsingle.phpの様に

<?php
if(have_posts()) :
    while(have_posts()) : the_post();
?>
    <div class="archive-frame">

while (have_posts()) : the_post();の下にdivを書いてしまう事です。
そうすると、<div class="archive-frame">は大枠なのに、while (have_posts()) : the_post();の下にあるので、繰り返し処理の対象となり繰り返し表示されてしまいます。
繰り返し処理をするのは、下図でいう所の青枠の部分、コードでいうと

    <section class="archive-box">
        ......
	</section><!--//class="archive-box"-->

の部分ですので、if(have_posts()) :記事がある時に表示の下に<div class="archive-frame">を入れて、while (have_posts()) : the_post();と繰り返し処理をします。
もし投稿があったら = if(have_posts()) : ここにある投稿を繰り返し処理 = (have_posts()) : the_post();と覚えると書き間違いが防げるかと思います。

記事の表示

アーカイブのページでは、アイキャッチと記事のタイトル、本文の一部を表示して、どこをクリックしても該当記事のページへジャンプする様にリンクを付与します。
アイキャッチの他に記事の中の画像をアイキャッチとして表示する方法もありますが、アイキャッチ画像が設定されていない場合に「NoImages」とアイキャッチがないよと画像表示したことで、お客様側が「見た目が良くない」とチェックして設定するようになったので、当該機能を実装するよりも、if(has_post_thumbnail())else で「NoImages」と書かれた画像を表示する様にした方が、私の経験上よかったです。
まず、 記事中に画像を必ず入れる と言う事がルール化されていないと結局「NoImages」を表示しなければならず、条件分岐が増えるだけなので...。

    <section class="archive-box">
	<a href="<?php the_permalink(); ?>">
		<?php
		if(has_post_thumbnail()){
			echo '<figure class="thumb-img4">' .get_the_post_thumbnail(). '</figure>';
		} else {
			echo '<figure class="thumb-img4"><img src="' .get_template_directory_uri(). '/images/noimages.png"></figure>';
		}
		?>
		<h4><?php the_title(); ?><span class="moddate en-txt"><?php the_modified_date('Y/m/d'); ?></span></h4>
        <?php
        //本文を文字数制限表示
        if(mb_strlen($post->post_content,'UTF-8')>50){
            $content = str_replace('\n', '', mb_substr(strip_tags($post-> post_content), 0, 50,'UTF-8'));
            echo '<div class="txt-box">' .$content.'……'. '</div>';
        }else{
            echo '<div class="txt-box">' .str_replace('\n', '', strip_tags($post->post_content)). '</div>';
        }
         ?>
	</a>
	</section><!--//class="archive-box"-->

the_modified_date('Y/m/d')更新日なので、公開日を表示したい場合はthe_time('Y/m/d')としてください。
the_date()は別記事でも書いていますが、Codexにある様に同じ日に複数の記事がある場合、最初の記事の公開日しか取得しないという挙動をするので、アーカイブページで使うと悲しいことになりますので、必ずthe_time('Y/m/d')としてください。

アーカイブでは、複数の記事を高さや横幅など揃えて並べて表示したいので、本文は文字数を指定して、一部だけ表示する様にしています。

if(mb_strlen($post->post_content,'UTF-8')>50){

50文字を超える場合、一部だけ表示する様に条件分岐しています。
「50文字」は半角(1バイト文字)での文字数なので、ざっくり日本語は25文字くらいです。

mb_substr(strip_tags($post-> post_content)でHTMLタグを削除し、str_replaceで半角スペースを'\n'置換し''で削除しています。
特定のタグ(例は<span><br>)を残したい場合は、mb_substr(strip_tags($post-> post_content)mb_substr(strip_tags($post-> post_content, '<span><br>')と追加します。
$content変数に入れて、echoで表示しますが、文末には続きがある事が分かる様に'……'を入れています。
Moreを入れてもいいですね。
else(50文字以下)では、HTMLタグと半角スペースを削除して全文表示する様にしています。

Loopの終わり

endwhile;endif;は忘れずに、必ず最後に書いてください。
さらにアーカイブページはページネーションと言われる、ページ番号を表示する関数も忘れずに入れましょう。

<?php
		endwhile;
?>
    </div><!--//class="archive-frame"-->
    <?php
    //ページネーション
    the_posts_pagination(array(
        'prev_text' => 'PREV',
        'next_text' => 'NEXT'
    ));
    ?>
<?php
	endif;
?>
'prev_text' => 'PREV',
'next_text' => 'NEXT'

の部分は好きな文言を入れることができます。
以前は、プラグインや自作でごにょごにょやってやっと表示できていたページネーションも、現在(WP4.1.0から実装)はこの関数だけで簡単に実装できるようになりました。

上記コードを実装すると以下の様なコードが出力されるので、それに合わせてCSSを適用してください。

<nav class="navigation pagination" area-label="投稿">
<h2 class="screen-reader-text">投稿ナビゲーション</h2>
    <div class="nav-links">
        <span area-current="page" class="page-numbers current">1</span>
        <a class="page-numbers" href="******">2</a>
        <a class="next page-numbers" href="*****">NEXT</a>
    </div>
</nav>

まとめ

前述した様に、archive.phpcategory.php taxonomy.phpを兼用できるファイルなので、それに書くコードもできるだけ幅を持たせたコードを書くようにしていますので、もしcategory.php taxonomy.phpと別ファイルにする場合でも、そのままコードが使えるようにしています。
loopの部分さえ気を付けて条件分岐を使い分けられれば、それほど難しくもないかと思います。

ファイルもコードもシンプルに、あとで自分が見ても、他人が見ても何をしているのか分かる様にを頭に置いて、日々コーディングしています。
10年以上WPでWEBサイト制作をしていますが、独学のため、色々間違えている個所などありましたらご指摘いただけますと幸いです。

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?