WordPress

WP-CLIのスキャフォルドを使う

スキャフォルド、Ruby on Railsとか他のWEBフレームワークでお馴染みのものです。 WordPressはコアでなくWP-CLIで提供されています。

投稿タイプとタクソノミーを作るのは、一から書いても流用しても割と手間のかかるものですが、WP-CLIのスキャフォルドを使うと素早く雛形が作れます。

この記事では主に下記3つのスキャフォルドの説明をします。

あと、Gutebergブロックのスキャフォルドもできます。

今回、WP-CLIのインストール方法は割愛します。

プラグインのスキャフォルド

まずカスタム投稿タイプやタクソノミー、カスタムフィールドを設定するプラグインを用意します。

wp scaffold plugin add_post_type --skip-tests

オプションでプラグイン名を予めセットしたり色々機能がありますが、プラグインとして最低限動けばいいのでテストユニットもなし、スラッグだけ設定します。
投稿タイプ、タクソノミーを設定するぐらいなら、テストユニットはおそらく出番がないです。

これで、add_post_typeというプラグインの雛形ができました。

投稿タイプのスキャフォルド

投稿タイプの定義はテーマとプラグインのどちらでも行えますが、今回はプラグインで行います。
サンプルとして「プログラミング言語」という投稿タイプを作ります。

wp scaffold post-type language --label="programing language" --plugin=add_post_type

add_post_type プラグインフォルダ内に post_types フォルダと language.php が生成されました。

プラグインの add_post_type.php は空っぽなので、生成した language.phpを読み込むよう実装。

require_once dirname( __FILE__ ) . '/post-types/language.php';

プラグインを有効にすると投稿タイプ「プログラミング言語」が使えます。

表示文言とか全部、テキストドメインを利用する多言語対応の形式で設定されています。
日本語表示にしたい場合はpo/moファイルを作るか、こんな感じで書き換えても表示されます。
上記画面では、このように書き換えてテキストドメインを利用せずに日本語表示をしています。

タクソノミーのスキャフォルド

先に実行したのと同様に「プログラミング言語」投稿タイプに「型付け」タクソノミーを設定してみます。

wp scaffold taxonomy typing --post_types=language --label="typing" --plugin=add_post_type

投稿タイプと同様にadd_post_type.phpにtyping.phpを読み込むように記述します。

require_once dirname( __FILE__ ) . '/tasonomies/typing.php';

注意 予約語について

タクソノミーなどに使える単語には制約があります。

WordPressの予約語
WordPressコアが提供する機能に重複するスラッグを使うとエラーが発生したりレスポンスが404になります。
今回は「typing」なので問題ありませんが、「型だからスラッグは『type』にしよう」とやるとエラーで動きません。
タクソノミーには予約語があることは念頭に入れておくと良いでしょう。

「プログラミング言語」投稿タイプを使う

下記のようにタクソノミーの階層性を True にすると「投稿」に対する「カテゴリー」のように扱えます。

'hierarchical' => true

「プログラミング言語」投稿タイプと「型付け」タクソノミーを利用した投稿サンプルです。テーマはWordPress 5.4デフォルトのTwentyTwentyです。

このように投稿タイプとタクソノミーの設定が素早く確実にできます。
数多くの設定項目やラベルをコマンド1つでセットしてくれるのは便利です。

ぜひスキャフォルドを活用してください。

テーマカスタマイズ関係でWordPressコアのコードを調べた

テーマカスタマイザーにカラーピッカーを追加する際、引数をどうすればいいか分からなくて困ってしまったので、コアのコードまで辿って調べました。

関連記事:テーマカスタマイザーに自由にカスタマイズ項目を追加する方法

CodexのテーマカスタマイズAPIにはずばり、カラーピッカーを追加する際の例が載ってます。

$wp_customize->add_control( 
  new WP_Customize_Color_Control(
     $wp_customize,
    'link_color',
     array(
       'label'      => __( 'Header Color', 'mytheme' ),
       'section'    => 'your_section_id',
       'settings'   => 'your_setting_id',
     ) ) );

しかし、この引数になってる配列には何を指定すればいいのか、よく分かりません。というか、書いてありません。本家の英語版Codexも解説内容は同等です。「add_controlメソッドも参照せよ」とありますので移動します。

クラスリファレンスに飛びました、WordPressコアの仕様書です。
Class Reference/WP Customize Manager/add control

$wp_customize->add_controlメソッドが取る引数はCodexによると下記の通り。

Parameters
$id
(mixed) (required) A string or a specific customization controller object. Default: None
$args
(array) (required) Not used if $id is a control object, otherwise an instance of WP_Customize_Control() (plain text) is created using the specified arguments. Default: None

WP_Customize_Manager/add_control

第一引数は文字列かコントローラーオブジェクトが必須です。
第二引数の配列は、第一引数がオブジェクトの場合は使われないので、add_control()への引数はオブジェクト1個で、今回はnew WP_Customize_Color_Control()ですね。

ということは、WP_Customize_Color_Controlクラスのコンストラクタ引数を確認すればいいわけです。

しかし、その説明がWP_Customize_Color_Controlクラスのリファレンスにありません。

テーマカスタマイザーAPIのコード例と同じ!

Codexの右上の検索フォームからWordPress.org内を検索するとCodexでなくdeveloper.wordpress.orgのクラスリファレンスが見つかります。

Code Reference WP_Customize_Color_Control

しかし、コードリファレンスはまたしてもこれだけです。

説明らしい説明がありませんので、表示されているWordPressコアのコードもみてみます。

