ビルドシステムによるテーマ作成とファイル構成

2017年11月25日に加筆・修正をしました。

今回はGruntを使い始めた頃から始めた、テーマ作成の方法とそのファイル構成について触れます。ビルドシステムを使ううえで便宜上こうなった、という類いの内容なので、参考程度にご覧ください。投稿作成にあたり、気付いて改良した内容も含みます。

ビルドシステムとその他ツール

プロジェクトディレクトリの構成

WordPress本体以外をgit管理するために、下記のような構成にしています。Wordpress本体はルートディレクトリの変更をする前提です。

project-name/
    ├ _src/ // 作業ディレクトリ
    │   ├ _bower_components/ // bowerでインストールするライブラリの管理用
    │   ├ ai // Illustratorファイル管理用
    │   ├ doc // 資料管理用
    │   ├ fonts/ // Webフォント管理用
    │   ├ images/ // 画像管理用
    │   ├ jade/ // 静的サイトファイル作成用(Wordpressの場合は使わない)
    │   ├ js/ // javascript管理用
    │   ├ project.json // jade用
    │   ├ psd/ // Photoshopファイル管理用
    │   ├ sass/ // sass管理用
    │   └ wpjade/ // WordPressテンプレファイル作成用
    ├ .bowerrc // bowerでインストールするライブラリの管理ディレクトリ指定用
    ├ .editorconfig // エディタ設定用
    ├ .htaccess // WordPress用 htaccess
    ├ bower.json // bowerでインストールするライブラリ管理用
    ├ gulpfile.js // Gulpファイル
    ├ index.php // WordPress用 index.php
    ├ package.json // node_modules 管理用
    ├ settings.json // Gulp設定用
    └ wp/ // WordPress本体

wpjadeディレクトリ内

wpjade内のjadeファイルをphpファイルとしてコンパイルする前提で下記のような構成にしています。

wpjade/
    ├ assets/
    │   ├ functions.php
    │   ├ screenshot.png
    │   └ style.css
    ├ index.jade
    ├ single.jade
    ├ page.jade
    ├ 404.jade
    ├ その他、テンプレファイル群
    └ templates/
        ├ _fb_sdk.jade
        ├ _ga.jade
        ├ _layout.jade
        ├ _ogp.jade
        ├ _site_tree.jade
        └ php/
            ├ _mixin.jade
            └ phpを記述したファイル群

テーマ用ファイルの内容

Theme Checkで得た情報を元に編集した、下記ファイルについてです。

  • function.php
  • style.css
  • screenshot.png

assets内ファイルの記述

functions.php(関連する内容のみ)

テーマディレクトリ内のcss/、js/内のファイルのみを読ませるための記述を入れてます。あと、タイトルタグ出力用の設定などを。下記サイトを引用させていただきました。

// -----------------------------------------
// wp-head 削除項目
// -----------------------------------------
remove_action('wp_head', 'wp_enqueue_scripts', 1); // js自動読み込み解除
remove_action('wp_head', 'locale_stylesheet'); // ローカル言語用css読み込み解除
// -----------------------------------------
// wp_enqueue_script()の設定
// -----------------------------------------
// JavaScriptに付加されるWordPressのバージョン番号を除去する
function remove_src_ver( $src ) {
    return remove_query_arg( 'ver', $src );
}
add_filter( 'script_loader_src', 'remove_src_ver' );
// -----------------------------------------
// タイトルタグの出力
// -----------------------------------------
// add_theme_support( 'title-tag' ); を使用する
function setup_theme() {
    add_theme_support( 'title-tag' );
}
add_action( 'after_setup_theme', 'setup_theme' );
// タイトルからキャッチフレーズを削除する
function remove_tagline($title) {
    if ( isset($title['tagline']) ) {
        unset( $title['tagline'] );
    }
    return $title;
}
add_filter( 'document_title_parts', 'remove_tagline' );
// セパレータを任意のものに変更する
function custom_title_separator($sep) {
    $sep = '|';
    return $sep;
}
add_filter( 'document_title_separator', 'custom_title_separator' );

style.css

Tagsは入れても入れなくてもTheme Check で怒られるので入れていません。テキストドメインのエラーが未だわからず、という状況です。
下記の記事のおかげで、タグの指定内容が決まっていることがわかりました。Theme Tagsの内容を参照して指定しておけば良いようです。
WordPressテーマを自作する際のstyle.cssに記述するテーマ情報のテンプレート(子テーマ制作にも対応) | オレインデザイン

/*
Theme Name:  (テーマ名)
Theme URI:   (配布テーマではないので使用するWebサイトのドメインを入れてます。)
Description: (テーマの簡単な説明)
Version: 1.0
Author: Shinichi Kuroda
Author URI: http://www.studiobusstop.com/
License:     GNU General Public License v2 or later // WordPress公式に準じて(詳しくないです)。
License URI: http://www.gnu.org/licenses/gpl-2.0.html // WordPress公式に準じて。
Text Domain: (テーマディレのスラッグ名にとりあえず設定しています。)
Tags: (Theme Tags の内容を参照してコンマ区切りで指定)
*/

screenshot.png

