【初心者向け】Wordpressテーマを自作する［singular.php］［single.php］［page.php］

ここでは、WPのテーマを作る上で必須の`singular.php`のコードを交えた解説を行います。
「あれ？`single.php`じゃないの？」と思った方、なぜ`single.php` ではなく`singular.php`なのかも含めて解説します。
とりあえずこの段階では「同じもの」と思っていただいて良いです。

:::note info
ファイルの構造や解説等、Wordpress（以下、WP）のテーマを自作する際の基本的な部分は、こちらの記事で紹介しています。
+ [【初心者向け】Wordpressテーマを自作する際に分かってると良いかもしれない事](
https://qiita.com/makkie/items/dc764c2845492079c0af)
+ `index.php`のコードを知りたいよって方はこちら
[【初心者向け】Wordpressテーマを自作する[index.php]](https://qiita.com/makkie/items/b5231a9f63b076c70af8)
+ `header.php`のコードを知りたいよって方はこちら
[【初心者向け】Wordpressテーマを自作する[header.php]](https://qiita.com/makkie/items/6d19ec0da990486ec6ab)
+ `footer.php`のコードを知りたいよって方はこちら
[【初心者向け】Wordpressテーマを自作する[footer.php]](https://qiita.com/makkie/items/65cd4be0e9c4ccbf7776)
:::
とりあえず解説はいいからコードだけ、の方は以下をどうぞ。
## コード（HTMLとPHP）
```diff_php
<?php /*
==========================================
Theme Name: Single + Page
==========================================
*/
get_header(); ?>
<div class="wrap">
    <main id="singular">
        <div class="breadcrumb-area">
            <?php output_breadcrumb(); ?>
        </div><!--//class="breadcrumb-area"-->
        <section class="content-area">
        <?php
        if(have_posts()) :
            while(have_posts()) : the_post();
        ?>
        <h2 class="sub-title"><?php the_title(); ?></h2>
        <div class="date-area">
            <span>Release</span><?php the_time('Y/m/d');?>
            <span>LastUp</span><?php the_modified_date('Y/m/d'); ?>
        </div><!--//class="date-area"-->
        <?php
        if(has_post_thumbnail()){
            echo '<figure class="thumb-img">' .get_the_post_thumbnail(). '</figure>' ;
        }
        ?>
        <div class="content-txt">
            <?php the_content();?>
        </div><!--//class="content-txt"-->
        </section><!--//class="content-area"-->
        <?php
            endwhile;
        endif;
        ?>
        </section><!--//class="content"-->
    </main>
    <?php get_sidebar(); ?>
</div><!--//class="wrap"-->
<?php
get_footer(); ?>
```
## 解説
### singular.phpとは
WPのテーマを自作する際の**必須ファイル**です。
とは言っても、`single.php`と`page.php`がある場合、`singular.php`は不要です。（それ必須とは言わない）

https://wpdocs.osdn.jp/%E3%83%86%E3%83%B3%E3%83%97%E3%83%AC%E3%83%BC%E3%83%88%E9%9A%8E%E5%B1%A4

WP4.3から実装され、`index.php`の次に読み込まれるテーマファイルで、個別ページ（single）と固定ページ（page）をこのファイルで兼用することができます。
デザインがシンプルで、個別ページと固定ページで条件分岐を細かく分ける必要がない場合はこれ一つだけで良いので、工数が減らせて良いかなと思います。
ただ、無理に`singular.php`にする必要はなく、「`single.php`と`page.php`がある方がいい」と言う方はそれでもいと思います。
私の場合は、出来るだけサーバの使用量を少なくしたいのと、メンテナンス性を重視して`singular.php`にしています。
そんな訳でコード内にある`Theme Name:`には`Single + Page`となっています。

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

https://qiita.com/makkie/items/dc764c2845492079c0af

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

### コードの説明
下記の部分は、自作の「パンくずリスト」を独自の関数で読み込んでいます。
```diff_php
<div class="breadcrumb-area">
    <?php output_breadcrumb(); ?>
</div><!--//class="breadcrumb-area"-->
```
コードはこちらで記事にしていますので参考にどうぞ。

https://qiita.com/makkie/items/c7597343e0d040ab08b0

#### Loopのはじまり
この部分は、`投稿（post）`があったら`loop`すると言う、`php`で動的にデータを取得して表示するために必須のコードで、ほぼすべてのテーマファイルで使われているので、「なんか知らんが必ず入れる」位でいいと思います。
```diff_php
<?php
if(have_posts()) :
    while(have_posts()) : the_post();
?>
```
:::note warn
テンプレートタグは、`loop`の中に置かないと動作しないものもあるので注意
:::

#### タイトル
この部分は記事のタイトルを取得して表示しています。
```diff_php
<h2 class="sub-title"><?php the_title(); ?></h2>
```

#### 公開日と更新日
この部分は、該当の投稿を公開した日を`the_time('Y/m/d')`で表示し、更新日を`the_modified_date('Y/m/d')`で表示しています。
内容によっては、固定ページではいらないので、このコード部分を`if( !is_page()) {`（固定ページじゃなかったら表示）もしくは`if(is_single()) {`で囲んでも良いかと思います。
```diff_php
<div class="date-area">
    <span>Release</span><?php the_time('Y/m/d');?>
    <span>LastUp</span><?php the_modified_date('Y/m/d'); ?>
</div><!--//class="date-area"-->
```
**▼固定ページじゃなかったら表示** 
```diff_php
<?php if( !is_page()) { ?>
<div class="date-area">
    <span>Release</span><?php the_time('Y/m/d');?>
    <span>LastUp</span><?php the_modified_date('Y/m/d'); ?>
</div><!--//class="date-area"-->
<?php } ?>
```
**▼個別ページだったら表示** 
```diff_php
<?php if(is_single()) { ?>
<div class="date-area">
    <span>Release</span><?php the_time('Y/m/d');?>
    <span>LastUp</span><?php the_modified_date('Y/m/d'); ?>
</div><!--//class="date-area"-->
<?php } ?>
```
公開日を表示する関数で`the_date()`もありますが、これは使いません。
以前は`the_date()`を使っていたのですが、複数の記事を同じ日に投稿した時に、それぞれの記事ごとに公開日を取得してくれないと言うことがあり使わなくなりました。Codexでも`同じ日に複数の記事がある場合は、最初の記事とともに一度だけ出力される。`と明記しているので仕様のようです。

https://wpdocs.osdn.jp/%E3%83%86%E3%83%B3%E3%83%97%E3%83%AC%E3%83%BC%E3%83%88%E3%82%BF%E3%82%B0/the_date

`the_date()`と似たようなので`get_the_date()`がありますが、`echo`を使って出力しなくてはならないのと、なんとなく`get`がついている関数は、 ***変数に値を入れる時に使うもの*** と私の中でルール化しているので、変数に公開日情報を入れる必要がある場合だけ使います。

https://wpdocs.osdn.jp/%E3%83%86%E3%83%B3%E3%83%97%E3%83%AC%E3%83%BC%E3%83%88%E3%82%BF%E3%82%B0/get_the_date

Wordpressのテンプレートタグは、似たような文言が多いのですが、使い方等かなり違うので、都度Codexで確認するのが良いと思います。

#### アイキャッチの表示

ここではアイキャッチを表示します。
`if(has_post_thumbnail())`としているのは`アイキャッチ画像があったら表示する`です。
```diff_php
<?php
if(has_post_thumbnail()){
    echo '<figure class="thumb-img">' .get_the_post_thumbnail(). '</figure>' ;
}
?>
```
ただ、これだと`アイキャッチ画像がない場合は何も表示されない`ので、
```diff_php
<?php
if(has_post_thumbnail()){
    echo '<figure class="thumb-img">' .get_the_post_thumbnail(). '</figure>' ;
} else {
    echo '<figure class="thumb-img"><img src="' .get_template_directory_uri(). '/images/noimages.png"></figure>';
}
?>
```
とした方がデザインが崩れずにいいかも。
別途、`images`フォルダに`noimages.png`と言う画像を用意するのを忘れずに。

#### 投稿内容の表示
`the_content()`で投稿画面で入力した内容が画像含め全部表示されます。
ただ文字の色や大きさを変える、画像へ文章を回り込ませたり、画像にキャプションを付けたりと言ったデザインの部分はここではコントロールできません。
`CSS`ファイルにWPの独自`class`を追加し、専用のスタイルでデザインを整えます。
これはまた別の機会に記事にできれば。
```diff_php
<div class="content-txt">
    <?php the_content();?>
</div><!--//class="content-txt"-->
```
#### Loopのおわり
これを書かないと`loop`が止まらないで延々と繰り返し処理をしてエラーになってしまうので忘れずに。
```diff_php
<?php
    endwhile;
endif;
?>
```

## まとめ
個別ページ（single）と固定ページ（page）は基本的に同じ様なことをやっているので、私は`singular.php`にまとめていますが、前述したように、`single.php`と`page.php`があった方が良いという方や、それぞれのページで条件分岐を色々したいという方は分けていいと思います。
コードはここに書かれているものをそれぞれのファイルにコピペしても正常に動作します。

他記事でも書いていますが、私は汎用性の高い、シンプルなファイル構成を目指しているので、兼用できる部分や少しの条件分岐を書くだけで済むのであれば、まとめてしまいたいです。
カスタム投稿を使い始めると、ついつい`taxonomy-***.php`と言うファイルを増やしがちになってしまうのですが、ファイルを増やす前に、条件分岐で何とかならないかな？と常に考えて手を動かす様にしています。

10年以上WPでWEBサイト制作をしていますが、独学のため、色々間違えている個所などありましたらご指摘いただけますと幸いです。