/**
 * Constructor.
 *
 * @since 3.4.0
 * @uses WP_Customize_Control::__construct()
 *
 * @param WP_Customize_Manager $manager Customizer bootstrap instance.
 * @param string               $id      Control ID.
 * @param array                $args    Optional. Arguments to override class property defaults.
 */
  • 第一引数:カスタマイズマネージャーのインスタンス
  • 第二引数:ID(識別子)
  • 第三引数:デフォルトのプロパティを上書きするための配列 (オプショナル、渡さなくてもいい)

記述はありましたが、結局、コンストラクタ引数の配列には何を入れたらいいんでしょうか?

ここで注目すべきはclass-wp-customize-color-control.php の最初の宣言です。

class WP_Customize_Color_Control extends WP_Customize_Control

WP_Customize_Color_ControlWP_Customize_Controlを継承したクラスです。
WP_Customize_Controlをベースに、カラーピッカーを表示するために必要な変数、関数を追加する形になっています。

よって、インスタンス引数は WP_Customize_Control と同じでよい、ということです。

参考:PHP公式 オブジェクトの継承

ということで、 CodexのWP_Customize_Cotrolリファレンスを確認します。

ようやく、辿り着きました。Arguments以下の定義リストが WP_Customize_Color_Controlにも指定できる引数一覧です。

テーマカスタマイザーに自由にカスタマイズ項目を追加する方法の記事では、ここから必要な項目のみを指定しています。

ちなみにWP_Customize_Controlクラスのリファレンスからソースコードをたぐると、コメントのConstructorセクションに引数の説明があります。

テーマカスタマイザーに自由にカスタマイズ項目を追加する方法

このブログのテーマ、shirohanadaに実装している「コンテンツ背景色」のカスタマイズ項目の追加方法について解説します。

カスタムヘッダーでヘッダー画像を自由に変えられるようにしたところ、期せずしてヘッダー色のカスタマイズも付随していたので、背景色とかもカスタマイズ可能にしました。

「コンテンツ背景色」はshirohanadaで独自に追加したカスタマイズ項目です。投稿の背景色などデフォルトで薄いグレーを敷いている部分の色が変更できます。テーマカスタマイズAPIを使うと、割と簡単に自由にカスタマイズ項目が実装できます。

基本的にはWordPress Codex テーマカスタマイズAPIに沿って実装していきました。

目次

テーマカスタマイザーの仕組み

  1. functions.phpにカスタマイズ項目を追加する設定を書く
  2. ダッシュボードの「外観」→「カスタマイズ」から、スタイルを変更する
  3. 変更した内容はoptionsテーブルのtheme_mods_テーマ名 レコードに格納される
  4. functions.phpでカスタマイズの内容を読み出してCSSを作る
  5. ヘッダーにインラインCSSとして出力する
  6. style.cssはカスタマイズしたスタイルで上書きされる

ざっとこういう具合です。

コントロールの追加

まず、「コンテンツ背景色」という名前のカラーピッカーを表示する設定をfunctions.phpに書きます。

  • $wp_customize->add_setting( args )
  • $wp_customize->add_control( args )

この2つの関数がテーマカスタマイザーの呼び出し時に実行されるよう、add_action('customize_register') で指定してます。

add_settingでの設定

まずはadd_setting関数から。

新たに作るカスタマイズ項目の設定を$wp_customizeオブジェクトの関数add_setting()に引数で渡します。ここで設定しておくとget_theme_mod( ‘ID’ )でカスタマイズした設定を取得できて、後々で楽になります。

$wp_customize->add_setting(
    'contents_bg_color',
     array(
        'default' => '#f8faff',
        'transport' => 'refresh',
        'sanitize_callback' => 'sanitize_hex_color',
    )
);

引数の内容は

  • ID(テーマ内で一意な識別名): contents_bg_color
  • 配列
    • デフォルト値:#f8faff
    • カスタマイズ画面での更新用の設定:refresh
    • 呼び出し時に実行するサニタイズの種類:sanitize_hex_color

設定内容の保存先をoptionsテーブルか、optionsテーブルのtheme_mods_shirohanadaレコードか指定できます。デフォルトではtheme_modsレコードに保存なので、今回は指定しません。

optionsテーブルへの保存を指定するとカスタマイズ項目1つにつき1レコード生成されると思いますが、特にメリットもなさそうなのでテーマのカスタマイズ関係はtheme_modsに固めています。

transport設定は、とりあえずrefreshでいきます。この設定だと、色を変えた時にプレビュー画面が数秒フェードアウトしてしまいますが、ちゃんと使えます。別途jQueryを書いたjsファイルを用意しておくとプレビュー画面でフェードアウトなしの再描画をしてくれます。

sanitize_callbackは、新たに作りたい項目が色なので16進カラーに適用するサニタイズを指定します。

参照:https://codex.wordpress.org/Class_Reference/WP_Customize_Manager/add_setting

add_controlでの設定

同様にadd_control関数に、コントロールを表示するための設定を渡します。今回は色の設定になるので、カラーピッカーを使えるように引数を組みます。他にもテキストエリア、ラジオボタンやセレクトボックスなどが指定できます。
参照: https://codex.wordpress.org/Class_Reference/WP_Customize_Manager/add_control

Usageなんかを参考にして、下記のコードを書きました

$wp_customize->add_control(
	new WP_Customize_Color_Control(
		$wp_customize,
                'contents_bg_color',
                array(
                    'label' => 'コンテンツ背景色',  
                    'section' => 'colors',
		)
	)
);

カラーピッカーの場合は、ちょっと特殊でWP_Customize_Color_Controlクラスのインスタンスを引数にします。

