メタボックスとは何ですか?

ユーザーが投稿を編集する際、編集画面はエディタ、公開、カテゴリ、タグなどのいくつかのデフォルトボックスで構成されています。これらのボックスはメタボックスです。プラグインは、任意の投稿タイプの編集画面にカスタムメタボックスを追加できます。

カスタムメタボックスの内容は通常、ユーザーがプラグインの目的に関連するデータを入力するHTMLフォーム要素ですが、内容は実際には希望する任意のHTMLにすることができます。

なぜメタボックスを使用するのですか?

メタボックスは便利で柔軟性があり、モジュール式の編集画面要素であり、編集されている投稿に関連する情報を収集するために使用できます。カスタムメタボックスは、他のすべての投稿関連情報と同じ画面に表示されるため、明確な関係が確立されます。

メタボックスは、表示する必要のないユーザーから簡単に隠すことができ、必要なユーザーには表示されます。メタボックスは、編集画面でユーザーが自由に配置できます。ユーザーは、自分に合った方法で編集画面を配置でき、編集環境に対するコントロールを持つことができます。

このページのすべての例は、説明目的のみです。コードは本番環境には適していません。

入力のセキュリティユーザーの権限ノンス、および国際化などの操作は意図的に省略されています。これらの重要な操作には常に対処してください。

メタボックスの追加

メタボックスを作成するには、add_meta_box()関数を使用し、その実行をadd_meta_boxesアクションフックに接続します。

