メタボックスとは何ですか?
ユーザーが投稿を編集する際、編集画面はエディタ、公開、カテゴリ、タグなどのいくつかのデフォルトボックスで構成されています。これらのボックスはメタボックスです。プラグインは、任意の投稿タイプの編集画面にカスタムメタボックスを追加できます。
カスタムメタボックスの内容は通常、ユーザーがプラグインの目的に関連するデータを入力するHTMLフォーム要素ですが、内容は実際には希望する任意のHTMLにすることができます。
なぜメタボックスを使用するのですか?
メタボックスは便利で柔軟性があり、モジュール式の編集画面要素であり、編集されている投稿に関連する情報を収集するために使用できます。カスタムメタボックスは、他のすべての投稿関連情報と同じ画面に表示されるため、明確な関係が確立されます。
メタボックスは、表示する必要のないユーザーから簡単に隠すことができ、必要なユーザーには表示されます。メタボックスは、編集画面でユーザーが自由に配置できます。ユーザーは、自分に合った方法で編集画面を配置でき、編集環境に対するコントロールを持つことができます。
このページのすべての例は、説明目的のみです。コードは本番環境には適していません。
入力のセキュリティ、ユーザーの権限、ノンス、および国際化などの操作は意図的に省略されています。これらの重要な操作には常に対処してください。
メタボックスの追加
メタボックスを作成するには、add_meta_box()関数を使用し、その実行をadd_meta_boxes
アクションフックに接続します。
以下の例は、post
編集画面とwporg_cpt
編集画面にメタボックスを追加しています。
function wporg_add_custom_box() {
$screens = [ 'post', 'wporg_cpt' ];
foreach ( $screens as $screen ) {
add_meta_box(
'wporg_box_id', // Unique ID
'Custom Meta Box Title', // Box title
'wporg_custom_box_html', // Content callback, must be of type callable
$screen // Post type
);
}
}
add_action( 'add_meta_boxes', 'wporg_add_custom_box' );
以下の例は、フォーム要素、ラベル、およびその他のHTML要素を追加しています。
``````bash
function wporg_custom_box_html( $post ) {
?>
<label for="wporg_field">Description for this field</label>
<select name="wporg_field" id="wporg_field" class="postbox">
<option value="">Select something...</option>
<option value="something">Something</option>
<option value="else">Else</option>
</select>
<?php
}
`
メタボックスには送信ボタンがないことに注意してください。 メタボックスのHTMLは編集画面のフォームタグ内に含まれており、ユーザーが公開または更新ボタンをクリックすると、すべての投稿データ(メタボックスの値を含む)がPOST
を介して転送されます。
ここに示されている例は、1つのフォームフィールド(ドロップダウンリスト)のみを含んでいます。特定のメタボックスに必要なだけ多くのフィールドを作成できます。表示するフィールドが多い場合は、複数のメタボックスを使用し、各メタボックスに類似のフィールドをグループ化することを検討してください。これにより、ページがより整理され、視覚的に魅力的になります。
値の取得
保存されたユーザーデータを取得して利用するには、最初に保存した場所から取得する必要があります。postmeta
テーブルに保存されている場合は、get_post_meta()を使用してデータを取得できます。
以下の例は、保存されたメタボックスの値に基づいて事前に入力されたデータで前のフォーム要素を強化します。メタボックスの値を保存する方法は次のセクションで学びます。
function wporg_custom_box_html( $post ) {
$value = get_post_meta( $post->ID, '_wporg_meta_key', true );
?>
<label for="wporg_field">Description for this field</label>
<select name="wporg_field" id="wporg_field" class="postbox">
<option value="">Select something...</option>
<option value="something" <?php selected( $value, 'something' ); ?>>Something</option>
<option value="else" <?php selected( $value, 'else' ); ?>>Else</option>
</select>
<?php
}
選択された()関数についての詳細。
値の保存
投稿タイプが保存または更新されると、いくつかのアクションが発火し、入力された値を保存するためにフックするのに適切なものがあるかもしれません。この例ではsave_post
アクションフックを使用しますが、特定の状況には他のフックがより適切かもしれません。save_post
は単一の更新イベントに対して複数回発火する可能性があることに注意してください。データを保存するアプローチをそれに応じて構築してください。
入力されたデータは、WordPressの外部でも保存できます。投稿に関連するデータを扱っていると思われるため、postmeta
テーブルはデータを保存するのに適した場所です。
以下の例では、wporg_field
フィールドの値を_wporg_meta_key
メタキーに保存します。これは隠されています。
function wporg_save_postdata( $post_id ) {
if ( array_key_exists( 'wporg_field', $_POST ) ) {
update_post_meta(
$post_id,
'_wporg_meta_key',
$_POST['wporg_field']
);
}
}
add_action( 'save_post', 'wporg_save_postdata' );
本番コードでは、情報ボックスに記載されているセキュリティ対策に従うことを忘れないでください!
舞台裏
通常、舞台裏で何が起こるかを心配する必要はありません。このセクションは完全性のために追加されました。
投稿編集画面が追加されたすべてのメタボックスを表示したい場合、do_meta_boxes()関数を呼び出します。この関数はすべてのメタボックスをループし、それぞれに関連付けられたcallback
を呼び出します。
各呼び出しの間に、介入するマークアップ(div、タイトルなど)が追加されます。
メタボックスの削除
編集画面から既存のメタボックスを削除するには、remove_meta_box()関数を使用します。渡されたパラメータは、add_meta_box()でメタボックスを追加するために使用されたものと正確に一致する必要があります。
デフォルトのメタボックスを削除するには、使用されているパラメータのソースコードを確認してください。デフォルトのadd_meta_box()呼び出しはwp-includes/edit-form-advanced.php
から行われます。
実装のバリエーション
これまで、メタボックスを実装するための手続き型技術を使用してきました。多くのプラグイン開発者は、さまざまな他の技術を使用してメタボックスを実装する必要があると感じています。
OOP
OOPを使用してメタボックスを追加するのは簡単で、グローバル名前空間での名前の衝突を心配する必要がありません。
メモリを節約し、実装を容易にするために、以下の例では静的メソッドを持つ抽象クラスを使用しています。
abstract class WPOrg_Meta_Box {
/**
* Set up and add the meta box.
*/
public static function add() {
$screens = [ 'post', 'wporg_cpt' ];
foreach ( $screens as $screen ) {
add_meta_box(
'wporg_box_id', // Unique ID
'Custom Meta Box Title', // Box title
[ self::class, 'html' ], // Content callback, must be of type callable
$screen // Post type
);
}
}
/**
* Save the meta box selections.
*
* @param int $post_id The post ID.
*/
public static function save( int $post_id ) {
if ( array_key_exists( 'wporg_field', $_POST ) ) {
update_post_meta(
$post_id,
'_wporg_meta_key',
$_POST['wporg_field']
);
}
}
/**
* Display the meta box HTML to the user.
*
* @param WP_Post $post Post object.
*/
public static function html( $post ) {
$value = get_post_meta( $post->ID, '_wporg_meta_key', true );
?>
<label for="wporg_field">Description for this field</label>
<select name="wporg_field" id="wporg_field" class="postbox">
<option value="">Select something...</option>
<option value="something" <?php selected( $value, 'something' ); ?>>Something</option>
<option value="else" <?php selected( $value, 'else' ); ?>>Else</option>
</select>
<?php
}
}
add_action( 'add_meta_boxes', [ 'WPOrg_Meta_Box', 'add' ] );
add_action( 'save_post', [ 'WPOrg_Meta_Box', 'save' ] );
AJAX
メタボックスのHTML要素は編集画面のform
タグ内にあるため、デフォルトの動作は、ユーザーがページを送信した後に$_POST
スーパーグローバルからメタボックスの値を解析することです。
AJAXを使用してデフォルトの体験を強化できます。これにより、ユーザーの入力や行動に基づいてアクションを実行できます。ページを送信したかどうかに関係なく。
トリガーの定義
まず、トリガーを定義する必要があります。これはリンクのクリック、値の変更、または他のJavaScriptイベントのいずれかです。
以下の例では、AJAXリクエストを実行するためのトリガーとしてchange
を定義します。
/*jslint browser: true, plusplus: true */
(function ($, window, document) {
'use strict';
// execute when the DOM is ready
$(document).ready(function () {
// js 'change' event triggered on the wporg_field form field
$('#wporg_field').on('change', function () {
// our code
});
});
}(jQuery, window, document));
クライアントサイドコード
次に、トリガーに何をさせたいかを定義する必要があります。言い換えれば、クライアントサイドコードを書く必要があります。
以下の例では、POST
リクエストを行い、応答は成功または失敗となります。これはwporg_field
の値が有効かどうかを示します。
/*jslint browser: true, plusplus: true */
(function ($, window, document) {
'use strict';
// execute when the DOM is ready
$(document).ready(function () {
// js 'change' event triggered on the wporg_field form field
$('#wporg_field').on('change', function () {
// jQuery post method, a shorthand for $.ajax with POST
$.post(wporg_meta_box_obj.url, // or ajaxurl
{
action: 'wporg_ajax_change', // POST data, action
wporg_field_value: $('#wporg_field').val(), // POST data, wporg_field_value
post_ID: jQuery('#post_ID').val() // The ID of the post currently being edited
}, function (data) {
// handle response data
if (data === 'success') {
// perform our success logic
} else if (data === 'failure') {
// perform our failure logic
} else {
// do nothing
}
}
);
});
});
}(jQuery, window, document));
WordPress AJAXファイルのURLを、次のステップで作成するwporg_meta_box_obj
JavaScriptカスタムオブジェクトから動的に取得しました。
メタボックスがWordPress AJAXファイルのURLのみを必要とする場合は、新しいカスタムJavaScriptオブジェクトを作成する代わりに、ajaxurl
事前定義されたJavaScript変数を使用できます。
WordPress管理画面でのみ利用可能です。 何らかのロジックを実行する前に、空でないことを確認してください。
クライアントサイドコードのエンキュー
次のステップは、コードをスクリプトファイルに入れ、編集画面でエンキューすることです。
以下の例では、次の投稿タイプの編集画面にAJAX機能を追加します:post、wporg_cpt。
スクリプトファイルは/plugin-name/admin/meta-boxes/js/admin.js
に存在し、
`````/plugin-name/plugin.php`````が関数を呼び出すファイルです。
``````bash
function wporg_meta_box_scripts()
{
// get current admin screen, or null
$screen = get_current_screen();
// verify admin screen object
if (is_object($screen)) {
// enqueue only for specific post types
if (in_array($screen->post_type, ['post', 'wporg_cpt'])) {
// enqueue script
wp_enqueue_script('wporg_meta_box_script', plugin_dir_url(__FILE__) . 'admin/meta-boxes/js/admin.js', ['jquery']);
// localize script, create a custom js object
wp_localize_script(
'wporg_meta_box_script',
'wporg_meta_box_obj',
[
'url' => admin_url('admin-ajax.php'),
]
);
}
}
}
add_action('admin_enqueue_scripts', 'wporg_meta_box_scripts');
`
サーバーサイドコード
最後のステップは、リクエストを処理するサーバーサイドコードを書くことです。
// The piece after `wp_ajax_` matches the action argument being sent in the POST request.
add_action( 'wp_ajax_wporg_ajax_change', 'my_ajax_handler' );
/**
* Handles my AJAX request.
*/
function my_ajax_handler() {
// Handle the ajax request here
if ( array_key_exists( 'wporg_field_value', $_POST ) ) {
$post_id = (int) $_POST['post_ID'];
if ( current_user_can( 'edit_post', $post_id ) ) {
update_post_meta(
$post_id,
'_wporg_meta_key',
$_POST['wporg_field_value']
);
}
}
wp_die(); // All ajax handlers die when finished
}
最後に、ここに示されているコードは、セキュリティに関する重要な操作が欠けています。本番コードにはそのような操作が含まれていることを確認してください。
ハンドブックのAJAX章およびCodexでAJAXの詳細を確認してください。