で、add_control()関数にオブジェクトを渡す場合は、引数は1個でOK。
IDとかラベルはWP_Customize_Color_Controlクラスのコンストラクタ引数で指定します。

  • 第一引数 コントロールマネージャーのオブジェクト $wp_customize
  • 第二引数 テーマ内で一意なID(識別子)
  • 第三引数 配列 オプショナル、デフォルトの設定の上書きに使う

第三引数の配列は new WP Customize_Contorol()で渡せる内容と同一のようです。
今回はラベルとセクションだけでいいです。配列にsettingsがない場合はIDで一致するカスタマイズ設定を取得&書込してくれます。なので、先ほどadd_setting() で指定したのと同じIDを入れておきます。

今回はラベルとセクションだけでいいです。配列にsettingsがない場合はIDで一致するカスタマイズ設定を取得&書込してくれます。なので、先にadd_setting() で指定したのと同じIDを入れておきます。

settings
All settings tied to the control. If undefined, `$id` will be used.

https://codex.wordpress.org/Class_Reference/WP_Customize_Control

labelはコントロールの表示名です。

sectionは「基本情報」「ヘッダー」「色」などの区分のうち、どこにコントロールを入れるかを指定します。sectionを新たに作ることもできます。

WP_Customize_Color_Controlクラスのインスタンス引数とか、Codexに説明がなくてコアのコードを見てきたので、まず合ってると思います。
調べた際の記事はこちら:テーマカスタマイズ関係でWordPressコアのコードを調べた

add_actionでフック

カスタマイズ項目を追加するための最終的なコードは下記の通りです。
add_actionに渡す関数(下記コードではcontents_bg_customize_register)は、引数に$wp_customizeを取ります。WordPress本体が使用しているグローバル変数です。

function contents_bg_customize_register( $wp_customize ) {
	$wp_customize->add_setting(
		'contents_bg_color', 
                 array(
			'default' => '#f8faff',
			'transport' => 'refresh',
			'sanitize_callback' => 'sanitize_hex_color',
		)
	);
	$wp_customize->add_control(
		new WP_Customize_Color_Control(
			$wp_customize,
			'contents_bg_color',
			array(
				'label' => 'コンテンツ背景色',
				'section' => 'colors'
			)
		)
	);
};
add_action( 'customize_register', 'contents_bg_customize_register' );

CSSの生成とヘッダーへの埋め込み

カスタマイズ項目が追加できたので、これを読み出してCSSを生成します。生成したCSSはadd_actionで<head>に埋め込まれるようセットします。
ヘッダーにインラインで埋め込まれるため、外部ファイルであるstyle.cssより優先度が高くなります。

カスタマイザーで設定した値を取得するにはget_theme_mod()関数を使います。

function mytheme_customize_css()
{
    ?>
         <style type="text/css">
             h1 { color:<?php echo get_theme_mod('header_color', '#000000'); ?>; }
         </style>
    <?php
}
add_action( 'wp_head', 'mytheme_customize_css');

このようにCodexにあるような書き方でもいいですが、自分はヒアドキュメントを使って書きました。
ヒアドキュメントでCSSを書いて変数に入れてしまう方が読みやすいと思います。ただし、echoで出力する際にエスケープ処理が必要になります。(WordPressコーディング規約に準拠させるなら)

