FlatIsleロゴ

Flat Isle 日誌

WordPressテーマの作成(ベース編)

2022-08-09

当サイトはフリーのWordPressテーマを使っていましたが、Google AdSenseの審査過程で「ページの表示が遅くモバイルフレンドリーでは無い」と判定されました。
テンプレートとなるシンプルなテーマをベースとして自作し、必要な機能を追加しながらモバイルフレンドリーなテーマを作成する事で、Google AdSense審査に合格できました。
本記事ではベースとなるテーマの作成について記載します。

FSE対応テーマについて

ベースとなるシンプルなテーマを作成する手始めに、現在WordPress公式が推進しているFSE(フルサイトエディティング)対応テーマについて調査しました。
実際に試作した結果、レイアウトの細かな制御が出来なかったため、従来のクラシックテーマを採用しました。
メリット、デメリットを下記に挙げておきます。

😄FSE対応テーマの「メリット」

  • デザインが容易である
  • 色の統一等が行いやすい
  • 今後の主流になる(?)
  • プログラム初心者の方でもデザインができる

🙁FSE対応テーマの「デメリット」

  • 制限が多く、細かな制御ができない
  • 資料が少ない(FSE自体開発中のため)
  • マルチサイトで開発している場合、エクスポート機能が使えなかった(ver5.9当時)

クラシックテーマのファイル構成

WordPressは数種類の画面で構築されています。各画面の種類とテンプレートファイル(PHPコード)の対応図がこちらに纏められています。
上記リンク先の図よりソースコードの保守性と表示内容を考慮し、以下の構成で作成しました。
(今回「Site Front Page」は「Archive Page」をトップ画面として作成するため省略)

  • index.php
    トップ画面であり記事一覧や検索結果を表示するページ。
    次の機能を含む:「Archive Page」「Site Front Page」「Blog Posts Index Page」「Search Result Page」
  • singular.php
    単一の記事と固定ページの内容を表示するページ。
    次の機能を含む:「Single Post Page」「Static Page」
  • 404.php
    存在しないページへのアクセス時に表示されるページ。
    次の機能を含む:「Error 404 Page」

下図にフォルダとファイルの構成を記載します。(別記事で作成するオリジナルブロックも含めています)
「comments.php」は必須のファイルですが未使用のため、内容は空になっています。

📁(webroot) 📁wp-content 📁themes 📁(開発テーマ名) 📄style.css 📄editor.css 📄functions.php 📄index.php 📄singular.php 📄404.php 📄header.php 📄footer.php 📄sidebar.php 📄comments.php 📄entry-card.php 🎨screenshot.png 📁js 📄function.js 📁images (ロゴ画像等の保管用) 📁blocks 📄register_block.php 📁(オリジナルブロック)
フォルダ・ファイル構成

テーマの登録・初期設定

テーマの登録と初期設定を行います。

テーマの登録

WordPressにテーマを作成・登録するため、「style.css」に以下の項目を記述します。
なお、デザインに関する記述は別記事で解説します。

@charset "UTF-8";
/*
Theme Name:        テーマの名前(例:My theme)
Author:            作成者の名前
Description:       テーマの説明文
Version:           テーマのバージョン(例:1.0.0)
Requires at least: テーマが動くWordPressの最も古いバージョン(例:5.9)
Tested up to:      テーマをテストしたWordPressのバージョン(例:5.9)
Requires PHP:      テーマが動くPHPの最も古いバージョン(例:7.0)
License:           ライセンス(例:GNU General Public License v2 or later)
License URI:       ライセンスのURL(例:http://www.gnu.org/licenses/gpl-2.0.html)
Text Domain:       翻訳設定と紐付けるためのドメイン名(例:my-theme)
*/

WordPressダッシュボードの[外観]-[テーマ]より、上記で設定した名前のテーマが一覧にあるか確認します。
なお、この時にテーマのイメージ画像として「screenshot.png」が表示されます。

テーマの初期設定

