自分でWPのテーマを作成する方法について。
まずは、ローカル環境にオリジナルのテーマを作成する。ローカル環境でのWP構築にはDockerを使用。
詳しくは、Dockerを使って自分のPC上にWordPressの環境を簡単に構築する方法を参照。
docker-compose up -d でDocker上でWPを起動したら、WPにアクセスしてテーマを作成する。例としてmy-themeというサイトを作成。

ディレクトリを見てみると、プロジェクトディレクトリにWPのファイル一式が作成されている。

テーマの作成場所
テーマを作成するディレクトリは、html > wp-content > themes の中になる。デフォルトでWordpressのデフォルトテーマがインストールされている。

ここに新しいテーマのためのディレクトリを作成する。ここでは my-theme というディレクトリを作成。

この状態でWordpress管理画面から 外観 > テーマ を確認すると新たに「壊れているテーマ」が追加されている。

必須ファイルの作成とテーマの有効化
テーマが壊れている理由はWordpressでテーマを作成するために必須の2つのファイルがないため。
- index.php
- style.css
先程作成したテーマディレクトリの中に2つのファイルを作成する。この時点では中身は空でも問題ない。

再度、Wordpressの管理画面でテーマを確認すると、新たなテーマが見れるようになっている。

早速、追加したテーマを有効化する。

テーマ名の変更
テーマ名は style.css を編集することで自由に設定することができる。以下を追記し、Them Name: の後ろに好きな名前を設定する。
@charset "UTF-8";
/*
Theme Name: my-original-theme
*/

日本語名もつけることができる。

作成するページとファイルの作成
WordPressにはテンプレートという概念があり、ページの種別によって読み込むファイルが決まっている。このため、目的に合わせてファイル名を選択する必要がある。
読み込み順序に優先順位があるので注意が必要。
▼主なテンプレートファイル
優先度1 | 優先度2 | 優先度3 | |
トップページ | front-page.php | home.php | ◎index.php |
*ヘッダー | header.php | ||
*フッター | footer.php | ||
*サイドバー | sidebar.php | ||
固定ページ | {custom-name}.php | page-{slug}.php | page.php |
記事ページ | single-{post-type}.php | single.php | singular.php |
一覧ページ | archive-{post-type}.php | archive.php | |
カテゴリーページ | category-{slug}.php | category.php | archive.php |
タグページ | tag-{slug}.php | tag.php | archive.php |
404ページ | 404.php | ||
スタイルシート | {custom-name}-style.css | rtl.css | ◎style.css |
例えば、トップページを指定するファイル名は front-page.php、home.php、index.php の3つがあり、それぞれ存在してる場合優先度はfront-page.php > home.php > index.phpとなる。
なお、固定ページを指定する場合front-page.phpが必須。
新着情報やブログの新着情報など、DBに保存された記事を順に表示するためには、archives.phpを使う。
TOP意外の静的なページを表示するには、page.phpを使う。
なお、上記表で{ }で囲んだ部分は任意の値が入る。例えば、page-{slug}.phpとして、page-food.phpがある場合は、page-food.php > page.php となる。
*がついている、header.php、 footer.php、 sidebar.phpはテンプレートの構成要素。
また、テンプレートではないが、関数を記述するファイルとして function.php がある。
今回、(1)Home、(2)Menu、(3)News、(4)Blog、(5)Shop、(6)Contactの6つのページを作成する。それぞれの階層構造とテンプレートは以下のようになる。

必要なファイルを一式作成する。

WordPressの管理画面で 外観 > テーマエディタ を選択すると作成したファイルが読み込まれる。

固定ページの作成
まずは、固定ページを作成する。Wordpressの管理画面で 固定ページ > 新規追加 を選択し、(2)Menu、(5)Shop、(6)Contactの3つのページを作成する。
先に、URLを任意に設定できるようにするために、設定 > パーマリンク設定 > 投稿名 を選択しておく。

固定ページの新規追加で、ページのタイトルを入力する。自動的に右カラムのURLスラッグに入力した内容の小文字が反映される。これを確認したら「公開」をクリック。

この作業と同様にContactとShopページも作成。サンプルページはいらないので削除。