以下の例は、post編集画面とwporg_cpt編集画面にメタボックスを追加しています。

  1. function wporg_add_custom_box() {
  2. $screens = [ 'post', 'wporg_cpt' ];
  3. foreach ( $screens as $screen ) {
  4. add_meta_box(
  5. 'wporg_box_id', // Unique ID
  6. 'Custom Meta Box Title', // Box title
  7. 'wporg_custom_box_html', // Content callback, must be of type callable
  8. $screen // Post type
  9. );
  10. }
  11. }
  12. add_action( 'add_meta_boxes', 'wporg_add_custom_box' );
  1. 以下の例は、フォーム要素、ラベル、およびその他のHTML要素を追加しています。
  2. ``````bash
  3. function wporg_custom_box_html( $post ) {
  4. ?>
  5. <label for="wporg_field">Description for this field</label>
  6. <select name="wporg_field" id="wporg_field" class="postbox">
  7. <option value="">Select something...</option>
  8. <option value="something">Something</option>
  9. <option value="else">Else</option>
  10. </select>
  11. <?php
  12. }
  13. `

メタボックスには送信ボタンがないことに注意してください。 メタボックスのHTMLは編集画面のフォームタグ内に含まれており、ユーザーが公開または更新ボタンをクリックすると、すべての投稿データ(メタボックスの値を含む)がPOSTを介して転送されます。

ここに示されている例は、1つのフォームフィールド(ドロップダウンリスト)のみを含んでいます。特定のメタボックスに必要なだけ多くのフィールドを作成できます。表示するフィールドが多い場合は、複数のメタボックスを使用し、各メタボックスに類似のフィールドをグループ化することを検討してください。これにより、ページがより整理され、視覚的に魅力的になります。

値の取得

保存されたユーザーデータを取得して利用するには、最初に保存した場所から取得する必要があります。postmetaテーブルに保存されている場合は、get_post_meta()を使用してデータを取得できます。

以下の例は、保存されたメタボックスの値に基づいて事前に入力されたデータで前のフォーム要素を強化します。メタボックスの値を保存する方法は次のセクションで学びます。

  1. function wporg_custom_box_html( $post ) {
  2. $value = get_post_meta( $post->ID, '_wporg_meta_key', true );
  3. ?>
  4. <label for="wporg_field">Description for this field</label>
  5. <select name="wporg_field" id="wporg_field" class="postbox">
  6. <option value="">Select something...</option>
  7. <option value="something" <?php selected( $value, 'something' ); ?>>Something</option>
  8. <option value="else" <?php selected( $value, 'else' ); ?>>Else</option>
  9. </select>
  10. <?php
  11. }

選択された()関数についての詳細。

値の保存

投稿タイプが保存または更新されると、いくつかのアクションが発火し、入力された値を保存するためにフックするのに適切なものがあるかもしれません。この例ではsave_postアクションフックを使用しますが、特定の状況には他のフックがより適切かもしれません。save_postは単一の更新イベントに対して複数回発火する可能性があることに注意してください。データを保存するアプローチをそれに応じて構築してください。

入力されたデータは、WordPressの外部でも保存できます。投稿に関連するデータを扱っていると思われるため、postmetaテーブルはデータを保存するのに適した場所です。

以下の例では、wporg_fieldフィールドの値を_wporg_meta_keyメタキーに保存します。これは隠されています。

  1. function wporg_save_postdata( $post_id ) {
  2. if ( array_key_exists( 'wporg_field', $_POST ) ) {
  3. update_post_meta(
  4. $post_id,
  5. '_wporg_meta_key',
  6. $_POST['wporg_field']
  7. );
  8. }
  9. }
  10. 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を使用してメタボックスを追加するのは簡単で、グローバル名前空間での名前の衝突を心配する必要がありません。

メモリを節約し、実装を容易にするために、以下の例では静的メソッドを持つ抽象クラスを使用しています。

  1. abstract class WPOrg_Meta_Box {
  2. /**
  3. * Set up and add the meta box.
  4. */
  5. public static function add() {
  6. $screens = [ 'post', 'wporg_cpt' ];
  7. foreach ( $screens as $screen ) {
  8. add_meta_box(
  9. 'wporg_box_id', // Unique ID
  10. 'Custom Meta Box Title', // Box title
  11. [ self::class, 'html' ], // Content callback, must be of type callable
  12. $screen // Post type
  13. );
  14. }
  15. }
  16. /**
  17. * Save the meta box selections.
  18. *
  19. * @param int $post_id The post ID.
  20. */
  21. public static function save( int $post_id ) {
  22. if ( array_key_exists( 'wporg_field', $_POST ) ) {
  23. update_post_meta(
  24. $post_id,
  25. '_wporg_meta_key',
  26. $_POST['wporg_field']
  27. );
  28. }
  29. }
  30. /**
  31. * Display the meta box HTML to the user.
  32. *
  33. * @param WP_Post $post Post object.
  34. */
  35. public static function html( $post ) {
  36. $value = get_post_meta( $post->ID, '_wporg_meta_key', true );
  37. ?>
  38. <label for="wporg_field">Description for this field</label>
  39. <select name="wporg_field" id="wporg_field" class="postbox">
  40. <option value="">Select something...</option>
  41. <option value="something" <?php selected( $value, 'something' ); ?>>Something</option>
  42. <option value="else" <?php selected( $value, 'else' ); ?>>Else</option>
  43. </select>
  44. <?php
  45. }
  46. }
  47. add_action( 'add_meta_boxes', [ 'WPOrg_Meta_Box', 'add' ] );
  48. add_action( 'save_post', [ 'WPOrg_Meta_Box', 'save' ] );

AJAX

メタボックスのHTML要素は編集画面のformタグ内にあるため、デフォルトの動作は、ユーザーがページを送信した後に$_POSTスーパーグローバルからメタボックスの値を解析することです。

AJAXを使用してデフォルトの体験を強化できます。これにより、ユーザーの入力や行動に基づいてアクションを実行できます。ページを送信したかどうかに関係なく。

トリガーの定義

まず、トリガーを定義する必要があります。これはリンクのクリック、値の変更、または他のJavaScriptイベントのいずれかです。

以下の例では、AJAXリクエストを実行するためのトリガーとしてchangeを定義します。

  1. /*jslint browser: true, plusplus: true */
  2. (function ($, window, document) {
  3. 'use strict';
  4. // execute when the DOM is ready
  5. $(document).ready(function () {
  6. // js 'change' event triggered on the wporg_field form field
  7. $('#wporg_field').on('change', function () {
  8. // our code
  9. });
  10. });
  11. }(jQuery, window, document));

クライアントサイドコード

次に、トリガーに何をさせたいかを定義する必要があります。言い換えれば、クライアントサイドコードを書く必要があります。

以下の例では、POSTリクエストを行い、応答は成功または失敗となります。これはwporg_fieldの値が有効かどうかを示します。

  1. /*jslint browser: true, plusplus: true */
  2. (function ($, window, document) {
  3. 'use strict';
  4. // execute when the DOM is ready
  5. $(document).ready(function () {
  6. // js 'change' event triggered on the wporg_field form field
  7. $('#wporg_field').on('change', function () {
  8. // jQuery post method, a shorthand for $.ajax with POST
  9. $.post(wporg_meta_box_obj.url, // or ajaxurl
  10. {
  11. action: 'wporg_ajax_change', // POST data, action
  12. wporg_field_value: $('#wporg_field').val(), // POST data, wporg_field_value
  13. post_ID: jQuery('#post_ID').val() // The ID of the post currently being edited
  14. }, function (data) {
  15. // handle response data
  16. if (data === 'success') {
  17. // perform our success logic
  18. } else if (data === 'failure') {
  19. // perform our failure logic
  20. } else {
  21. // do nothing
  22. }
  23. }
  24. );
  25. });
  26. });
  27. }(jQuery, window, document));

WordPress AJAXファイルのURLを、次のステップで作成するwporg_meta_box_objJavaScriptカスタムオブジェクトから動的に取得しました。

メタボックスがWordPress AJAXファイルのURLのみを必要とする場合は、新しいカスタムJavaScriptオブジェクトを作成する代わりに、ajaxurl事前定義されたJavaScript変数を使用できます。

WordPress管理画面でのみ利用可能です。 何らかのロジックを実行する前に、空でないことを確認してください。

クライアントサイドコードのエンキュー

次のステップは、コードをスクリプトファイルに入れ、編集画面でエンキューすることです。

以下の例では、次の投稿タイプの編集画面にAJAX機能を追加します:post、wporg_cpt。

スクリプトファイルは/plugin-name/admin/meta-boxes/js/admin.jsに存在し、

  1. `````/plugin-name/plugin.php`````が関数を呼び出すファイルです。
  2. ``````bash
  3. function wporg_meta_box_scripts()
  4. {
  5. // get current admin screen, or null
  6. $screen = get_current_screen();
  7. // verify admin screen object
  8. if (is_object($screen)) {
  9. // enqueue only for specific post types
  10. if (in_array($screen->post_type, ['post', 'wporg_cpt'])) {
  11. // enqueue script
  12. wp_enqueue_script('wporg_meta_box_script', plugin_dir_url(__FILE__) . 'admin/meta-boxes/js/admin.js', ['jquery']);
  13. // localize script, create a custom js object
  14. wp_localize_script(
  15. 'wporg_meta_box_script',
  16. 'wporg_meta_box_obj',
  17. [
  18. 'url' => admin_url('admin-ajax.php'),
  19. ]
  20. );
  21. }
  22. }
  23. }
  24. add_action('admin_enqueue_scripts', 'wporg_meta_box_scripts');
  25. `

サーバーサイドコード

最後のステップは、リクエストを処理するサーバーサイドコードを書くことです。

  1. // The piece after `wp_ajax_` matches the action argument being sent in the POST request.
  2. add_action( 'wp_ajax_wporg_ajax_change', 'my_ajax_handler' );
  3. /**
  4. * Handles my AJAX request.
  5. */
  6. function my_ajax_handler() {
  7. // Handle the ajax request here
  8. if ( array_key_exists( 'wporg_field_value', $_POST ) ) {
  9. $post_id = (int) $_POST['post_ID'];
  10. if ( current_user_can( 'edit_post', $post_id ) ) {
  11. update_post_meta(
  12. $post_id,
  13. '_wporg_meta_key',
  14. $_POST['wporg_field_value']
  15. );
  16. }
  17. }
  18. wp_die(); // All ajax handlers die when finished
  19. }

最後に、ここに示されているコードは、セキュリティに関する重要な操作が欠けています。本番コードにはそのような操作が含まれていることを確認してください。

ハンドブックのAJAX章およびCodexでAJAXの詳細を確認してください。

詳細情報