[WordPress] Hello Dolly で学ぶプラグイン作りの第一歩

WordPressユーザーのみなさん、WordPressに同梱されている公式プラグイン『Hello Dolly』は使ってますか?

なに、使ってない?

ですよねー。

だってこのプラグイン、説明書きを見ても

これはただのプラグインではありません。Louis Armstrong によって歌われた最も有名な二つの単語、Hello, Dolly に要約された同一世代のすべての人々の希望と情熱を象徴するものです。このプラグインが有効にされると、すべての管理画面の右上に Hello, Dolly からの歌詞がランダムに表示されます。

って書いてあるだけで、ルイ・アームストロングのファンじゃなかったらまるで使い道が見つからないわけですから。

大半のWordPressファンに「あんたはうちの子じゃありません!」的な扱いをされているであろう『Hello Dolly』。ですが、ソースをひらいてみるとおや驚き。ナニゲにPHPのプログラミングや、プラグイン制作の基本が学べるつくりになっているではありませんか。

そんなわけで、世界一有名でありながら世界一使われていない(想像)プラグイン『Hello Dolly』の救済企画、スタートであります。『Hello Dolly』を聞きながら気分あげていきましょー。

『Hello Dolly』がやっていること

『Hello Dolly』(バージョン1.6)のソースコードはトータル83行。うち、メタデータ(プラグインの名前や説明文など)で12行、ルイ・アームストロングの歌詞で28行を費やしているので、実質40行ほどしかコードがないプラグインです。

では、ソースを冒頭から追っていくとしましょう。プラグインでは下記のような処理をしています。

  1. 歌詞をフレーズごとに改行して並べる
  2. それぞれのフレーズを改行(\n)で区切って、配列に納める
  3. 配列の中から、要素(=フレーズ)をランダムに選ぶ
  4. WordPressが使っている言語が、左→右に文字の並ぶ言語(例:英語や日本語)か、右→左に文字の並ぶ言語(例:アラビア語やヘブライ語)かを判定する
  5. 4.の判定結果に合わせ、スタイル(floatとpadding)を決める
  6. 5.のスタイルをHTMLの head セクションに書き込む
  7. 3.で選ばれたフレーズを管理画面に表示し、5.のスタイルを適用する

歌詞をフレーズごとに改行して並べる

ソースの17行~44行がそれにあたります。

	$lyrics = "Hello, Dolly
Well, hello, Dolly
It's so nice to have you back where you belong
You're lookin' swell, Dolly
/*
 * 中略
 */
Dolly'll never go away
Dolly'll never go away
Dolly'll never go away again";

ご覧のとおり、適宜改行を入れながら並べているだけですね。ただしPHPの場合、歌詞のような〈文字列〉はシングルクオーテーション(’)か、ダブルクオーテーション(”)で両端をくくらないとエラーが出てしまいます。

歌詞には「You’re」「goin’」など、文字の省略を表す意味でシングルクオーテーションが使われています。なので、文字列の両端にシングルクオーテーションを打つと、歌詞の「’」が文字列のくくりと誤判定されてしまいます。歌詞がダブルクオーテーションでくくられているのは、誤判定を避けるため、 なんですね。

で、歌詞はいったん $lyrics という変数(文字列や数値を収めておく箱、みたいなもの)にまるっと入れられます。これを、変数への〈代入〉といいます。

それぞれのフレーズを改行(\n)で区切って、配列に納める

変数 $lyrics に入った歌詞は、そのままだとフレーズとして取り出せません。「1.の段階で改行しながら書いてたあったのになんで?」と思われるでしょうが、そこがコンピュータの融通の利かないところ。人間の目には〈区切り〉のように見えても、コンピュータにとっては改行も、文字の一種にしかすぎません。

そこで「この改行を〈フレーズの区切り〉として認識してね」と、コンピュータにおねがいすることにします。それが47行目の処理。

	$lyrics = explode( "\n", $lyrics );

explode とは、特定の文字(この例では〈改行〉を表す \n)を目印に文字列を分割し、配列 $lyrics に代入するPHPの命令です。配列? うん、また新しい言葉が出てきましたね。

配列も変数のように、文字列や数値を納めておく箱のようなものです。ただ変数とちょっと違うのは、箱の中身が仕切られていること。なので、explode 命令で分割された文字列(=フレーズ)を納めるには配列の方が好都合なのです。変数だと、フレーズの数だけ箱を用意しなければならず煩雑になっちゃいますからね。

47行目では2つの $lyrics が出てきていますが、左辺は配列、右辺にあるのは変数と、名前は同じでも箱の構造が実はまったく違うのです。

配列の中から、要素(=フレーズ)をランダムに選ぶ

50行目の処理がそれにあたります。

	return wptexturize( $lyrics[ mt_rand( 0, count( $lyrics ) - 1 ) ] );

