WordPressでカスタムフィールドをお手軽に実装できるクラスライブラリ「WPAlchemy MetaBox」
Wordpressのカスタムフィールド(メタボックス)を使いやすくするプラグインが多くありますが、GUIで簡単に設定できる反面カスタマイズがするのが大変だったりします。
でも一から実装するのはだるいよね。というときに便利かもしれないクラスライブラリ「WPAlchemy MetaBox PHP Class」をご紹介します。
2011.12.06 「管理画面から項目の追加&削除を行う」の項目を追加しました。
ライブラリのダウンロード
ソースはGitHubにあります。以下からダウンロードしてください。
farinspace/wpalchemy
ここでは現在最新の「1.4.15」をダウンロードします。
Wordpressのバージョンは「3.2.1」です。
ダウンロードしたファイルを解凍すると「wp-content」の中に「wpalchemy」フォルダがあるので、Wordpressがインストールしてある「wp-content」フォルダに入れます。
これでとりあえず準備完了です。
シンプルなカスタムフィールド
現在使用しているテーマフォルダにカスタムフィールド用のフォルダを作成して、その中にファイルを作成します。
ここでは「metaboxes」というフォルダの中に「setup.php」と「metabox.php」を作成しました。
また、ダウンロードしたファイルの中にcssファイルがありますので同じ階層にいれておきましょう。
場所は「wp-content」→「themes」→「mytheme」→「metaboxes」→「meta.css」です。

「setup.php」で各種設定をします。
setup.php
include_once WP_CONTENT_DIR . '/wpalchemy/MetaBox.php';
if (is_admin()) wp_enqueue_style('wpalchemy-metabox', get_stylesheet_directory_uri() . '/metaboxes/meta.css');
$custom_metabox = $simple_mb = new WPAlchemy_MetaBox(array
(
'id' => '_custom_meta',
'title' => 'カスタムフィールド',
'template' => get_stylesheet_directory() . '/metaboxes/metabox.php'
));
「title」はカスタムフィールドのボックスのタイトル。
「template」は表示するテンプレートファイルを指定します。ここでは「metabox.php」ですね。
カスタム投稿タイプで使用したいときは「’types’ => array(‘hoge’)」で指定します。何も指定しないと「投稿」と「ページ」に追加されます。
「template」で指定した「metabox.php」を編集することで投稿画面にフィールドを追加できます。
metabox.php
<div class="my_meta_control">
<label>サブタイトル</label>
<p>
<?php $mb->the_field('title'); ?>
<input type="text" name="<?php $mb->the_name(); ?>" value="<?php $mb->the_value(); ?>"/>
</p>
<label>説明</label>
<p>
<?php $mb->the_field('description'); ?>
<textarea name="<?php $mb->the_name(); ?>" rows="3"><?php $mb->the_value(); ?></textarea>
</p>
</div>
htmlベースなので結構自由にできるのではないでしょうか。
最後に「setup.php」を「functions.php」から読み込みます。
functions.php
include_once 'metaboxes/setup.php';
これだけでオリジナルのカスタムフィールドが作成されます。
保存とかもしてくれますよ。

テンプレートの表示
データベースには各フィールドの値がセットになって保存されてますので「get_post_meta」で取得して表示します。
ループ表示するときはこんな感じですね。
template file
<?php if (have_posts()) : while (have_posts()) : the_post(); ?>
<?php
$meta = get_post_meta(get_the_ID(), $custom_metabox->get_the_id(), TRUE);
echo $meta['title']. "<br />";
echo $meta['description'];
?>
<?php endwhile; ?>
<?php else: ?>
<p><?php _e('no post'); ?></p>
<?php endif; ?>
画像のカスタムフィールドを追加する
次は画像のカスタムフィールドを作成します。「MetaBox.php」と一緒にダウンロードした「MediaAccess.php」が画像関係のライブラリになります。
「setup.php」を下記のように変更します。
setup.php
include_once WP_CONTENT_DIR . '/wpalchemy/MetaBox.php';
include_once WP_CONTENT_DIR . '/wpalchemy/MediaAccess.php';
$wpalchemy_media_access = new WPAlchemy_MediaAccess();
if (is_admin()) wp_enqueue_style('wpalchemy-metabox', get_stylesheet_directory_uri() . '/metaboxes/meta.css');
$custom_metabox = $simple_mb = new WPAlchemy_MetaBox(array
(
'id' => '_custom_meta',
'title' => 'カスタムフィールド',
'template' => get_stylesheet_directory() . '/metaboxes/metabox.php'
));
2、3行目の「MediaAccess.php」のインクルードとインスタンス化を追加しただけですね。
次は画像の項目の追加です。
「metabox.php」に以下を追加します。
metabox.php
<?php global $wpalchemy_media_access; ?>
<?php $mb->the_field('imgurl'); ?>
<?php $wpalchemy_media_access->setGroupName('nn')->setInsertButtonLabel('追加'); ?>
<label>画像</label>
<p>
<?php echo $wpalchemy_media_access->getField(array('name' => $mb->get_the_name(), 'value' => $mb->get_the_value())); ?>
<?php echo $wpalchemy_media_access->getButton(); ?>
</p>
これで画像のフィールドが追加されます。