function customizer_css_output() {
	$bg_color = get_background_color();
	$contents_bg_color = get_theme_mod( 'contents_bg_color', '#f8faff' );
	$style = <<<CSS
<style type="text/css" id="shirohanada-customizer">
	body { background-color : #$bg_color; }
	.side-widgets,
	.page-title,
	.pagination,
	.nomatch-contents,
	.link-posts p,
	.type-page,
	.type-post {
		background-color : $contents_bg_color ;
	}
</style>
CSS;
	$allowed_style_tag = array(
		'style' => array(
			'type' => array(),
			'id' => array(),
		),
	);
	echo wp_kses( $style, $allowed_style_tag );
}
add_action( 'wp_head', 'customizer_css_output' );

get_background_color()はカスタムバックグラウンド機能で指定した色を取得します。これはBody要素に適用するので、一緒に読み出して設定してしまいます。

get_theme_mod( 'contents_bg_color', '#f8faff' )
第一引数にIDを指定します。add_setting/add_controlで指定したIDをセット。これだけでoptionsテーブルのtheme_mods_shirohanadaレコードから、該当するIDの設定値を取得してくれます。設定値が空の場合、第二引数のデフォルト値が使われます。

wp_kses( $style, $allowed_style_tag )
wp_kses()関数でエスケープ処理をします。第一引数にCSSヒアドキュメントを格納した変数、第二引数にタグ・属性の配列を渡すと、指定したタグ・属性のみをそのまま出力してくれます。今回はスタイルタグと、type・idを出力して欲しいので上記のような配列を作って引数として渡しています。

実際にヘッダーに出力されるCSSは以下の通り。

本番用はカスタムヘッダーの設定も一緒に取得&出力している

完成

add_settingの設定時に説明したように、カラーピッカーで色を変えるとプレビュー画面が数秒フェードアウトしてから反映されます。

テーマカスタマイズAPI ステップ 2: JavaScript ファイルの作成で説明されているように、更新用jsファイルを用意すれば、WordPressがデフォルトで用意しているカスタマイズ項目のように、フェードアウト無しで一瞬でプレビューが描画されます。

$wp_customize->add_controlの引数がやや複雑ですが、非常にシンプルな記述でオリジナルの項目を作成できます。

テーマフォルダの画像を表示するときに便利な関数

常用していた画像の呼び出し方法だと、srcsetプロパティを使った時にちょっと読みにくくなるので、get_theme_file_uri() 関数を使って書き換えてみました。

WordPressのテーマ作成で、テーマテンプレート内の画像を表示する方法としてget_stylesheet_uri関数を使用してきました。こういう感じですね。

<img class="site-banner"
   src="<?php echo get_stylesheet_directory_uri(); ?>/img/site-banner.png"
   alt="<?php bloginfo( 'name' ); ?>"
>

get_stylesheet_directory_uri()と書いてから、ディレクトリを続けて書いてファイル名。これで当サイトならimgのsrcプロパティは下記のように出力されます。

https://autumnsky.jp/wp-contents/themes/shirohanada/img/site-banner.png

ですが、レスポンシブ対応で複数の画像を指定する際は、この方法だと少し読みにくいように感じます。
最近だと画像やアイコンをassetsフォルダの中に、さらに分類していたりするのでパス指定も長くなりがちです。
参考: レスポンシブ画像の作り方 – 解像度の切り替え: 同じサイズ、異なる解像度  Mozzila

<img class="site-banner"
src="<?php echo get_stylesheet_directory_uri(); ?>/assets/img/site-banner.png"
srcset="<?php echo get_stylesheet_directory_uri(); ?>/assets/img/site-banner.png x1,
<?php echo get_stylesheet_directory_uri(); ?>/assets/img/site-banner@x2.png x2"
alt="<?php bloginfo( 'name' ); ?>" >

このように、すこし読みにくいように思います。

そこで、WordPress4.7以降で追加された get_theme_file_uri関数を使います。

<?php echo get_theme_file_uri( "/img/site-banner.png" ); ?>

get_theme_file_uri関数は<?php  ?>の後ろに書いていたファイルパスを引数として()内に指定できます。
上記のコードは、get_stylesheet_directory_uri関数を使った時と同じように下記の通り出力されます。

https://autumnsky.jp/wp-contents/themes/shirohanada/img/site-banner.png

srcsetプロパティを指定する際に
get_theme_file_uri関数を使うと、このように書き換えられます。

<img class="site-banner"
   src="<?php echo get_theme_file_uri( "/assets/img/site-banner.png" ); ?>"
   srcset="<?php echo get_theme_file_uri( "/assets/img/site-banner.png" ); ?> x1,
   <?php echo get_theme_file_uri( "/assets/img/site-banner@x2.png" ); ?> x2"
   alt="<?php bloginfo( 'name' ); ?>"
>

get_stylesheet_directory_uriを使うよりもスッキリと書けます。

参考にしたサイト

コミット時にWordPressコーディング規約に自動的に準拠させる方法

GitにはGitフックという仕組みがあります。
Git Documentation 8.3より

Gitのカスタマイズ ー Git フック
Gitにも特定のアクションが発生した時にカスタムスクリプトを叩く方法があります。

これを使って、WordPressのコーディング規約に準拠するようPHP/CSSをコミット時に自動修正します。
また、チェックにパスできない場合はコミットできないようにもなります。
コードのチェックにはPHP Code Snifferを使います。
さらに、Code Snifferが参照するWordPressのコーディング規約
WordPress-Coding-Standards
参考として、大元になるWordPressのコーディング規約集
WordPress コーディング規約 WordPress Codex 日本語版

PHP Code Snifferのインストールと設定

ローカルでPHPの実行環境が必要になりますので、インストールしておいて下さい。
WindowsでのPHP単体インストールは当サイトに記事があります。
参照:PHP7を単体でインストールする
Code Snifferをインストールします。
Composerでも行けるし、公式のGitHubにあるようにcurlwgetでダウンロードでもいいです。

ファイルを入れるだけで動かせます、binフォルダ内のphpcsを実行してバージョンを確認してみます。

$ phpcs/bin/phpcs --version

PHPCSの動作確認
別途、WordPress用のルールセットWordPress-Coding-Standardsをダウンロードしておきます。
今回はルールセットをwpcsフォルダにダウンロードしています。
このフォルダを下記コマンドでCode Snifferのinstalled_pathsに登録します。

$ phpcs/bin/phpcs --config-set installed_paths .\wpcs

コマンドラインで単体ファイルの修正とチェックを行ってみます。

$ phpcs/bin/phpcs --standard=wordpress front-page.php

PHPCSでコードをチェック
2箇所のエラーがありますね。

49行目
「次の関数はエスケープ処理を行うべきです(Codexの『データバリデーション』を参照)、’get_first_post_year’」
50行目
「関数呼び出しの閉じ括弧の後ろのスペースは禁止されています」
最後に
「マークされた1件の違反は、PHPCBFで自動修正が可能です」

50行目は自動修正が可能なようですので、CodeSnifferのphpcbfツールで修正します。

$ phpcs/bin/phpcbf --standard=wordpress front-page.php

PHPCBFにて自動修正
1カ所が修正されました。
もう一度、phpcsでチェックしてみます。
PHPCSで2回目のチェック
50行目のエラーが修正されたので、エスケープ処理がされていないエラーだけ残っています。
こちらは適切なエスケープ処理を書いてやる必要があります。
エラー処理前のコードは下図の通りです。50行目のhome_url()の直後だけ余計なスペースがあります。
また、get_first_post_year関数はfunctions.phpで定義している、年号を返す関数なのでエスケープ処理が必要です。
intvalにて整数型へキャストするようにWordPress Codexに記載があります。
PHPCSでエラーになる例

git hooksファイルの作成

先に試した修正とチェックをコミット前に行うよう、git hooksにスクリプトを書きます。
ローカルリポジトリの.git/hooks/にサンプルがあります。
中身はシェルスクリプトです。簡単に使い方など書いてあります。
githooksのフォルダ
ファイル名から.sampleを削除すると、該当するgitの処理が走る時に実行されます。
今回、pre-commitとして、このようなスクリプトを配置します。

#!/bin/sh
IS_ERROR=0
# コミットされるファイルのうち、.phpかcssで終わるもの
FILES=` git status --short | grep -E "^[M|A].*(.css|.php)$" | cut -c4-`
for FILE in $FILES
do
    ./phpcs/bin/phpcbf --standard=wordpress $FILE
    if ! ./phpcs/bin/phpcs --standard=wordpress $FILE ; then
        ./phpcs/bin/phpcs --standard=wordpress $FILE
        IS_ERROR=1
    else
        git add $FILE
    fi
done
exit $IS_ERROR

スクリプトの処理内容は、下記の通り。

  1. git addされたファイルから拡張子がphpかcssのファイル名を取り出す
    → FILES変数へ格納する
  2. 取り出したファイル一つずつに対し、自動修正をかける
    for FILES in $FILE do 内の処理
  3. さらに、そのファイルにCodeSnifferでチェックを行う
  4. エラーがなかったファイルは、git addでステージングし直す。
  5. エラーコードを返して終了

動作確認

git commitしてみます。
pre-commitフックはコミットメッセージを書くためのエディタが立ち上がる直前に実行されます。
githooksからPHPCSを走らせる
先ほどのように修正してチェックが実行されています。
エスケープ処理は自分で書かなくてはいけないので、エラーで終わっています。
この場合、エディタが起動しません。
SourceTreeからコミットしようとしてもこの通り。
SourceTreeからもgithooksは実行される
また、下記のように「手動で調査が必要」というアラートが出ることがあります。

Detected access of super global var $_POST, probably needs manual inspection.

手動での調査が必要なエラー
コードが規約に準拠していてもアラートが出て、エラーコード1となってしまうため、githooksでCodeSnifferが走る限りコミットできなくなります。
ルールセットの修正などで対応できるのだと思いますが、私は一度エラーメッセージを確認したらバイパスしてコミットしています。  githooksをバイパスする
gitコマンドではgit commit --no-verifyでバイパスできます。
さらにShirohanadaテーマはTravisCIでもCodeSnifferを実行するようにしています。
チェック後にテーマをビルドするので、規約違反のコードはデプロイされません。
(設定はローカルと違って、Warningは可としています)
TravisCIでのチェックログ

やってはいけないことは、できないようにしておく

例えば工場のプレス機など、プレスをするスイッチは両手で同時押しになっています。
手を挟まないように、両手が安全な位置になければ動作しない構造にしているわけです。
(それでも労働災害は、起きるときは起きる)
危険が伴う作業や現場、機械には、さまざまな安全装置があり原則があります。
有名なところでは「フェイル・セーフ」という原則があります。
例えば鉄道はブレーキの信号線が断線すると自動的に非常ブレーキがかかります。
安全に関わる原則の内「やってはいけないことは、できなくしておく」ことは「フール・プルーフ」という原則に含まれます。
私はデスクワークやコーディングも、このような原則を積極的に取り入れるべきだと思います。
今回紹介したように、コミット時とビルド時に自動修正をかけた上でチェックする仕組みを整えておけば、コーディング規約に準拠するコードだけがコミットされていきます。
こういった「安全確認」は本来やりたいこと、やるべきことに対する付随作業です。
また、コーディング規約の準拠は、手作業でやるには煩雑で、目視では間違えやすいところです。
たった一つの丸括弧の後ろの空白を、手作業で探すのは非現実的ではないでしょうか。
なので、機械に任せてしまう方が楽で確実です。

参考

gitのpre-commit hookを使って、綺麗なPHPファイルしかコミットできないようにする MANA-DOT
フェイルセーフとフールプルーフ~意味の違いと事例 レジリエントメディカル より安全な医療システムを実現する

WockerでWordmoveを使う

Wockerバージョン1.3にてWordmoveが実装されました。


今回はWordmoveをつかって、このブログのテーマをWocker内のWordPressに反映させてみます。
Wordmoveを使うと、PC内の開発用WordPressとサーバの本番環境のWordPressをコマンド一つで「同期」できます。
公式サイトでは「自動的なミラー」(複製)と書いています。

Wordmove is a gem that lets you automatically mirror local WordPress installations and DB data back and forth from your local development machine to the remote server.

Wocker自体の使い方は、公式サイトwocker.ioを参照して下さい。
Windowsでの使い方は当ブログに解説記事があります。WindowsでWockerを使う ― Autumnsky

ローカルのフォルダ構成、リモートの構成

作業前にローカルのフォルダ構成と、サーバ側のWordPressの設定を確認します。
当方ではDドライブ内にwockerのフォルダを作っています。
下記のコマンドでtest-wordmoveというコンテナを作りました。

$ wocker run --name test-wordmove

ローカルのWordPressが入っているフォルダはD:\wocker\data\test-wordmoveとなります。
wocker start test-wordmoveコマンドで、このフォルダ内のWordPressがPCで実行されます。
当ブログはさくらのレンタルサーバ スタンダードプランに構築されています。
サーバ側のWordPressは別途フォルダを作ってwordpress内にインストールしていますので、

WordPress アドレス (URL): https://autumnsky.jp
サイトアドレス: https://autumnsky.jp

上記の通りになっています。

Wordmoveのmovefile.ymlを生成する

ローカルのWordPressの設定、本番環境が動いているサーバの設定、等の設定をmovefile.ymlに記載します。
movefile.ymlに記載された設定を元に、Wordmoveは同期を行います。
.ymlは、YAML(ヤメル)というデータ形式のファイルです。私は「ヤムル」と読んでいます。
ローカルのWocker内には、初期状態ではmovefile.ymlはありません。
まず、Wockerコマンドでmovefile.ymlを生成します。

$ wocker wordmove init

result_wordmove_init
movefile.ymlが作成されました。テキストエディタで開いてみます。
(Windowsではメモ帳は使わないで下さい。)created_movefile
この時点で、Wocker内のWordPressは設定済みです。
下記のglobal:からproduction:の手前までの部分。
movefile_global_section

global:
  sql_adapter: wpcli # default is not available for Wocker
local:
  vhost: http://wocker.test
  wordpress_path: /var/www/wordpress # use an absolute path here
  database:
    name: wordpress
    user: wordpress
    password: "wordpress" # could be blank, so always use quotes around
    host: localhost

movefile.ymlを編集する

先に生成したymlファイルに本番環境(サーバー側、リモート)の設定を書いていきます。
production:以下、インデントが一つ下がっている項目は、サーバー側の本番環境の設定項目です。
例えば、database以下はproduction(本番環境)のデータベース設定です。databaseのname、databaseのuser、databaseのpasswordと設定が必要です。
これを本番環境のサーバー設定に書き換えていきます。
WordPressの設定、wp-config.phpとmovefile.ymlの設定を対応させると下図のようになります。
サーバ側 WordPress 4.9.2 / ローカル Wocker v1.3 の場合
prodction_server_settings
書き換え後の例

production:
  vhost: https://autumnsky.jp
  wordpress_path: /home/autumnsky/www/wordpress
  database:
    name: wp-config.phpからコピー
    user: wp-config.phpからコピー
    password: wp-configからコピー
    host: wp-configからコピー
    # port: 3308 # Use just in case you have exotic server config
    # mysqldump_options: --max_allowed_packet=1G # Only available if using SSH

vhost:は最後のスラッシュは書きません。リモートのデータベースをローカルへプルした際、データベース内にあるproduction: vhostのURLをlocal: vhostの文字列に書き換えています。サーバー側とローカルで、サイトURLが変わるため、URLを書き換えなければローカルのWordPressが正しく動きません。
正確に記載されていないと、書き換えに失敗します。
production:以下のwordpress_pathはサーバー側のWordPressを設置しているパス(フォルダ)の指定です。

サーバーのテーマフォルダをプル

それではサーバのテーマをローカルのWockerに引っ張ってみます。
今回はSSHという接続を使います。

SSH(Secure Shell) とは、物理的に遠いところから、サーバを操るための手段のひとつです。
さくらのレンタルサーバ SSHについて

SSHでの接続設定はサーバごとに異なりますので、各自ご確認下さい。
まず、先と同様にmovefile.ymlのSSH項目の設定を書きます。
SSHの設定は初期状態ではコメントアウトされているので、#を半角スペース2個で置き換えます。
左が編集前、右がコメントアウトを外した状態です。
下記の画像では分かりやすいように、エディタの設定でスペースを_で可視化しています。
enable_ssh
さくらレンタルサーバなら、hostとuser設定だけでもOKです。wordmoveする都度、パスワードを入れる必要がありますが。
インデントの半角スペースの個数、インデントの段数に気をつけて下さい。
YAML形式のインデントは半角スペース2個です。
このインデントの深さがデータの階層構造に対応します。
movefile.ymlは下記のツリーのような階層構造となっています。

movefile.yml
├─ local:(PCのローカルWordPressの情報)
│   ├─ vhost: http://wocker.test (サイトURLはwocker.test)
│   ├─ wordpress_path: /var/www/wordpress # use an absolute path here
│   └─ database:(ローカルのデータベース設定)
│        ├─ name: wordpress
│        ├─ user: wordpress
│        ├─ password: "wordpress" # could be blank, so always use quotes around
│        └─ host: localhost
│
└─ production:(本番環境のサーバ、WordPressの情報)
    ├─ vhost: http://example.com (本番環境のサイトURL)
    ├─ wordpress_path: /var/www/your_site (本番環境のサーバー内のパス)
    ├─ database: (本番環境のデータベース設定)
    │   ├─ name: database_name
    │   └─ ...
    ├─ exclude (除外ファイル)
    ├─ ftp (本番環境へのFTP接続の設定)
    ├─ ssh (本番環境へのSSH接続の設定)
    └─ ...

WordmoveはRubyで書かれています。YAML形式はRubyの構文に近いです。インデントが空白2個で文法上の意味があるのも、Rubyと同じです。WordPressはPHPなので、随分と勝手が違いますね。
ではいよいよWordmoveコマンドでテーマを取得します。
その前に

  • 注意 サーバーに存在しないテーマは、ローカルのフォルダから削除されます!

サーバー側にないファイルは、一旦待避してください。
では実行します。

$ wocker wordmove pull -t

pullはサーバー側のファイルを引っ張ってくる、-t はテーマのみとする指定です。
実行結果はこのようになります。
success_pulling
success_download
movefile.ymlが読み込めない時は、下記のようにRuby実行環境がエラーを出します。
yaml_parse_error
「あるべきはずの設定値が見つからなかった」という意味ですね。
この場合は「28行目を含むブロックを解析中に見つかりませんでした」とのことです。
(黄色背景の強調表示は筆者が独自につけています。)
YAMLファイルの書き方が正しいかチェックしてくれるWEBサービスもあります。
例)YAML フォーマットチェッカーCGI