いくつかの命令が並んだ行なので、処理をちょっとほどいてみると

  1. 配列内の要素(=箱の中の区画)の数をカウントする
  2. 1.の数を最大値として、いずれかの区画を乱数で選ぶ
  3. 2.の区画から文字列を取り出し、ある規則に沿って置換処理をかける
  4. 管理画面に表示させるための準備をする

1.に相当するのが、要素の数を count 命令で取得している

count( $lyrics ) - 1

の箇所です。なぜ -1 するのかというと、PHPの場合、要素には0から始まる連番(PHPでは〈添え字〉と呼びます)がふられているからなのですね。たとえば配列 $lyrics に5つの要素(区画)があるとすると

  • 1番目の要素……連番0($lyrics[0] と表記する 以下同様)
  • 2番目の要素……連番1
  • 3番目の要素……連番2
  • 4番目の要素……連番3
  • 5番目の要素……連番4

となり、要素数から -1 することで連番の最大値を取得できるということになります。『Hello Dolly』の歌詞は28行にわたっていましたから、要素の数は28、連番の最大値は27になるわけです。

では、1.で得た最大値(27)を生かして次の処理に進みましょう。乱数を使って連番(0~27)のいずれかを取得するのが mt_rand 命令です。

	$lyrics[ mt_rand( 0, count( $lyrics ) - 1 ) ]

これにより $lyrics[0]~$lylics[27] のどれかが選択されることになります。

これで表示すべきフレーズは一応確定したわけですが、『Hello Dolly』では、選択したフレーズ(文字列)にさらに処理をかけています(手順3.の「ある規則に沿って置換処理をかける」)。50行目の wptexturize 関数がそれにあたります。

	return wptexturize( $lyrics[ mt_rand( 0, count( $lyrics ) - 1 ) ] );

wptexturize 関数はCodexにあるように、記事中の特定の文字をよしなに置換してくれる関数です。『Hello Dolly』の場合、wptexturize 関数で置換されるような文字は歌詞に含まれていませんが、WordPressの作法として念のため処理を通しているのでしょう(正確な理由についてはわからないので、このあたりの事情についてご存じの方はぜひ教えてください)。自作のプラグインを作る際の参考になりそうですね。

[2015.10.13追記]
歌詞の中に、本来アポストロフィであるべきなのに、シングルクォーテーションになっている箇所があります。ここを wptexturize 関数を通して、本来のアポストロフィに変換してますね。


さて長くなりましたが、これでようやく歌詞を表示する準備が終わりました。このあと、スタイルまわりの処理に入っていきます。

WordPressが使っている言語を判定する

なにしろ世界シェアトップのブログ/CMSソフトですから、WordPressは世界中のさまざまな地域で使われています。その中には、右から左に向かって文を書いていくという、戦前の日本のような横書きをする言語圏(例:アラビア語やヘブライ語)があります。

日本語や英語のように左→右に書き進む方法を〈Left-to-Right(LTR)〉、逆に書き進む方法を〈Right-to-Left(RTL)〉といい、CodexにあるようにWordPress側でもしっかりと両者がサポートされています。

現在使っているWordPressがどちらの言語圏に属するものか判定しているのが、65行目の is_rtl 関数による処理です。

	$x = is_rtl() ? 'left' : 'right';

初心者の方にはなじみが薄いかもしれない記述ですが、これは〈三項演算子〉といい、別の書き方をするとこんな感じになります。

if ( is_rtl() ) {
	$x = 'left';
} else {
	$x = 'right';
}

つまり is_rtl が真(=RTLである)なら変数 $x の値が「left」、偽(=LTRである)なら「right」になるというわけです。

スタイル(float と padding)を決める

前項の $x が実はここで効いてきます。70行目・71行目を見てみましょう。

		float: $x;
		padding-$x: 15px;

勘のいい方ならお気づきかもしれませんね。実は前項の $x の値によって、70行目・71行目のCSSプロパティや値が動的に切り替わるようになっているのです。

  • RTL(右→左に書き進む)の場合
    70行目……float: left;
    71行目……padding-left: 15px;
  • LTR(左→右に書き進む)の場合
    70行目……float: right;
    71行目……padding-right: 15px;

もっとも、動的にスタイルが変わったところで、このままでは管理画面のスタイルに反映させることはできません。管理画面が表示される際、しかるべき位置に出力させてやる必要があります。そこで浮上するのが、WordPress側で用意されている「プラグインAPI」のアクションフックの存在なのです。

プラグイン制作に興味のある方なら一度は〈アクションフック〉という言葉を聞いたことがあるかもしれませんね。前振りがえらく長くなっちゃいましたが、ようやくプラグイン制作っぽい記事になってきました 🙂

HTMLの head セクションにスタイルを書き込む

プラグインAPIとは言い換えれば、WordPressにおける〈割り込み処理の受付窓口〉にあたるものです(誤解を恐れずにいうと)。