テーマの初期設定や、機能は「functions.php」に記述する事により有効になります。
以下に作成した「functions.php」の全文を載せておきます。
後半にある「アイキャッチ画像の表示調整」「URLの取得(ショートコード)」については必須ではないため説明は省きます。
末尾にある「ブロックの登録」「目次の生成・表示」「パンくずリスト生成」については別記事で解説します。

<?php
if(!defined('ABSPATH')) exit;

// テーマ基本設定 /////////////////////////////////
if(!function_exists('custom_theme_setup')){
	function custom_theme_setup(){
		// ナビメニューの登録
		register_nav_menu('header-nav', 'ヘッダメニュー');
		// エディタのCSS対応
		add_theme_support('editor-styles');
		add_editor_style('editor.css');
		// サムネイル対応
		add_theme_support('post-thumbnails');
	}
}
add_action('after_setup_theme', 'custom_theme_setup');

// style.cssの読み込み
if(!function_exists('custom_theme_styles')){
	function custom_theme_styles(){
		wp_enqueue_style('style-name', get_template_directory_uri().'/style.css');
	}
}
add_action('wp_enqueue_scripts', 'custom_theme_styles' );

// アイキャッチ画像の表示調整 /////////////////////
if(!function_exists('thumbnail_control')){
	function thumbnail_control($html, $post_id, $post_thumbnail_id, $size, $attr){
		if(!has_post_thumbnail() || $html == ""){
			$html = "<img src=\"".get_template_directory_uri()."/images/flatisle_logo-150x150.png\" class=\"attachment-thumbnail size-thumbnail wp-post-image\" alt=\"\">";
			return $html;
		}
		$html = preg_replace('/(width|height)="\d*"\s/', '', $html);
		$html = preg_replace('/sizes=".*"/', 'sizes="(max-width: 800px) 150px, 300px"', $html);
		return $html;
	}
}
add_filter('post_thumbnail_html', 'thumbnail_control', 10, 5);

// URLの取得(ショートコード) ////////////////////
if(!function_exists('shortcode_url')){
	function shortcode_url() {
		return get_bloginfo('url');
	}
}
add_shortcode('url', 'shortcode_url');

// ブロックの登録 /////////////////////////////////
require get_template_directory()."/blocks/register_block.php";
// 目次の生成・表示 ///////////////////////////////
require get_template_directory()."/blocks/heading_index.php";
// パンくずリスト生成 /////////////////////////////
require get_template_directory()."/blocks/breadcrumb.php";

以降で記述するPHPファイルには、セキュリティ対策として下記コードを先頭に記述し、PHPのソースが見えないようにして下さい。

if(!defined('ABSPATH')) exit;

テーマの機能設定

テーマの初期設定のため、CSSファイルの読み込みやデフォルトではWordPressのダッシュボードに表示されない機能を有効にしていきます。

CSSの読み込み設定

公開ページ用のCSSファイル「style.css」及び、編集画面用CSSファイル「editor.css」の読み込み設定を行います。

「style.css」はwp_enqueue_style関数を使い、パラメータにハンドル名(ファイルを区別するための名前)、CSSファイルのURLを指定します。
なおテーマディレクトリのURLを取得するためget_template_directory_uri関数を使っています。
アクションフック[wp_enqueue_scripts]のタイミングで登録します。

if(!function_exists('custom_theme_styles')){
	function custom_theme_styles(){
		wp_enqueue_style('style-name', get_template_directory_uri().'/style.css');
	}
}
add_action('wp_enqueue_scripts', 'custom_theme_styles' );

「editor.css」はadd_theme_support関数で機能を有効化し、add_editor_style関数でCSSファイルを指定します。
アクションフック[after_setup_theme]のタイミングで登録します。

if(!function_exists('custom_theme_setup')){
	function custom_theme_setup(){
		// エディタのCSS対応
		add_theme_support('editor-styles');
		add_editor_style('editor.css');
	}
}
add_action('after_setup_theme', 'custom_theme_setup');
メニュー設定