共通パーツの挿入方法
Homeページを作成する前に、header.php, footer.php, sidebar.phpなどテンプレート内で呼び出す共通パーツについて理解する。これらを呼び出すときは専用の記述(インクルートタグという)を使う。
インクルードタグはphpであることを示すタグ<?php ?> と get_hader() などの関数の組み合わせ。
項目 | インクルードタグ |
header.phpを読み込む | <?php get_header(); ?> |
footer.phpを読み込む | <?php get_footer(); ?> |
sidebar.phpを読み込む | <?php get_sidebar(); ?> |
searchform.phpを読み込む | <?php get_search_form(); ?> |
comments.phpを読み込む | <?php comments_template(); ?> |
header.phpやfooter.php、sidebar.phpはファイルの優先順位に従い、header-{name}.phpなどがある場合はそちらのファイルを優先する。
引数にファイル名(拡張子を除く)を入れれば、指定したファイルを読み込むことができる。
例: header-main.phpを読み込みたい場合
<? php get_header('header-main'); ?>
トップページの作成と表示
WordPressの挙動を確認するため、まずは簡単にトップページを作成しブラウザ上で表示してみる。
現在の状態トップページを表示すると何も表示されない。

トップページを表示するために必要なファイルは以下3つ。
- header.php
- footer.php
- front-page.php
例として、超シンプルに作成する。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<footer>
<div>my-themeサイト</div>
</footer>
</body>
</html>
以上で、headerとfooterが完成。次に実際に画面に表示するfront-page.phpを編集する。
<?php get_header(); ?>
<div>本文</div>
<?php get_footer(); ?>
インラインタグで作成したheaderとfooterを読み込んでいる。
この状態でページをリロードすれば、記述した内容がブラウザに表示される。

ブラウザ上のページのソースコードは以下のようになっている。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<div>本文</div>
<footer>
<div>my-themeサイト</div>
</footer>
</body>
</html>
WordPressの機能を使えるようにする(プラグイン API フック)
上記で作成したページではWordpressの機能を使うことができない。Wordpressの機能を有効化するために、プラグイン API フックというタグを挿入する必要がある。
APIフック | 記述場所 | 内容 |
wp_head() | header.phpのheadタグ内に記述 | WPに必要なスタイルシートのリンクやJavaScriptなどを挿入する。 |
wp_footer() | footer.phpの/bodyタグ直前に記述 | 最後に実行するコードを挿入する。Google Analytics などのアクセス解析コードの挿入に使われることが多い。 |
wp_meta()/en | sidebar.phpのmetaタグ内に記述することが多い | 広告スイッチャーやタグクラウドなどを表示する。 |
comment_form() | comments.phpの終了タグ/div直前に記述 | コメントプレビューを表示させる。 |
(参考)wp_head()とwp_footer()で読み込まれる内容、およびAPIフックの詳細
特に、wp_head()とwp_footer()は必須。これを記述した、header.phpとfooter.phpは以下のようになる。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<?php wp_head() ?>
</head>
<body>
<footer>
<div>my-themeサイト</div>
</footer>
<?php wp_footer() ?>
</body>
</html>
トップページに投稿一覧を表示する
トップページに投稿一覧を表示する機能を追加する。front-page.phpファイルがある場合は、自動的にそのファイルが読み込まれるため、コードを記述する。
例えば以下のようなコードになる。
<?php get_header(); ?>
<div>
<section>
<div class="headline">
新着投稿の一覧ページ
</div>
<ul class="blogs-wrapper">
<?php if ( have_posts() ) : while ( have_posts() ) : the_post(); ?>
<li class="blog-wrapper">
<a href="<?php the_permalink(); ?>">
<div>
<?php if(has_post_thumbnail()): ?>
<?php the_post_thumbnail('medium', array('class'=>'blog-img')); ?>
<?php else : ?>}
<img class="blog-img" src="<?php bloginfo('template_url') ?>/images/nophoto.jpg" alt="">
<?php endif; ?>
</div>
<div>
<div class="blog-title"><?php the_title(); ?></div>
<div class="blog-lead"><?php the_excerpt(); ?></div>
</div>
</a>
</li>
<?php endwhile; ?>
</ul>
<?php endif; ?>
</section>
</div>
<?php get_footer(); ?>
have_posts()やthe_post()などWordpress独自の関数の意味については【WordPress】投稿一覧ページの作り方。have_posts()やthe_post()とは?意味と使い方を参照。
この状態でブラウザを確認すると、以下のように冒頭divタグの中の文字のみが表示される。ここに表示する投稿を作成する。

アイキャッチ画像項目の有効化
デフォルトではアイキャッチ画像項目がないので、functions.phpに以下を追記する。
<?php
function custom_theme_setup() {
add_theme_support( 'post-thumbnails' );
}
add_action( 'after_setup_theme', 'custom_theme_setup' );
これで、投稿の右カラムにアイキャッチ画像の項目が表示されるようになる。

