WordPressのテーマ自作は怖くない 【第一回:最小構成でテーマを作ろう】
こんにちは。Kalsarikannintのフロントエンド担当・daiです。
WordPress、使ってますか?未だに無料CMSの中では右に出る者はいないレベルで支持されていますが、かくいうこのサイトも、WordPressで作られています。
そして、デザインの要となるテーマについては、ボイラープレートすら使わずに、イチから自作しています。
PHPが苦手なこともあり、ほんの数ヶ月前まではなるべくWordPressを避けてきた僕ですが、やってみると意外と怖くなかったよ、ってことをシリーズ(全4回の予定)でお伝えできればと思います。
いままで静的なサイトは作ったことがあるけど、「複雑そう」とか「既存のテーマをイジるのが怖い」といった理由でWordPressを避けていたコーダーの方の背中を押すきっかけになれば幸いです。
まずは最小構成で作ってみよう
このサイトのもともとのテーマが「シンプル」「15年前のインターネット」だったこともあり、最小構成で成り立っています。WordPress初心者の方も、まずは「トップページ」と「記事ページ」だけのシンプルなサイトで作ってみることをおすすめします。
その後、折を見て「一覧ページ」と「検索結果ページ」「404ページ」くらいを作れば、文句ないのではないでしょうか。このサイトもそんなレベルです。
とりあえずの最小構成で作る際に必要なのは以下のファイルたち。
wp-content/
    └ themes/
        └ kalsarikannint-theme/
            ├ images/
            ├ style/
            │   ├ common.css
            │   ├ front-page.css
            │   └ single-post.css
            ├ footer.php
            ├ front-page.php
            ├ functions.php
            ├ header.php
            ├ index.php
            ├ single-post.php
            └ style.css
結構あるように感じるかもしれませんが、各ページのヘッダーとフッターがそれぞれ別ファイルに分かれてたり、テーマの情報を記載するだけのために style.css を配置しないといけなかったりと、お約束ごととしてファイル数が増えてしまっていますが、実際には2画面分なので、それほど負担はありません。
それぞれのファイルに記述していこう
それでは早速、それぞれのファイルに必要なコードを書いていきましょう。
ヘッダーとフッター
サイト共通で利用するヘッダーとフッターがあれば、各ファイルに記述してください。特になければ以下のコードだけでも動かすことができます。
header.php
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <?php wp_head(); ?>
</head>
<body>
footer.php
<?php wp_footer(); ?>
</body>
</html>
トップページ
トップページのうち、ヘッダーとフッターで記述した場所を除いて記述していきます。
今回は、このサイトのTOPページのように、投稿されている記事をIDの新しい順に一覧で表示する例です。
WordPressの難しいところが出ちゃってますが出来る限りコード内にもコメント残したつもりなので… がんばろう!
front-page.php
<?php get_header(); ?>
    <?php if(have_posts()) : ?>
    
    <div class="inner">
        <?php while(have_posts()) : the_post(); ?>
        <?php 
            // ------------------------------
            //  各記事ごとの準備
            // ------------------------------
            // 本文の500文字だけ抜粋
            $content = $post->post_content != '' ? str_replace('\\n', '', mb_substr(strip_tags($post-> post_content), 0, 500,'UTF-8')) : '本文が取得できませんでした。';
        ?>
        <div class="article_list">
            <a class="article_list--box" href="<?php the_permalink(); ?>">
                <p class="article_list--title"><?php the_title(); ?></p>
                <span class="article_list--content"><?php echo $content; ?></span>
            </a>
        </div>
        
        <?php endwhile ?>
        <?php 
            // ページネーション
            the_posts_pagination(array(
                'prev_text' => '前へ',
                'next_text' => '次へ'
            ));
        ?>
    </div><!-- /inner -->
    <?php else: ?>
        <div class="error error--no_article">
            <h1>記事はまだありません</h1>
        </div>
    <?php endif; ?>
<?php get_footer(); ?>
だいたい察しがついていると思いますが、 <?php get_header(); ?> で header.php を、 <?php get_footer(); ?> で footer.php をインクルードしています。
そして、記事が1つ以上存在するときに <?php if(have_posts()) : ?> 〜 <?php else: ?> の間が処理され、記事の数だけ <?php while(have_posts()) : the_post(); ?> 〜 <?php endwhile ?> が繰り返されます。
記事ページ
各記事の内容が表示されるページです。一旦はタイトルと中身が出ればOK!
single-post.php
<?php get_header(); ?>
    <?php if ( have_posts() ) : ?>
        <div class="inner -post">
        <?php while( have_posts() ) : the_post(); ?>
            <article>
                <h1><?php the_title(); ?></h1>
                <div><?php the_content(); ?></div>
            </article>
        </div><!-- /inner -->
        <?php endwhile;?>
    <?php endif; ?>
