ホーム > WordPress

WordPress アーカイブ

WordPress の連載が始まりました

お久しぶりです。僕です。
連載:WordPress解体新書|gihyo.jp … 技術評論社 という WordPress の運用面に関する連載を始めました。開発面に関する連載も今週開始予定です。
掘り下げる、というよりは積み上げていって WordPress を理解するような内容ですので長くなる予定です。
こういったところに連載を始めたからにはもうちんことかうんことか言っていられませんね。

名残惜しいですが一句詠みたいと思います。
玉袋に 全て隠れる 冬の朝

本当にありがとうございました。

Wordpress プラグイン開発に役立つ小さなテクニックと気をつけるべき点

間違ってたらご指摘頂けると助かります。

  1. wp_enqueue_script() でバージョン指定するときに mktime() と書くと毎回ちゃんと更新されててよろしい。wp_enqueue_style() も然り。
  2. プラグインファイルで直接メソッドや関数を呼び出さず、アクションにフックした方がいい。
  3. plugin_loaded アクションが最初に呼び出される。URI の解析なんかよりも前に呼ばれる。
  4. Wordpress コアの前処理が終わった後に実行されるのは init アクション。通常はこっちを使う。
  5. admin_notices アクションで echo すると「投稿を保存しました。」みたいなメッセージ表示が出来る。div.error で括ればエラー表示が出来る。
  6. Wordpress コアに標準搭載されてる jQuery よりも新しい jQuery が使いたいときは init アクションとかにフックして wp_deregister_script( ‘jquery’ ); をしてから wp_enqueue_script() で登録しなおす。
  7. 管理画面のサイドバーに表示されてるメニューのサブメニューに項目追加したい場合は add_submenu_page() を使う。init アクションとかに無名関数をフックしてそこから呼び出すと無駄がない。
  8. $wpdb->prepare() は sprintf() のラッパー。エスケープは addslashes() だけど UTF-8 だから問題ないと思う。
  9. $wpdb->prepare() は %s と %d を拾って自動的にクォートしてくれる。%1$s とかじゃ駄目
  10. MySQL 4.0.27 未満だと UTF-8 での LIKE 句の処理にバグがあるので 4.0.27 未満の MySQL で運用する Wordpress の日本語検索は正しい結果が返ってこない。
  11. テスト環境とか似たような環境をいくつも用意する場合は mysqldump でデータベースコピーした方が早い。
  12. 管理画面用の admin-ajax.php に POST リクエストするときに独自アクションを追加するなら ‘wp_ajax_’.$_POST['action'] にフックする。
  13. admin-ajax.php を使うと最後に 0 が出力されるので、それがいやならばその前にスクリプトを停止させる。

たまったらまた書きます。

Wordpress に独自のテンプレートを追加する

自作のプラグインで生成するページが既存のテンプレートにマッチしなかったり、ページの種類によってテンプレートを変えたいなーなんて事、ありますよね。
page.php などの中でさらに分岐させても良いのですが、それではロジックとビューが混在してしまうためロジックがプラグインだったりするとテーマとプラグインに依存関係が生まれて使い勝手が悪くなってしまってイマイチです。

そんなときはフィルタ関数で呼び出すテンプレートファイルを変えてしまいましょう。
大体こんな感じ。

<?php
function pageSnacher( $template ){
    if( preg_match( '/^\/hoge$/', getenv( 'REQUEST_URI' ) ) )
        $template = TEMPLATEPATH . '/hoge.php';
    return $template;
}
add_filter( 'page_template', 'pageSnatcher' );
?>

URI が /hoge だった場合にテーマのディレクトリにある hoge.php がテンプレートファイルとして読み込まれます。
page_template は wp-includes/template-loader.php で is_page() が true を返したときに呼び出されるフックです。
よって、init フックとかで add_filter() しても意味がなかったりしますので気をつけてください。
それぞれのテンプレートで呼び出されるフックは wp-includes/theme.php 辺りを読めば大体わかると思います。

Wordpress におけるメタボックスの構造解説

Wordpress 2.5 辺りから整備されてきたメタボックス。2.7 にもなるとかなりシステマチックな構造となってきました。
このメタボックスの構造があるおかげで 2.7 からはユーザーごとに「表示オプション」という形でそれぞれのページでのメタボックスをコントロールできています。

さて、このメタボックス。プラグインでも存分にその機能を利用できます。設定項目が多岐に渡るようなプラグインの場合、設定画面の UI が煩雑になりがちです。
そんなときにこのメタボックスを利用する事で、すっきりとシステマチックな UI を設定画面に提供する事が出来ます。

使い方はいたって簡単。

  1. メタボックスの登録
  2. メタボックスの出力
  3. メタボックス状態の保存と復元

これだけです。

メタボックスの登録

<?php
add_meta_box( 'メタボックスの識別名', 'メタボックスのラベル', 'コールバック関数', 'ページ名', 'コンテキスト', '優先度');
?>

これがメタボックスを登録する関数です。
まず、第一引数にメタボックスの識別名を指定します。これは最終的にメタボックスを HTML として出力する際、一番外側の div 要素の id 属性として利用されますので、制限的には id 属性のそれに準じます。PHP 側ではハッシュのキーとして使われます。
同一のページ内で使うメタボックス同士で重複してはいけませんし、そもそも id 属性として利用されるので HTML 内で重複してもいけません。ユニーク性を強調するならば ‘プラグイン名_メタボックス識別名’ という様な構造がお手軽です。