デフォルトではWordPressダッシュボードにメニューバーの設定項目が表示されません。
register_nav_menu関数を使い、パラメータにメニュー位置の識別子、表示名を指定します。
アクションフック[after_setup_theme]のタイミングで登録します。

if(!function_exists('custom_theme_setup')){
	function custom_theme_setup(){
		// ナビメニューの登録
		register_nav_menu('header-nav', 'ヘッダメニュー');
	}
}
add_action('after_setup_theme', 'custom_theme_setup');
サムネイル設定

デフォルトでは記事の編集画面にサムネイル(アイキャッチ画像)の設定項目が表示されません。
add_theme_support関数を使って機能を有効化します。
アクションフック[after_setup_theme]のタイミングで登録します。

if(!function_exists('custom_theme_setup')){
	function custom_theme_setup(){
		// サムネイル対応
		add_theme_support('post-thumbnails');
	}
}
add_action('after_setup_theme', 'custom_theme_setup');

各ページの作成

ここからは上記「クラシックテーマのファイル構成」を基に各ページを構成するPHPファイルを記述していきます。

共通項目

フォントサイズや、各ページの見た目を統一するためのテンプレートパーツを設定します。

フォントサイズの設定

スマートフォン等の小さい画面(特にRetinaディスプレイ等の高解像度・高密度な画面)は、デバイスピクセル比が高いためブラウザの表示サイズが小さくなっています。そのため、文字サイズを少し小さくし、表示できる文字数を増やすようにします。
ここでは小さい画面の幅を500px以下とし、画面幅800pxまでの範囲で文字サイズを可変にしています。
下記は小さい画面幅を500px(文字サイズ14px)、大きい画面幅を800(500+300)px(文字サイズ16px)とする場合の計算式です。

<style type="text/css">
	html {
		font-size:	clamp(14px, calc(14px + 2 * (100vw - 500px) / 300), 16px);
	}
</style>

ヘッダ、フッタ等のパーツ設定

ヘッダやフッタ等をPHPファイルとしてパーツ化すると、使い回しが出来、またソースコードの保守性も向上します。このようなファイルをWordPressでは「テンプレートパーツ」と呼びます。今回は下記パーツを作成しました。

  • header.php
  • footer.php
  • sidebar.php
  • comments.php(未使用ですが必須ファイルのため作成)
  • entry-card.php(記事一覧や関連記事の表示枠として使用)

テンプレートパーツの呼び出しにはget_template_part関数を使います。パラメータはテンプレートパーツのスラッグ名(拡張子無しのPHPファイル名)です。

<?php get_template_part('header'); ?>

FSEでは、テンプレートパーツは「parts」フォルダに保存しています。
FSEと同様にフォルダ分けをすべきですが、従来のテーマではテンプレートパーツをテーマのルート直下に保存する必要があるため、今回はフォルダ分けを行っていません。
テンプレートパーツを呼び出す関数は色々ありますが、get_header、get_footer、get_sidebarはファイル(header.php、footer.php、sidebar.php)を表示します。見つからない場合WordPress標準テーマのパーツを表示します。
ですが、フォルダやファイル名を指定できないため今後を踏まえてget_template_part関数を使用しています。

index.phpの作成

トップ画面となるindex.phpを作成していきます。最新の記事一覧や検索結果、カテゴリやタグ別の記事一覧を表示するページとなります。

記事一覧の取得、表示

まず if文のhave_posts関数で記事の有無を確認します。記事があれば while文のhave_posts関数でループし、the_post関数で各記事を取得します。

<?php 
	if(have_posts()){
		while(have_posts()){
			the_post();
			// 記事一覧用テンプレートパーツ呼び出し等の処理
		}
	}
?>

ページネーション処理

記事一覧は長くなるため数記事毎にページを分割します。the_posts_pagination関数でページ番号や「次へ」等のページ送り機能を付け、ページ間の移動を容易にします。
パラメータは配列で、現ページ番号を中心に左右に表示する番号の数、前ページへのリンク文字列、次ページへのリンク文字列、読み上げ用文字列(下記の例では省略。初期値:Posts navigation)です。