プルしたテーマを確認する

Wordmove pullは、サーバー側とローカル側のテーマフォルダを完全に同期します。
サーバー側に存在しないテーマをローカルで使っている場合など、wocker.testを開くとホームは真っ白になる場合があります、
http://wocker.test/wp-login.phpからダッシュボードにログインして、テーマを確認します。
after_pulling
左側のスクリーンショットが空白のテーマが選択されています。
当サイトはWordPress4.9.2のデフォルトテーマであるTwentySeventeenを入れていないため、ローカルのWockerから削除されています。
右側のShirohanadaを有効化します。
WockerでShirohanadaテーマが表示されました。
mytheme_in_wocker

おわりに

今回はプルしか試していませんが、もちろんプッシュも可能です。
また、Wocker V1.3では若干、制限があります。

  • 公開鍵認証を使ったSSH接続
    できると思いますが、Wockerのコンテナ内にid_rsaファイルを設置する必要があります。
  • FTP接続
    FTP接続は今のところできません。これもWockerのコンテナの設定で出来るようになります。

多少の制約もありますが、使いやすく実装できていると思います。
是非活用して下さい。
movefile.ymlの書き方については、こちらを参考にしました。
Wordmove の正しい設定方法 Qiita @miya0001

WordPressのカテゴリーに「カスタムフィールド」を設定する