WordPress推奨の880x660pxで作成します。すると、Theme Checkで怒られるので、1200x900pxで作成します。「screenshot」なので、本来はテーマのスクリーンショットを入れるべきなのですが、制作者クレジット代わりにロゴを入れることが多いです。

テンプレート

WordPressのテンプレートパーツ機能は使わず、jade(pug)の extends と include を使ってテンプレートを作成する前提として、ベースとなる_layout.jadeを作成します。

テンプレートに記述するWordpress独自関数

Theme Check の情報を元に下記の関数を設定します。

基本

アクションフック用

クラス付加用

js読み込み用

ファビコン

ファビコン指定はサイトアイコン機能に任せる前提です。

IE9以下対応

IE9以下対応の記述は、そろそろ必要ないかもしれません。

wpjade/templates/_layout.jade

block current
block single
block pghdr
block row
-var root = '<?php echo esc_url(home_url()); ?>'
-var tRoot = '<?php echo esc_url(get_template_directory_uri()); ?>'
doctype
html(<?php language_attributes(); ?>)
    head(prefix=( current === 'home' ? 'og: http://ogp.me/ns# website: http://ogp.me/ns/website#' : 'og: http://ogp.me/ns# article: http://ogp.me/ns/article#' ) )
        meta(charset!='<?php bloginfo("charset"); ?>')
        include _site_tree
        | <?php wp_head(); ?>
        include _ogp
        // head内のみで動くので直書き
        != '\n    <!--[if lt IE 9]>'
        script(type='text/javascript', src!='#{tRoot}/js/html5shiv.min.js')
        script(type='text/javascript', src!='#{tRoot}/js/css3-mediaqueries.js')
        != '\n    <![endif]-->'
        //- css
        link(rel='stylesheet', media='screen', href!='#{tRoot}/css/normalize.css')
        link(rel='stylesheet', media='screen', href!='#{tRoot}/css/#{name}.css')
        //- google fonts
        link(rel='stylesheet', href='//fonts.googleapis.com/css?family=Poppins:300,400,600,700')
        //- 現在はwp_enqueue_scriptsを停止させているので下記は読み込まない。
        //- コメント返信のスクリプト
        | <?php if ( is_singular() ) wp_enqueue_script( 'comment-reply' ); ?>
    body(<?php body_class(); ?>)
        #container
            header.m-hdr
                h1.logo
                // ... ヘッダー用の記述
            main.m-body
                -if( pghdr )
                    header.m-pg-hdr(class='#{current}')
                        block pghdrContent
                -if( row )
                    .m-cont.l-flex
                        article(<?php post_class('l-main', 'l-float-l'); ?>)
                            block content
                    .l-sub.l-float-r
                        block subcontent
                -else
                    article(<?php post_class('m-cont'); ?>)
                        block content
            footer.m-ftr
                // ... フッター用の記述
        //- js
        != '\n    '
        | <?php wp_enqueue_script('jquery-original', get_template_directory_uri() . '/js/jquery.min.js'); ?>
        | <?php wp_enqueue_script('#{name}', get_template_directory_uri() . '/js/#{name}.min.js', array( 'jquery-original')); ?>
        | <?php wp_footer(); ?>
        block script

wpjade/templates/_ogp.jade

meta(property='og:title' content!='<?php echo wp_get_document_title(); ?>')
-if( current === 'home' )
        meta(property='og:type' content='website')
        meta(property='og:description' content='#{des}')
        meta(property='og:url' content!='#{root}/')
-else
        meta(property='og:type' content='article')
        | <?php $current_url = esc_url( home_url() . $_SERVER['REQUEST_URI'] ); ?>
        meta(property='og:url' content!='<?php echo $current_url; ?>')
meta(property='og:image' content!='#{tRoot}/images/ogimg.png')
meta(property='og:site_name' content!="<?php _e( '#{title_en}', 'テーマのテキストドメイン' ); ?>")

テンプレート本体の構成

extends ./templates/_layout
include ./templates/php/_mixin
block current
    -var current = 'news'
block pghdr
    -var pghdr = 1
block row
    -var row = 1
block single
    -var single = 1
block pghdrContent
    // 必要な記述
block content
    // 必要な記述
block subcontent
    // 必要な記述
block script
    script(type='text/javascript').
        $(function(){
            // 必要な記述
        });

最終的なテーマディレクトリ内

wp/
    └ wp-content/
        └ themes/
            └ project-name/
                ├ css/
                ├ fonts/
                ├ images/
                ├ js/
                ├ functions.php
                ├ screenshot.png
                ├ style.css
                ├ index.php
                ├ single.php
                ├ page.php
                ├ 404.php
                └ その他、テンプレファイル群

さいごに

bowerは主にjQueryとnormalize-css用で、いいかげんnpmで一元管理したいと思いつつ、そのままな状況です。Theme Checkをクリアするために、やり残していることは下記のとおりです。

Theme Checkでクリアできていない項目

  • 1つのテキストドメインがこのテーマ内で使用されています。テーマが WordPress.org の言語パックと互換性を持つよう、テーマのスラッグと一致しているかを確認してください。

以上です。

Author

  • Shinichi Kuroda - 黒田晋一
  • 香川県高松市 - Takamatsu-shi, Kagawa, Japan.
  • Mail - info@studiobusstop.com