<?php
	the_posts_pagination(
		array(
			'mid_size' => 2,
			'prev_text' => '⏪',
			'next_text' => '⏩',
		)
	);
?>

singular.phpの作成

記事本文や固定ページを表示するsingular.phpを作成していきます。記事の場合は末尾に関連記事一覧も表示させます。

SEO対策

SEO対策としてheadタグ内に下記を記述します。

  • 文字コード
  • ビューポート
  • タイトル
    the_title関数で記事タイトルを取得、使用しています。
  • メタディスクリプション
    記事の概要文です。ここではget_the_excerpt関数で記事の抜粋を取得、使用しています。
  • OGPタグ
    記事をSNSでシェアした時に表示される内容を設定します。
<head>
	<meta charset="utf-8">
	<meta name="viewport" content="width=device-width, initial-scale=1.0">
	<title><?php the_title(); ?></title>
	<meta name="description"        content="<?php echo get_the_excerpt(); ?>">
	<meta property="og:title"       content="<?php the_title(); ?>">
	<meta property="og:type"        content="article">
	<meta property="og:description" content="<?php echo get_the_excerpt(); ?>">
	<meta property="og:url"         content="<?php the_permalink(); ?>">
	<meta property="og:site_name"   content="<?php bloginfo('name'); ?>">
<?php	if(has_post_thumbnail()){ ?>
	<meta property="og:image"       content="<?php the_post_thumbnail(); ?>">
<?php	} else { ?>
	<meta property="og:image"       content="<?php echo get_theme_file_uri('/images/flatisle_logo.png'); ?>">
<?php	} ?>
	<meta property="twitter:card"   content="summary">

記事の取得、表示

have_posts関数で記事の有無を確認後、the_post関数で記事を取得します。
the_title関数で記事タイトルを表示、the_modified_date関数で記事の更新日を表示、the_content関数で記事の本文を表示させます。

<?php
	if(have_posts()){
		while(have_posts()){
			the_post();
?>
			<h1><?php the_title(); ?></h1>
			<div class="wp-block-modified-date"><?php the_modified_date('Y-m-d'); ?></div>
			<div class="wp-block-post-content">
				<?php the_content(); ?>
			</div>
<?php
		}
	}
?>

サムネイルの表示

上記 while文のループ内でサムネイルの処理を行います。
if文のhas_post_thumbnail関数でサムネイルの有無を判定し、the_post_thumbnail関数で表示させます。
the_post_thumbnail関数のパラメータは画像サイズのキーワード(thumbnail、medium、large、full)です。

<?php		if(has_post_thumbnail()){ ?>
				<figure class="wp-block-featured-image">
				<?php the_post_thumbnail('medium'); ?>
				</figure>
<?php		} ?>

関連記事の表示

サイトの回遊率を上げるため、ページの末尾に現在の記事内容に関連する記事を抽出して表示させます。
get_the_tags関数で現在の記事に付いているタグを取得し、同じタグを持つ記事の中から3つまでを「関連記事」として表示します。

<?php
	if(has_tag()){
		$tags   = get_the_tags();
		$aryId  = array();
		foreach($tags as $tag){
			$aryId[] = $tag->term_id;
		}
		$args = array(
			'post_type'     => 'post',
			'post__not_in'  => array($post->ID),
			'tag__in'       => $aryId,
			'orderby'       => 'modified',
			'posts_per_page'=> 3,
		);
		$data = new WP_Query($args);
		if($data->have_posts()){
			while($data->have_posts()){
				$data->the_post();
				// 記事一覧用テンプレートパーツ呼び出し等の処理
			}
		}
		wp_reset_postdata();
	}
?>

404.phpの作成

「404 記事が見つかりません」と表示するだけのシンプルな物にしましたが、SVG画像等で工夫すると面白そうです。

ここまでで、ベースとなるテーマが出来ました。
次回はCSSの詳細及びオリジナルブロック等、ブログ記事を作成しやすくする補助機能の作成について記述していきます。