当サイトのテーマShirohanadaはカテゴリー表示の時、全文表示と抜粋表示を切り換える機能を実装している。
この抜粋・全文の表示フラグ、構想当初は「カスタムフィールドで保持して読み書きすればいいだろう」と考えていた。 投稿に対するカスタムフィールドはget_post_meta()などで取得する。多分、なんか楽にできる仕掛けがあるだろう、と。
結果、「カスタムフィールド」ではなく、theme_modで実装しました。その紆余曲折とtheme_modについての記事です。

wp_optionsテーブルがカオス

「カテゴリー カスタムフィールド」なんかでググったところget_options関数を使う例がいくつかみられた。
「これだこれだ、wp_optionsテーブルに入れてget_optionsで取得するのね。さてどういう感じで入れようかね」とコードを書いていたら何か上手く行ったり行かなかったり。
データベースの方はどうなってるんだ?というわけでphpmyadminでwp_optionsテーブルを見ると…
レコード番号が物凄い値になってる…(まあIDの連番がすごい数になってるぐらいは、どうということはないはず)
当サイトのwp_options スクリーンショット

「カスタムフィールド」とは何か?

改めてカスタムフィールドやデータベースについて、WordPress Codexの説明を読む。

WordPress には、投稿者が投稿に「カスタムフィールド」を追加できる機能があります。
WordPress Codex カスタムフィールドの使い方