WordPress内部では、データベースに対して読み/書きするときや、表示すべきテンプレートがセットされたとき、記事本文が表示されるとき……などさまざまな場面に〈割り込み処理の受付窓口〉が設けられています。

WordPressの一連の処理は、これら多数の〈窓口〉でほんの一瞬だけストップし、外部に対して「割り込み処理をかけたいプログラムはありませんか?」と問い合わせをします。その際、プラグインのようなカスタマイズに関わるプログラムが「そこに割り込ませてくれ!」と応答すると、それを受け入れたうえで、続きの処理をしていきます。

で、上記をふまえてプラグイン『Hello Dolly』のコードを見てみると……80行目にこんな記述があります。

add_action( 'admin_head', 'dolly_css' );

これぞまさに、「そこに割り込ませてくれ!」と応答している箇所です。ちなみに、割り込ませる処理は冒頭に書いた

  1. WordPressが使っている言語が、左→右に文字の並ぶ言語(例:英語や日本語)か、右→左に文字の並ぶ言語(例:アラビア語やヘブライ語)かを判定する
  2. 4.の判定結果に合わせ、スタイル(floatとpadding)を決める
  3. 5.のスタイルをHTMLの head セクションに書き込む

の流れ。これらが hello_css() というかたまり(PHPではこれを〈関数〉といいます)となって63行目~78行目にまとめられています。ちなみに67行目の echo は、文字を出力するPHPの命令です。

「そこに割り込ませてくれ!」があるということは、「割り込み処理をかけたいプログラムはありませんか?」と問い合わせをしている箇所もどこかにあるということですよね。ソースを追いかけていったら、管理画面のテンプレートの一部となる wp-admin/admin-header.php の125行目(WordPress 4.1.1の場合)にこんなコードがありました。

do_action('admin_head');

そう。これこそ〈割り込み処理の受付窓口〉、つまりアクションフックの正体なんです。 改めてWordPressの用語に置き換えると

  • do_action……「割り込み処理をかけたいプログラムはありませんか?」という問い合わせ
  • add_action……「そこに割り込ませてくれ!」という応答

ということになります。

〈割り込み処理の受付窓口〉はWordPressのさまざまな場面に現れます。したがって、しかるべき箇所で割り込み(カスタマイズ)をかけないと思わぬ挙動を引き起こしかねません。ライヴコンサートでいうところの〈コールアンドレスポンス〉ってやつで、ここではその合い言葉が \admin_head/ になっているというわけです。80行目の add_action では、合い言葉を介して dolly_css() の処理を実行しているのですね。

フレーズを管理画面に表示し、スタイルを適用する

冒頭に書いた

  1. 歌詞をフレーズごとに改行して並べる
  2. それぞれのフレーズを改行(\n)で区切って、配列に納める
  3. 配列の中から、要素(=フレーズ)をランダムに選ぶ

の流れは、プラグイン『Hello Dolly』の15行目~51行目で hello_dolly_get_lyric() というかたまり(関数)にまとめられ、選ばれたフレーズが54行目~57行目の関数 hello_dolly() 内で呼び出されています。

function hello_dolly() {
	$chosen = hello_dolly_get_lyric();
	echo "<p id='dolly'>$chosen</p>";
}

hello_dolly() 内では

  • 選ばれたフレーズ(文字列)を変数 $chosen に代入する
  • 文字列 $chosen を p タグで挟んで出力する(p タグには id=”dolly” を付記)

という処理を行っています。 ここまでくれば前項と同様の処理です。『Hello Dolly』の60行目を見てみると

add_action( 'admin_notices', 'hello_dolly' );

合い言葉は \admin_notices/ ですね。さあ、admin_noticeはどこにあるのでしょうか……ありました! wp-admin/admin-header.php の239行目です。

	do_action('admin_notices');

出力された文字列(フレーズ)には id=”dolly” が付記されているので、head セクションに書き込まれたスタイルが適用され、たとえばWordPressがLTRの設定の場合はフレーズが float: right; (右寄せ)で表示されることになります。

ちなみに管理画面のHTML内で出力されるのは id=”wpbody-content” がふられたボックスの内部です。

今一度 wp-admin/admin-header.php を見てみると

<div id="wpbody-content" aria-label="<?php esc_attr_e('Main content'); ?>" tabindex="0">
<?php

// 中略

	do_action('admin_notices');

となっていて、id=”wpbody-content” のボックス内で do_action が実行されていることがわかります。

以上、世界一有名なのに世界一ないがしろにされているプラグイン『Hello Dolly』(感想には個人差があります)の中身を見てみました。「PHPのプログラミングはこれから……」という方は、ルイ・アームストロングの歌詞の代わりに自分の好きな詩や格言などを入れて改造するところから始めてみるのもよいかもしれません。

「[WordPress] Hello Dolly で学ぶプラグイン作りの第一歩」への2件のフィードバック

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です