ボタンが「Add Media」と英語表記になっていますが、これは「MediaAccess.php」を直接編集することで変更できます。
管理画面から項目の追加&削除を行う
例えば商品の写真をカスタムフィールドで追加したいとき、2つかもしれないし3つかもしれないと項目のが記事によって可変するケースがあったとします。
あらかじめ最大数の項目を作成しておいてもいいですが、「WPAlchemy MetaBox」を使えば投稿者が自由に項目を追加&削除できる機能も簡単に付けることができます。
metabox.phpを下記のようにします。
metabox.php
<?php global $wpalchemy_media_access; ?>
<div class="my_meta_control">
<p><a href="#" class="dodelete-docs button">全て削除</a></p>
<?php while($mb->have_fields_and_multi('docs')): ?>
<?php $mb->the_group_open(); ?>
<?php $mb->the_field('imgurl'); ?>
<?php $wpalchemy_media_access->setGroupName('img-n'. $mb->get_the_index())->setInsertButtonLabel('メディア追加'); ?>
<p>
<?php echo $wpalchemy_media_access->getField(array('name' => $mb->get_the_name(), 'value' => $mb->get_the_value())); ?>
<?php echo $wpalchemy_media_access->getButton(); ?>
<a href="#" class="dodelete button">項目の削除</a>
</p>
<?php $mb->the_group_close(); ?>
<?php endwhile; ?>
<p style="margin-bottom:15px; padding-top:5px;"><a href="#" class="docopy-docs button">項目の追加</a></p>
</div>
これで「項目の追加」を押せば自由に追加できるようにまります。
「$mb->the_group_open()」から「$mb->the_group_close()」が一つのグループになりますので、inputの種類の変更や追加を行いたい場合はこのあたりを修正します。

項目数を制限する。
項目を無制限に追加されてもちょっと困りますね。
最小が3つ、最大5つの項目にしたい場合は、4行目下記のようにします。
metabox.php
<?php while($mb->have_fields_and_multi('docs', array('length' => 3, 'limit' => 5))): ?>
削除ボタンを押したときの英語を日本語にする。
削除ボタンを押すと「This action can not be undone, are you sure?」と英語でアラートが表示されます。
この文は「wpalchemy」→「MetaBox.php」の1470行目あたりにありますので直接書き換るしかないと思います。
COMMENTS

arimichi2011-12-03 21:39
はじめましてWEBOPIXELさん。
便利なクラスをご紹介頂きありがとうございます。
ひとつ伺いたいのですが、カスタムポストタイプで画像のカスタムフィールドを設置したところうまくメディアアップローダーが立ち上がらないのですが、なにか解決策はないのでしょうか?
どうしてもカスタムポストタイプ内でWPAlchemyの画像フィールドをリピートできるようにして設置したくて、コメントさせて頂きました。
どうかよろしくお願いします。

webOpixel2011-12-04 11:15
ブログ閲覧ありがとうございます。
「画像フィールドをリピートできるようにして設置」とは複数の画像フールドを作るということですか?
1つだけならアップロードすることはできますか?

arimichi2011-12-04 12:32
そうなんです。WPAlchemyの機能としてリピートでカスタムフィールドを追加できるので。ただ、リピートの機能は問題ないのですが、画像周りの機能がカスタムポストタイプではおかしくなるんです。
もちろんWEBOPIXELさんが【画像のカスタムフィールドを追加する】以下で記載して頂いた内容をカスタムポストタイプで行ってもアップローダーのポップアップがおかしくなるんです。
カスタムポストタイプ内でmediaacsessがうまく機能してないようなのです。ソースコードかなり眺めたんですが、私、プログラマーではないので難しくコメントさせて頂きました。
よろしくお願いします。

webOpixel2011-12-05 09:20
ちょっとリピートというのがよくわからないのですが、、、
普通のテキストなら保存できて、画像のタイプだとポップアップが立ち上がらないということでしょうか?
記事通りにファイルを設置して頂ければ動作するとは思うのですが、何でしょうね。
原因としては、他のプラグインとバッティングしているとか、古いブラウザを使用しているとかくらいしか思いつきません。

arimichi2011-12-05 12:06
リピートに関しては↓
http://www.youtube.com/watch?v=4DU-jX0j96g
で紹介されている機能です。
カスタム投稿タイプで画像を追加するとポップアップが立ち上がらず(iflameが効いていない)、アップローダーがポップアップではない状態になります(画面いっぱいにメディアアップローダーが表示される)。その後管理画面に戻れない状態になります。もちろん挿入するのボタンもありません。

webOpixel2011-12-05 12:59
リピートして項目を追加する部分を加筆しました。

arimichi2011-12-07 16:42
webOpixelさん、こんにちは。
カスタム投稿内で画像アップロード機能がおかしくなる件ですが、自己解決しましたので、報告します。
今回私、カスタム投稿でカスタムフィールドのみの使用を考えていたので、そもそもカスタム投稿を作成する際
‘supports’=> array(‘title’)
でタイトル部分とカスタムフィールドのみでカスタム投稿を組んでいたのですが、ココの部分を
‘supports’=> array(‘title’,'editor’)
とエディターをサポートするように変更した所うまく動作しました。
まあ、考えてみれば実際の投稿でもエディターの部分にメディアアップローダーが実装されていますので、これをサポートするようにカスタム投稿を使用しないといけないという落ちでした。
どうも、お騒がせしました。