このカスタムフィールドはpost_metaというテーブルに保存される。post_metaは投稿に対して付加されるので、カテゴリー番号やカテゴリー名でセットすることができないのだ。
WordPress Codexデータベース構造によると…

wp_postmeta
メタデータという各投稿記事特有の情報を格納。カスタムフィールドとして使用するほか、各投稿に情報や設定を付加するようなプラグインが、その情報を当テーブルに追加することがある。
wp_options
管理 > 設定で設定されたオプション設定情報を格納(オプション設定リファレンス参照)。プラグインの設定情報が格納されることも多い。

カスタムフィールドというのは、基本的に「投稿」を拡張する仕組みであって、カテゴリー単位の設定情報とかを保存する仕組みではない。
ならば、まさにwp_optionsを使うところなのだが……
どうも過去に使っていたプラグインの一時データやら設定やらで膨れあがっている。
そうするとテーマが削除されるタイミングをフックして、関係するレコードは削除しなくてはならないなあ……
カテゴリーが増えてきたら、沢山のプラグインと同居したら、きちんとレコードから「ウチのテーマの抜粋表示・全文表示フラグ」を取れるんだろうか、正しく書き込めるだろうか……

theme_modsレコード

wp_optionsテーブルを眺めていたら、mods_twentyelevenやtwelveなるレコードがある。
もしかして、枠線の色を変えたりとかTwenty系テーマのカスタマイズ値はここに格納されているのだろうか?
テーマ名を含むレコードのphp my admin のスクリーンショット

テーマカスタマイズ API
テーマ設定を取得し、ヘッダーにCSSを出力します。 上記のように customize_register アクションでテーマ設定を追加したなら、wp_head アクションで CSS を出力したり、get_theme_mod() / en で設定値を取得するだけです。

正解。これだ。
テーマをカスタマイズしたら、wp_optionsテーブルの
theme_mods_[テーマ名] レコードにキーと値が格納されているので、get_theme_mod(‘Key’, default)で取得してテンプレートやCSS、Javascriptで煮るなる焼くなりしている。

get/set メソッドで簡単に使える

set_theme_mod( $name, $value )
抜粋表示フラグをセットする。
cat_を接頭辞にしてカテゴリー番号を使ってキーを作成する。キーと値との組を引数にしてset関数実行。

$cat_id = "cat_$term_id";
if ( 'yes' === $flag ) {
  set_theme_mod( $cat_id, true );
} else {
  set_theme_mod( $cat_id, false );
}

get_theme_mod( $name, $default )
抜粋表示フラグを取り出す時は、同じくカテゴリー番号からキーを作ってget関数を実行。

$key = 'cat_' . get_query_var( 'cat' );
$is_show_excerpt = get_theme_mod( $key );

シンプル!
theme_modsレコードがない時はWordPressコアの方で上手いことやってくれると思います(未検証)
wp_optionsテーブルのtheme_mods_shirohanadaレコードに格納されている値はこんな感じ。

a:9:
{
  i:0;
  b:0;
  s:81:"https://autumnsky.jp/wp-content/uploads/2016/11/161029-web.jpg";
  s:17:"header_image_data";
  O:8:"stdClass":5:
    {
    s:13:"attachment_id";
    i:15747;
    /* このへんカスタムヘッダー関係の設定値. */
    s:6:"height";
    i:700;
    s:5:"width";
    i:700;
    }
  /* set_theme_mod()でセットした値. */
  s:6:"cat_10";
  b:1;
  s:7:"cat_269";
  b:0;
  s:7:"cat_157";
  b:0;
  s:7:"cat_253";
  b:1;
}