<?php get_footer(); ?>
いろいろ司るfunctions.php
テーマに機能を持たせたりすることができる functions.php も必須ファイルの1つです。
functions.php
/**
 * CSS と JavaScript の読み込み
 */
add_action('wp_enqueue_scripts', function() {
    wp_enqueue_style('original', get_template_directory_uri().'/style/common.css');
    
    if (is_front_page()) {
        // フロントページ
        wp_enqueue_style('front-page', get_template_directory_uri().'/style/front-page.css', array('original'));
    } else if (is_single()) {
        // 個別記事ページ
        wp_enqueue_style('single-post', get_template_directory_uri().'/style/single-post.css', array('original'));
    }
});
/**
 * タイトルタグの生成
 */
add_action('wp_head', function() {
    $site_name    = get_bloginfo('name', 'display');
    $title        = get_the_title().'  |  '.$site_name;
    $description  = get_bloginfo('description');
    if (is_front_page()) {
        // フロントページ
        $title = $site_name.'  |  '.$og_desc;
    } else if (is_single()) {
        // 個別記事ページ
        $description = get_the_excerpt();
    
    }
 
    echo '<title>'.$title.'</title>';
    echo '<meta name="description" content="' .$description. '" />';
});
ページごとに読み込むCSSファイルを変えたり、title や description を head 内に出力したりする処理を記述しています。
慣れてくると、色々試したくなってきて、最終的にこのファイルが肥大化して大変なことになりますw
最低限のCSSたち
ヘッダー・フッター、それから全ページで共通して使いたいclassは style/common.css に記載します。
style/front-page.css や style/single-post.css は同名のPHPファイルが呼ばれたときに適用されるようにしているので、競合しそうな部分にお使いください。
style/common.css
:root {
    --light-gray: #F0F0F0;
    --gray: #65717B;
    --blue: #0f83fd;
    --navy: #1A2638;
    --black: #222;
    --beer-yellow: #D9DE00
}
.inner {
    width: 100%;
    max-width: 1200px;
    margin: 0 auto
}
.inner.-post {
    max-width: 900px
}
.error h1 {
    color: var(--black);
    margin-bottom: 4rem;
    font-size: 18px;
    font-weight: bold
}
.error--no_article {
    padding: 4rem 0 0;
    text-align: center
}
style/front-page.css
.article_list {
    position: relative
}
.article_list--box {
    padding: 2rem;
    display: block;
    border-bottom: solid 1px var(--black)
}
.article_list--box:hover {
    background-color: var(--light-gray)
}
.article_list--title {
    font-size: 2rem;
    font-weight: bold;
    line-height: 1.25em;
    margin-bottom: 5rem
}
.article_list--content {
    max-width: 100%;
    max-height: 1em;
    display: inline-block;
    font-size: 1.2rem;
    color: #65717b;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis
}
style/single-post.css
/* 今回特に記載することがありませんでした。必要に応じてどうぞ。 */
お約束ごとなファイルたち
WordPressの仕様上、最低限用意しなくてはいけないファイルたちを用意しておきます。
index.php
<?php get_header(); ?>
<h1>準備中</h1>
<?php get_footer(); ?>
WordPressでは、どのPHPファイルをどのタイミングで使うかがあらかじめ決まっていて、例えばサイトのトップページ(Site Front Page)では、最初に front-page.php を探して、存在しなければ home.php を探して、それもなければ index.php を表示する動きになっています。
その優先順位の一覧は以下のページに図で解説があるので、本格的なテーマを作りたくなったらご一読あれ… 僕は把握してないですw
とりあえず、上記ページの図を見ると、最終的には index.php を参照するようになっているので、index.php 最後の砦として働く重要・必須なファイルとなっています。
裏を返せば、index.php に到達しちゃったということは何かしらテーマファイルに考慮不足がある可能性もあるので、しばらくは上記のようにミスに気づきやすいようなページにしておきます。(最終的にはトップページや404ページにリダイレクトさせるのも手かなと思ったり)
style.css
/*
Theme Name: Sample
Author: Knot Works
Author URI: <https://kalsari.net/>
Version: 1.0.0
*/
こちらもWordPressの少し気持ち悪い仕様、テーマディレクトリ直下に用意した style.css へ、コメントとしてテーマファイルの概要を記載する必要があります。必須です。
スタイルシートとして利用しなくてもいいので、このファイルには特にCSSは記載しません。
超最小構成でのテーマファイルの完成!
これで一通り動作するテーマファイルができたのではないでしょうか。
作成したテーマをフォルダごと、WordPressが動作しているサーバー上の /wp-content/themes/ 配下に置いてあげると、管理画面から選択できるようになるはずです!
あとはみなさんのコーディング力で理想の見た目に近づけていってください。
次回は、一覧ページを作る!をお届け予定です!書く気力があれば…。 
乞うご期待!