次に第二引数。これはそのままメタボックスの上部に表示されるラベルです。それ以外に利用される事はありません。
また、この引数はそのまま HTML に出力されるので、タグを利用してメタボックスの表現に変化をもたせることが可能です。しかし、ラベルは span 要素で括られているためボックス要素を利用する事は出来ません。せいぜい <span class=”extra”>ラベル</span> とする程度にとどめた方がよいでしょう。

第三引数はコールバック関数です。後述する do_meta_boxes() でメタボックスの HTML が出力される際に呼び出されます。
つまりメタボックス内部の HTML を出力するための関数やメソッドを指定します。
例えば、コールバック関数に display_meta_box() を指定した場合 display_meta_box() では以下のようなコードを書きます。

<?php
function display_meta_box(){
?>
<label>今朝食べたもの<input type="text" name="breakfast" value="スパンコール丼" /></label>
<?php
}

call_user_func() で呼び出されますので、メソッドの場合は配列で指定します。

第四引数は ‘ページ名’ となっていますが、これはプラグインの URI には依存していません。自由です。
ページ名というよりはページの識別名と考えた方がよいかもしれません。後述する JavaScript 側でのコントロールにおいて重要な役割を持ちます。
プラグイン名を利用するのがベターでしょう。

第五引数のコンテキストは、要するに同一ページ内に複数列のレイアウトを組むような場合の識別名として利用します。
例えば以下のような HTML があったとします。

<div class="sidebar"></div>
<div class="body"></div>

sidebar と body にはそれぞれ別のメタボックスを出力したい、という様な場合にこのコンテキストで分類し、後述する do_meta_boxes() で区別して呼び出します。
指定しない場合は ‘advanced’ として扱われます。

最後の第六引数は優先度です。優先度は高い順に ‘high’, ’sorted’, ‘core’, ‘default’, ‘low’ となっており、これ以外の優先度を指定してしまうとメタボックスが出力されなくなってしまいますので気をつけてください。優先度が適用されるのは「メタボックスが呼び出される順番」です。プラグインの構造上出力したい順番にメタボックスの登録が出来ない場合などに力を発揮します。
指定しない場合は ‘default’ として扱われ、優先度が重複するメタボックス同士は登録された順に出力されていきます。

以上がメタボックスの登録関数について。

メタボックスの出力

次に登録したメタボックスを出力する関数である do_meta_boxes() についてです。

<?php
do_meta_boxes( 'ページ名', 'コンテキスト', 'コールバック関数に渡したい変数');
?>

第一引数と第二引数はそれぞれ add_meta_box() で指定したものと相関関係にあります。
呼び出した居場所で適時呼び出して下さい。

<div class="sidebar"><?php do_meta_boxes( 'pluginName', 'sidebar' )?></div>
<div class="body"><?php do_meta_boxes( 'pluginName', 'body' )?></div>

という様な具合です。
第三引数にはコールバック関数に渡したい変数を指定することが出来ます。
コールバック関数には二つの引数が渡されます。

function callbackFn( ‘do_meta_boxesから渡された変数’, ‘このコールバック関数を呼び出しているメタボックスの設定’ ) となっておりますので、例えば1種類のコールバック関数で複数のメタボックスを出力したい場合などには、第二引数で呼び出し元のメタボックスを評価し第一引数にある変数を使ってメタボックスを構成する、という様な利用方法が挙げられます。

メタボックス状態の保存と復元

ここまでは PHP のお話でしたが、このメタボックスは JavaScript によって折りたためたり、ドラッグして移動する事ができます。
これらの直感的な操作は wp-admin/js/postbox.js にそのスクリプトが書かれていますので、とりあえずこれを呼び出します。
postbox.js は規定のスクリプトとして登録されているので、呼び出しは wp_enqueue_script( ‘postbox’ ); で OK です。

呼び出そうと思っている本体のスクリプトの呼び出し名を知りたい場合は以下の URI を参照して下さい。
Function Reference/wp enqueue script « WordPress Codex

次におまじないを2行、JavaScript として追加します。

postboxes.add_postbox_toggles('ページ名');
jQuery('.if-js-closed').removeClass('if-js-closed').addClass('closed');

1行目はメタボックスのイベント登録をします。
また、メタボックスの状態を保存する際にどのページで出力されたメタボックスの情報であるかを識別するページ名を引数に渡します。
このページ名は前述の add_meta_box() で指定したページ名と同一のものを利用します。
これによって PHP 側で生成したメタボックスと、JavaScript 側で制御している表現の状態を結び付けます。
2行目はメタボックスが閉じられたものであると指定された場合に、そのメタボックスを予め閉じるための指示です。
PHP で生成されたメタボックスが閉じられる予定のものであった場合、class 属性に if-js-closed が指定されていますので、そのクラス名を closed に変えています。
これにより closed のスタイルが適用される事になります。

JavaScript によってメタボックスを閉じたり、移動した情報はその度にサーバにリクエストされます。
その際 nonce_field が無いと状態を保存してくれません。
ページ内のどこでもよいので nonce_field を出力しておきましょう。

<?php
wp_nonce_field( 'closedpostboxes', 'closedpostboxesnonce', false );
wp_nonce_field( 'meta-box-order', 'meta-box-order-nonce', false );
?>

これで OK です。
nonce_field の説明は長くなってしまうので機会があれば別エントリで言及しますが、これは簡単に言えばユーザーの権限評価も含めたワンタイムチケットです。

メタボックスが表示され、状態が保存されていれば全てはうまくいったという事です。
さほど複雑な構造ではないので是非利用してみて下さい。

参考

[Wordpress] 管理画面のメタボックス表示・非表示を切り替えるプラグイン

と言うプラグインを公開しました。
詳しくは管理画面のメタボックス表示・非表示を切り替えるプラグインへどうぞ。

ホーム > WordPress

カテゴリー

ページの上部に戻る