投稿の作成
投稿を適当に5個ほど作成する。

この状態で、再度、ブラウザでトップページをリロードする。以下のように投稿一覧が表示されればOK。
※注意点:phpインクルードタグにスペルミスがあると読み込みが途中で止まる。

コードで記述したとおり、the_post_thumbnail(‘medium’)、the_title()、the_excerpt()が表示されている。
スタイルの調整
スタイルシートは便利なscssを使う。コンパイルするためにプラグイン SCSS-Libraryを有効化する。

使い方は有効化し、普通のcssファイル同様にwp_enqueue_styleで、scssファイルを読み込むだけ。(簡単便利)
スタイルシートの読み込み設定
front-page.php専用のスタイルシート、front-style.scssを作成しfunction.phpで読み込む。
html > wp-content > themes > テーマ名 > front-style.scss

function addtional_styles() {
if( is_front_page() ){
wp_enqueue_style( 'front-css', get_template_directory_uri() . '/front-style.scss' );
}
}
add_action( 'wp_enqueue_scripts', 'addtional_styles' );
スタイルを個別ページにのみ追加するコードの詳細はWordPressで特定のページにのみcssを適用する方法を参照
スタイルの調整
適宜スタイルを調整。
.headline{
margin: 30px auto;
font-weight: bold;
font-size: 30px;
text-align: center;
max-width: 1000px;
}
.blogs-wrapper{
margin: 0 auto;
list-style: none;
display: flex;
max-width: 1000px;
flex-wrap: wrap;
}
.blog{
&-wrapper{
display: flex;
flex-direction: column;
text-align: center;
width: 250px;
margin: 20px;
}
&-img{
max-width: 100%;
height: 170px;
}
&-title{
font-size: 18px;
font-weight: bold;
}
}
a{
text-decoration: none;
}
a:link, a:visited, a:hover, a:active {
color: #333;
}
ブラウザで表示を確認
トップページをリロードし、スタイルが反映されることを確認。

いい感じのレスポンシブになりました。
投稿個別ページのレイアウト調整
各投稿のリンク先である個別ページのレイアウトは signle.php で調整する。
html > wp-content > themes > テーマ名 > single.php
例えば、以下のようなコードを設置。
<?php get_header(); ?>
<main class="container">
<time class="blog-date" datetime="<?php the_time('Y-m-d'); ?>" >
<?php the_time('Y年m月d日'); ?>
</time>
<?php if ( have_posts() ) : while ( have_posts() ) : the_post(); ?>
<div>
<?php if(has_post_thumbnail()): ?>
<?php the_post_thumbnail('medium', array('class'=>'blog-img')); ?>
<?php else : ?>}
<img class="blog-img" src="<?php bloginfo('template_url') ?>/images/nophoto.jpg" alt="">
<?php endif; ?>
</div>
<div>
<div class="blog-title"><?php the_title(); ?></div>
<div class="blog-lead"><?php the_excerpt(); ?></div>
</div>
<section>
<div>
<span><?php previous_post_link('%link','<< 前の記事'); ?></span>
<span><?php next_post_link('%link','次の記事 >>'); ?></span>
</div>
<div>
<a href="<?php echo home_url() ?>">TOPに戻る</a>
</div>
</section>
<?php endwhile; ?>
<?php endif; ?>
</main>
<?php get_footer(); ?>
スタイルシートを設置
以下のようなスタイルシートを作成。
html > wp-content > themes > my-theme > css > blog-style.scss
.container{
margin: 40px auto;
text-align: center;
max-width: 1000px
}
.footer-container{
max-width: 1000px;
text-align: center;
margin-top: 100px;
color: rgb(153, 153, 153);
}
.blog{
&-date{
font-size: 10px;
color:rgb(153, 153, 153);
}
&-title{
font-size: 20px;
font-weight: bold;
}
}
a{
text-decoration: none;
}
functions.phpで読み込ませる。
function addtional_styles() {
if( is_front_page() ){
wp_enqueue_style( 'front-css', get_template_directory_uri() . '/css/front-style.scss' );
}
if( is_single($post) ){
wp_enqueue_style( 'blog-css', get_template_directory_uri() . '/css/blog-style.scss' );
}
}
add_action( 'wp_enqueue_scripts', 'addtional_styles' );
is_single()はsingle.phpであればtrueを返す。引数に$postを指定すると、現在表示通のページにのみtrueになる。
ページをリロードして完了。

こんな感じでカスタムしていくことでオリジナルのテーマを作成することができます。