この記事では、普段 Laravel を使って開発しているエンジニアが WordPress テーマを作成する際にできるだけ違和感のない環境を作成する方法を紹介します。
いつも View まわりで使っている技術を取り入れようということで、テンプレートエンジンに Blade を、Sass コンパイルに Laravel Mix を使用します。
準備
WordPress
インストール
Codex に書かれている通りですが…。
$ wget http://wordpress.org/latest.tar.gz
$ tar -xzvf latest.tar.gz
$ rm -f latest.tar.gz
テーマディレクトリ作成
テーマの名前はもちろん任意です。
$ cd wordpress/wp-content/themes
$ mkdir mytheme
Composer
インストール
PHP パッケージマネージャ Composer を使って Blade ライブラリをインストールするので、まずは Composer 自体をマシンにインストールします。
$ php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
$ php -r "if (hash_file('SHA384', 'composer-setup.php') === '93b54496392c062774670ac18b134c3b3a95e5a5e5c8f1a9f115f203b75bf9a129d5daa8ba6a13e2cc8a1da0806388a8') { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;"
$ php composer-setup.php
$ php -r "unlink('composer-setup.php');"
$ mv composer.phar /usr/local/bin/composer
初期化
composer init
コマンドでパッケージ管理のための設定ファイルを生成します。
$ composer init
Package name (<vendor>/<name>) [masahiro.harada/mytheme]:
Description []:
Author [Masahiro Harada <******@***.com>, n to skip]:
Minimum Stability []:
Package Type (e.g. library, project, metapackage, composer-plugin) []:
License []:
Would you like to define your dependencies (require) interactively [yes]? no
Would you like to define your dev dependencies (require-dev) interactively [yes]? no
Do you confirm generation [yes]?
「Would you like to define〜」と聞かれる2行以外は何も入力せずエンターでOKです。
Bladeテンプレート
今回はテンプレートエンジンとして Blade を使用します。そもそもは Laravel フレームワークの一部ですが、切り離して独立したライブラリにしたバージョンを使います。
なぜテンプレートエンジン?
初めて WordPress に触れて簡単なテーマを自作しようと思い、同梱されているテーマのソースコードを調べてみるとなんとも居心地が悪いです
たとえばヘッダー部品のファイルを見ると…
<html>
<head>
<meta ...>
<?php wp_head(); ?>
</head>
<body>
<header id="...">
<?php // ... ?>
</header>
<div class="site-content-contain">
<div id="content" class="site-content">
途中で終わっています。タグの対応関係が正しいかとか、ワケ分からなくなりそうです。
あと制御構文がとにかく見づらい!
<?php if ( have_posts() ) : while ( have_posts() ) : the_post(); ?>
<!-- ここに記事一件分を出力するコードを書く -->
<?php endwhile; else : ?>
<p><?php _e( 'Sorry, no posts matched your criteria.' ); ?></p>
<?php endif; ?>
このような記述の分かりにくさはテンプレートエンジンを使えば解消できます。
Bladeの機能
簡単に Blade でできることを紹介します。
変数出力
波カッコ2つで変数の値を出力します。
<h1>{{ bloginfo('name') }}</h1>
こちらと同じ意味です。
<h1><?php echo bloginfo('name'); ?></h1>
制御構文
アットマーク @
をつけたキーワードで読みやすい制御構文を表現できます。
<!-- 条件分岐 -->
@if ($var === true)
<p>Hello</p>
@else
<p>Goodbye</p>
@endif
<!-- 繰り返し -->
@foreach ($posts as $post)
<li>{{ $post->title }}</li>
@endforeach
上記はこちらと同じ意味です。
<!-- 条件分岐 -->
<?php if ($var === true) : ?>
<p>Hello</p>
<?php else : ?>
<p>Goodbye</p>
<?php endif; ?>
<!-- 繰り返し -->
<?php foreach ($posts as $post) : ?>
<li>{{ $post->title }}</li>
<?php endforeach; ?>
やっていることは同じですが、php
タグを省略できるだけでかなり読みやすくなると思います。
レイアウト
レイアウトとは、各ページの HTML で共通の外枠のことです。WordPress というか PHP には標準でそのような機能がないので途中で終わるヘッダー部品などが出てきてしまいます。
レイアウトファイルはこのような内容になります。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>ブログの名前</title>
</head>
<body>
<main>
@yield('content')
</main>
</body>
</html>
テンプレートから HTML を作成するときに @yield('セクション名')
の部分にページごとのコンテンツが挿入されます。ページごとのテンプレートは以下のようになるでしょう。
@extends('layout')
@section('content')
<h1>コンテンツだよ</h1>
@endsection
まず @extends('レイアウトファイル名')
でどのレイアウトを使うか指定します。そして @section('セクション名')
〜 @endsection
の間に差し込みたい内容を記述します。
以下の HTML が最終的に生成されます。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>ブログの名前</title>
</head>
<body>
<main>
<h1>コンテンツだよ</h1>
</main>
</body>
</html>
インクルード
インクルードは部品化したテンプレートファイルを読み込む機能です。
<body>
@include('header')
</body>
@include('テンプレート名')
と記述すると、テンプレート名.blade.php
というファイルが探し出され(Blade テンプレートの拡張子は .blade.php
です)…
<header>ヘッダーだよ</header>
結果的にこのような HTML が出来上がります。
<body>
<header>ヘッダーだよ</header>
</body>
とりあえずこれくらいの機能が分かれば便利に使えると思います。より詳しい Blade の機能や書き方についてはマニュアルを参照してください。
インストール
さて、インストール手順を紹介していきましょう。といっても Composer で一発です。
$ composer require jenssegers/blade
インストールが成功すると vendor
というディレクトリが作成されていて、その中にインストールしたライブラリが配置されています。覗いてみると Blade 以外のライブラリも入っていますが、Blade が動作するために必要なライブラリなので問題ありません。
次に views
と cache
というディレクトリを作成してください。どちらもテンプレートエンジンのために必要です。
$ mkdir views cache
views
は Blade テンプレートファイルを格納する場所で、cache
はテンプレートファイルから変換された普通の PHP ファイルをキャッシュとして格納する場所です。
Git で管理する場合は、cache
ディレクトリの下に作成された PHP ファイルを無視するために .gitignore
ファイルを置きましょう。
$ touch cache/.gitignore
*
!.gitignore
functions.php
準備が整いましたのでまずは functions.php
を作成しましょう。
Blade テンプレートをふつうの PHP ファイルに変換する関数を記載します。functions.php
に書いておけば、あとで index や single など各種ページでこの関数を使いまわすことができます。
<?php
require_once(__DIR__ . '/vendor/autoload.php');
use Jenssegers\Blade\Blade;
/**
* Bladeテンプレートをレンダリングする
*/
if (!function_exists('render_blade')) {
function render_blade($template_name)
{
$blade = new Blade(__DIR__ . '/views', __DIR__ . '/cache');
return $blade->make($template_name);
}
}
レイアウト
次にレイアウトファイルです。
<!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>{{ bloginfo('name') }}</title>
<link rel="stylesheet" href="{{ get_template_directory_uri() }}/style.css">
</head>
<body>
@include('share.header')
<main>
@yield('content')
</main>
@include('share.footer')
</body>
</html>
ヘッダーとフッターは部品化してインクルードします。
共通パーツ
他のファイルからインクルードされるパーツです。
こちらがヘッダー。
<header>
<nav>
<a href="/">{{ bloginfo('name') }}</a>
</nav>
</header>
そしてフッターです。
<footer>
This is a footer.
</footer>
indexページ
ここから各ページの作成です。固定ページや 404 などいろいろ種類はあるようですが、今回は index と single のみ作成します。他のページも同じ手順で作成できるはずです。
index.php
index.php
にはテンプレートをレンダリング(HTML に変換)する処理のみを記載します。
<?php
echo render_blade('index');
functions.php
に定義した関数を呼び出します。引数はテンプレートの名前だったので、views/引数.blade.php
というファイルがレンダリングされます。
テンプレート
ふだん index.php
に書く内容はテンプレートに記述します。ふつうに php タグも使えます。echo する必要がある場合は {{}}
で、関数を実行すればいいだけの場合は php タグのままという使い分けになるでしょう。
@extends('layout')
@section('content')
<div class="container">
<ul>
@if (have_posts())
@while (have_posts())
<?php the_post(); ?>
<li>
<a href="{{ the_permalink() }}">{{ the_title() }}</a>
</li>
@endwhile
@endif
</ul>
</div>
@endsection
テンプレートファイルも結局は機能が追加された PHP ファイルなので、index.php
などに書いていた内容はそのままテンプレートにも書くことができます。
singleページ
single も index ページと同様です。
single.php
<?php
echo render_blade('single');
テンプレート
@extends('layout')
@section('content')
<div class="container">
@if (have_posts())
@while (have_posts())
<?php the_post(); ?>
<article>
<h1>{{ the_title() }}</h1>
<div class="content">
{{ the_content() }}
</div>
</article>
@endwhile
@endif
</div>
@endsection
index ページと single ページだけを紹介しましたし、中身もスカスカですが、あとは完成図に応じて記述を増やしていけば OK です。
続いて Sass のコンパイル方法を紹介します。
Laravel Mix
Sass のコンパイルには Laravel エンジニアにはおなじみの Laravel Mix を使用します。Laravel に標準で同梱されていて、簡単な設定で Sass や ES2015 のコンパイルができる便利なライブラリです。Webpack の設定を自動生成してくれるライブラリという理解でいいのではないでしょうか。Laravel のドキュメントにも説明があるのでそちらも参照してください。
インストールと設定
インストール
インストールは npm で行います。npm がなければ Node.js をダウンロードしましょう。npm も一緒についてきます。
$ npm init -y
$ npm i -D laravel-mix
webpack.mix.js
インストールできたら設定ファイルを作成します。
$ touch webpack.mix.js
Sass コンパイルのために sass
メソッドを使います。第一引数がコンパイル元で第二引数がコンパイル先です。
let mix = require('laravel-mix');
mix
.sass('src/sass/style.scss', './style.css')
.options({
processCssUrls: false
});
options
メソッドでコンパイル時の設定を指定します。例えば上記の processCssUrls
の記述はマニュアルにもある通り、Webpack が Sass ファイル中の url()
の画像パスを書き換えないようにするための指定です。
package.json
package.json
にコンパイル実行のための以下のスクリプトを追加します。
{
"scripts": {
"dev": "NODE_ENV=development node_modules/webpack/bin/webpack.js --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js",
"watch": "NODE_ENV=development node_modules/webpack/bin/webpack.js --watch --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js",
"hot": "NODE_ENV=development webpack-dev-server --inline --hot --config=node_modules/laravel-mix/setup/webpack.config.js",
"production": "NODE_ENV=production node_modules/webpack/bin/webpack.js --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js"
},
}
Sassでスタイルシートを作成
設定が完了したのでスタイルシートを書きましょう!
$ mkdir -p src/sass
$ touch src/sass/styles.scss
WordPress のテーマなので Styles にはコメントが必要ですね。
/*!
Theme Name: MyTheme
Author: Masahiro Harada
Description: My Theme
*/
body {
h1 {
color: red;
}
}
注意していただきたいのは、一行目の末尾の !
です。このビックリマークがなければ本番ビルドした際にコメントは除去されてしまいます。ファイルサイズを減らすために必要な機能なのですが、style.css
の冒頭のコメントだけはないとテーマとして認識されないので、!
をつけています。
スタイルシートができたら以下のコマンドでコンパイルができます。
// 開発用ビルド
$ npm run dev
// 監視モード(ファイルが変更されたら自動的に開発ビルドが走る)
$ npm run watch
// 本番用ビルド(ミニファイされる)
$ npm run production
開発中は npm run watch
で、本番にリリースする直前に production
コマンドを実行するような手順になるでしょう。
今回は Sass のコンパイルのみ紹介しましたが、ES2015 や Vue のトランスパイルも可能です。
いかがだったでしょうか。最近になって初めて WordPress に触れてみて、特定の用途では便利そうな反面、コードはかなーりレガシーだなと感じたので、Laravel フレームワークで使われる便利なツール(テンプレートエンジン Blade と Laravel Mix)を WordPress でも使う方法を紹介しました。