自作テンプレートを作っていて個別投稿ページを表示するためのテンプレートを作りたい。single.phpの書き方がいまいち分からない。

投稿用キャラクタ

今回はこういった疑問にお答えします。

この記事ではsingle.phpを作成する方法を解説していきます。ターゲットとしてはHTMLやCSSの書き方が分かる方でこれから初めて自作テンプレートを作ろうとしている初心者のかた向けに解説していきます。

single.phpを作成する方法

single.phpは投稿ページを表示するためのテンプレートです。作成方法をご紹介する前に簡単にテンプレートファイルが読み込まれる優先度を確認しておきましょう。

テンプレートが読み込まれる順番

投稿ページが読み込まれる際にテンプレートを読みに行く順番は以下の順番になります。

WordPressに呼ばれるテンプレートファイルの優先度

  • single-[post_type].php(高)
  • single.php
  • singular.php(4.3より追加)
  • index.php(低)

以上の順番になります。

single-[post_type].phpは投稿タイプによってテンプレートファイルを振り分けることができます。カスタム投稿タイプを使っている場合はこのテンプレートファイルでそれぞれのファイルを作成します。

singular.phpに関してはバージョン4.3から追加されているので割と新しいテンプレートファイルです。

簡単にsingular.phpを補足しておくとsingular.phpは投稿ページと固定ページそれぞれを共通で表示するためのテンプレートファイルです。投稿ページと固定ページを共通のテンプレートで運用する場合はこちらを作成しましょう!

single.phpのコード

コードに関しては僕が自作で作った今使っているテンプレートを簡略化して表示しています。

<?php get_header(); ?>
<div id="content_area" class="bg-main-color py-5">
	<div class="container-fluid">
		<div class="row no-gutters">
			<div class="col-12 col-md-12 col-xl-3 order-last order-xl-first">
			<?php get_sidebar("left"); ?>
			</div>
			<div class="col-12 col-md-8 col-xl-6 p-0 px-md-2 mb-4 single-page">
				<div class="mx-xl-3 mr-sm-3 bg-white box-shadow-only">
					<main>
					<?php if(have_posts()): while(have_posts()):the_post(); ?>
					<div class="post-header p-4">
						<div class="d-flex justify-content-between">
							<span class="category-box px-2 py-1 main-color d-inline-block text-white"><?php the_category(', '); ?></span>
						</div>
						<h1 class="h2 my-3"><?php the_title(); ?></h1>
						<div class="time-box text-right">
							<i class="fas fa-history"></i>
							<time datetime="<?php the_time('Y-m-d'); ?>"><?php the_time('Y年m月d日'); ?></time>
						</div>
					</div>
					<?php if (has_post_thumbnail()) : ?>
						<?php the_post_thumbnail('full', array('class' => 'img-fluid w-100')); ?>
					<?php else : ?>
						<img class="img-fluid w-100" src="<?php bloginfo('template_url'); ?>/img/ec-wordpress.png" alt="デフォルト画像">
					<?php endif ; ?>
					<div class="post-content px-4 pb-4"><?php the_content(); ?></div>
					<?php endwhile; endif; ?>
					</main>
					<section>
						<div class="d-flex mb-3 justify-content-between p-3">
						<?php previous_post_link('%link','古い記事へ'); ?>
						<?php next_post_link('%link','新しい記事へ'); ?>
						</div>
					</section>
				</div>
			</div>
			<div class="col-12 col-md-4 col-xl-3 mb-4 mb-md-0">
			<?php get_sidebar("right"); ?>
			</div>
		</div>
	</div>
</div>
<?php get_footer(); ?>

それでは簡単に解説をしていきます。bootstrapを使っている為クラスやdivが多かったりしますので不要な方は削除して自分用にカスタマイズしちゃってください!

1行目のget_headerでheader.phpを呼び出しています。

<?php get_header(); ?>

6行目、39行目はsidebar.phpを呼び出しています。2カラム(2列のレイアウト)の場合、記述は一回で大丈夫です。またget_sidebarのかっこ内のパラメーターも不要です。

<?php get_sidebar(); ?>

11行目から28行目がメインループの記述になります。ここに投稿を表示するための記述をしていきます。

<?php if(have_posts()): while(have_posts()):the_post(); ?>
ループの内容を記述
<?php endwhile; endif; ?>

16行目でthe_titleを使ってタイトルを出力しています。

<?php the_title(); ?>

19行目で投稿された時間を出力しています。

<?php the_time('Y年m月d日'); ?>

23行目から27行目はアイキャッチ画像を出力するコードです。投稿記事にアイキャッチが登録されている場合は24行目のコードで登録画像を表示します。投稿にアイキャッチ画像がない場合は26行目のコードで指定している画像を表示しています。

<?php if (has_post_thumbnail()) : ?>
	<?php the_post_thumbnail('full', array('class' => 'img-fluid w-100')); ?>
<?php else : ?>
	<img class="img-fluid w-100" src="<?php bloginfo('template_url'); ?>/img/ec-wordpress.png" alt="デフォルト画像">
<?php endif ; ?>

26行目に関してこのまま使うと/img/ec-wordpress.pngという画像を読みにいってしまうのでパラメーターを自分の画像を置いてあるフォルダとファイル名に書き換えてください。

27行目のthe_contentで投稿画面に入力された内容を出力します。

<?php the_content(); ?>

32行目、33行目のタグに関してはprevious_post_linkが1つ前の記事、next_post_linkが1つ後の記事のリンクをそれぞれ取得しています。第二パラメーターでリンクの文字を指定します。

<?php previous_post_link('%link','古い記事へ'); ?>
<?php next_post_link('%link','新しい記事へ'); ?>

45行目のget_footerでfooter.phpを呼び出しています。

<?php get_footer(); ?>

作る時間を短縮するなら

HTMLの骨組みだけ欲しいと言う方にはブランクテーマと呼ばれる骨組みのみのテーマがあります。bonesと言う無料のテーマがあるのでテンプレート制作を時短したい方はこちらをチェックしてみてください。

WordPressでテーマを作るなら「bones」がおすすめ

WordPressでテーマを作るなら「bones」がおすすめ

まとめ

WordPressのsingle.phpを自作する方法をご紹介しました。初めてのテンプレート制作はなかなか難しいと思いますので不明点などあればTwitterお問い合わせからご連絡いただければ自分の分かる範囲でしたらお答えしますのでお気軽にご連絡ください!