外観のカスタマイズ用ということもあって、かなり大量の要素を扱えるようになっているみたいです。
本来の用途はダッシュボード > 外観 > カスタマイズ で設定した値を簡単に保存・読出するための関数です。
ダッシュボード > 外観 > カスタマイズ スクリーンショット
この画面の左側、カスタマイズ項目を自由に追加するために用意されている関数・クラスです。本来の使い方はテーマカスタマイズ APIを参考にして下さい。私もあまりよく分かっていません。

まとめ

テーマ固有の値を保持したいときは、WordPressのtheme_mod関係の関数を使って簡単にできます。
投稿の抜粋・全文の表示の制御など、プラグインでやることじゃないか?
と思いましたが、しかし、どちらにも対応したテンプレート構造・CSSを用意しないといけないので、Shirohanadaではテーマ側で実装しています。
結局、カスタムフィールドとwp_optionsは使ってませんが、タイトルはあえて「カスタムフィールド」としました。

さくらインターネット+PHP7.1+WordPress

さくらのレンタルサーバ PHP7.1 提供開始のお知らせ 2016年12月14日

早速、当サイトも切り替えてみました。

WordPressの互換性

最新版である4.7ではPHPの推奨バージョンは7.0以上である。
動作は5.2.4以上で確認されているが、4.4~5.4は既にEOLで開発終了。
このサイトはPHP5.6でWordPressを走らせていました。
よって、WordPressコアはPHP7.0にアップデートして問題ない。
自作テーマもこの時に備えてPHP7.0でテスト済み。
プラグインは…まあ大丈夫だろう!
TravisCIスクリーンショット

設定方法

というわけで、PHP5.6 -> 7.1へ変更してみる。

  1. サーバーコントロールパネルにログイン
  2. PHPのバージョン選択 -> 新しいバージョン
  3. PHP 7.1を選ぶ

以上。
さくらインターネット PHP7設定

速度

WordPressのダッシュボード画面で速度を計測しました。
Firefoxのツール -> Web開発 -> ネットワーク でレスポンス速度など計測できます。
上がPHP5.6の時、下がPHP7.1の時。
Firefox ネットワークのスクリーンショット
比較しやすいよう、1.28秒のラインを揃えてみました。
ダッシュボードでの速度比較 グラフ
9.34秒かかっていたダッシュボードの表示が、3.27秒です。速い!
「WordPressをHHVM(Facebookが開発したすごい速いPHP実行環境)で実行するとダッシュボードが一瞬で開く」「PHP7はHHVMに匹敵する処理速度になる」とのことでした。PHP開発元によるWordPressのベンチマークでもほぼ同等。


WordPressの弱点「読込が重い」という点が、あっさり改善しました。
なんでもPHP本体の開発陣もWordPressでのパフォーマンスは注視しているそうで、ありがたい限りです。
ふと思ったのですが、4.7から標準機能になったWordPress REST APIは「PHP7の処理速度ならいける」という目算かも知れないですね。

front-page.phpを使うテーマテンプレートで「最新の投稿」を表示

front-page.phpにてホームを固定ページにしていると、「最新の記事」を表示する方法がないことに、はたと気づいて方法を調べた。
WordPressのテンプレート呼び出し順序の関係で、front-page.phpファイルがあると、それが最優先となる。
ダッシュボードからの設定よりもファイル構成の方が優先されます。
index.phpを使った「最新の投稿」を表示させる方法はあるのか…さて…?

設定方法

方法はありました。

  1. 中身が空の「固定ページ」を作成
  2. 1.で作った固定ページを「投稿ページ」として表示するよう設定

以上、2ステップです。

1. 固定ページ作成

ダッシュボードから固定ページを作ります、タイトルなどは自由につけて構わないです。
パーマリンクは、WordPressの表示変更をした際に強制的に変更されます。
投稿の中身は空欄としておきます。
latest-page

2. 設定 > 表示設定で「投稿ページ」を設定

デフォルトではこのように、「フロントページの表示」は「最新の投稿」になっているはずです。
options-reading-before

ここを「固定ページ」をチェック。
フロントページ:今回は「About for root」を指定。front-page.phpは、ここの設定にかかわらず優先で表示される。
投稿ページ:先ほど作った「Latest」固定ページを選択。
「変更を保存」
options-reading-after

3. 表示の確認

ダッシュボードの「固定ページ」管理画面へ戻ってみます。
「Latest -投稿ページ」となっています。
pages-after
blog-page-after
これで、パーマリンク blog/ で「最新の投稿」が表示されるようになりました。
当サイトではhttps://autumnsky.jp/blog/となります。
blog-entry

そもそも何をどうしたかったのか?

このサイト…というかこのテーマのフロントページは、固定のfront-page.phpにてページを作っている。
Shirohanadaテーマのフロントページは下図のように、「カスタムメニュー」と「ウィジェット」エリアを設定している。
front-page
これにより、コンテンツへのリンクがダッシュボードから柔軟に構築できる……
のであるが、「最新の投稿」リンクはメニューのカスタマイズからは選べない。
また、月ごとのアーカイブへもカスタムリンクを使うしかないようだ。
customize-menu
しかし、「最新の投稿」はきちんとWordPressの機能でカバーする方法が用意されていました。
若干面倒ですが、テンプレート構成を変更することなく「最新の投稿」表示ができました。