「使いやすい」と言われたい!WordPressの編集画面にメタボックスを追加する方法

2017/04/12

Agbonghama Collins

54

Articles in this issue reproduced from SitePoint
Copyright © 2017, All rights reserved. SitePoint Pty Ltd. www.sitepoint.com. Translation copyright © 2017, KADOKAWA ASCII Research Laboratories, Inc. Japanese syndication rights arranged with SitePoint Pty Ltd, Collingwood, Victoria,Australia through Tuttle-Mori Agency, Inc., Tokyo

WordPressの編集画面にオリジナルのメタボックスを追加して、テーマに反映するまでの方法を解説。サイト独特の項目を追加して、クライアントに使いやすい画面を作れます。

自分のWebサイトやクライアントのWebサイトを作るのにWordPressを使ったことがある人、勤めている会社のWebサイトがWordPressで動いているという人なら、メタボックスを見たり使ったりしたことがあるでしょう。

SitePointでは、過去にNarayan Prustyの『Adding Custom Meta Boxes to the WordPress Admin Interface(メタボックスをWordPressに追加する)』でメタボックスについて取り上げています。この記事ではさらに2歩進んで、投稿タイプとの関連や一緒に使う方法について説明します。また、WordPressのフロントエンドのメタボックスにセーブされたデータの使い方についても取り扱います。

「投稿」にメタボックスを追加する

メタボックスを作るのに便利なPHP関数、パラメータ、アクションフックの大部分(全部ではないですが)については、先のNarayan Prustyの記事で紹介されています。

「投稿」の編集画面にメタボックスを加えるには、add_meta_box()アウトを使ったあと、add_meta_boxesアクションにフックします。

次のコードはpost編集画面にメタボックスを追加します。global_notice_meta_box_callbackに注目してください。メタボックスにフォームフィールドを表示する関数です。これについては、あとで説明します。

function global_notice_meta_box() {

    add_meta_box(
        'global-notice',
        __( 'Global Notice', 'sitepoint' ),
        'global_notice_meta_box_callback',
        'post'
    );
}

add_action( 'add_meta_boxes', 'global_notice_meta_box' );

postpagebookといったカスタム投稿タイプなどや、いろいろな投稿タイプの画面にメタボックスを加えるには、投稿タイプの配列を作り、add_meta_box()を繰り返し使って配列にメタボックスを追加します。

function global_notice_meta_box() {

    $screens = array( 'post', 'page', 'book' );

    foreach ( $screens as $screen ) {
        add_meta_box(
            'global-notice',
            __( 'Global Notice', 'sitepoint' ),
            'global_notice_meta_box_callback',
            $screen
        );
    }
}

add_action( 'add_meta_boxes', 'global_notice_meta_box' );

すでに作った投稿タイプ全部、あるいはこれから作る投稿タイプにメタボックスを追加するには、get_post_types()を用いて投稿タイプの配列を取得し、上の$screenの値を書き換えます。

function global_notice_meta_box() {

    $screens = get_post_types();

    foreach ( $screens as $screen ) {
        add_meta_box(
            'global-notice',
            __( 'Global Notice', 'sitepoint' ),
            'global_notice_meta_box_callback',
            $screen
        );
    }
}

add_action( 'add_meta_boxes', 'global_notice_meta_box' );

3番目の$screen引数を省略してもメタボックスを追加できます。次のようになります。

function global_notice_meta_box() {

    add_meta_box(
        'global-notice',
        __( 'Global Notice', 'sitepoint' ),
        'global_notice_meta_box_callback'
    );

}

add_action( 'add_meta_boxes', 'global_notice_meta_box' );

メタボックスを特定の投稿タイプ(この例ではbook)に作ることもできます。 次のように、投稿タイプ名をadd_meta_boxesアクションフックに追加します。

function global_notice_meta_box() {

    add_meta_box(
        'global-notice',
        __( 'Global Notice', 'sitepoint' ),
        'global_notice_meta_box_callback'
    );

}

add_action( 'add_meta_boxes_book', 'global_notice_meta_box' );

register_post_type()で使われている配列引数の中でカスタム投稿タイプをカスタマイズするために使われるのが、register_meta_box_cbで、値はメタボックスをセットアップするときに呼ばれるコールバック関数となります。

次のコードでbookカスタム投稿タイプを作ったとします。

function book_cpt() {

    $args = array(
        'label'                => 'Books',
        'public'               => true,
        'register_meta_box_cb' => 'global_notice_meta_box'
    );

    register_post_type( 'book', $args );
}

add_action( 'init', 'book_cpt' );

global_notice_meta_box PHP関数でメタボックスを作成するためのadd_meta_box()関数定義(上のコードではregister_meta_box_cbの値)をすれば、bookカスタム投稿タイプの編集画面にメタボックスが追加されます。

global_notice_meta_box関数の例をもう1度示します。

function global_notice_meta_box() {

    add_meta_box(
        'global-notice',
        __( 'Global Notice', 'sitepoint' ),
        'global_notice_meta_box_callback'
    );

}

ここまで、WordPressにメタボックスを登録したり、追加したりする方法をいろいろと説明してきましたが、まだ、メタボックスのフォームフィールドを含んだ関数global_notice_meta_box_callbackの説明はしていません。

メタボックスにテキスト領域を含む関数global_notice_meta_box_callbackのコードを次に示します。

function global_notice_meta_box_callback( $post ) {

    // Add a nonce field so we can check for it later.
    wp_nonce_field( 'global_notice_nonce', 'global_notice_nonce' );

    $value = get_post_meta( $post->ID, '_global_notice', true );

    echo '<textarea style="width:100%" id="global_notice" name="global_notice">' . esc_attr( $value ) . '</textarea>';
}

text area meta box

save_postアクションフックは、投稿が下書きとしてセーブされたり、公開されたときに、テキストエリアに入力されたデータをセーブする働きをします。

/**
 * When the post is saved, saves our custom data.
 *
 * @param int $post_id
 */
function save_global_notice_meta_box_data( $post_id ) {

    // Check if our nonce is set.
    if ( ! isset( $_POST['global_notice_nonce'] ) ) {
        return;
    }

    // Verify that the nonce is valid.
    if ( ! wp_verify_nonce( $_POST['global_notice_nonce'], 'global_notice_nonce' ) ) {
        return;
    }

    // If this is an autosave, our form has not been submitted, so we don't want to do anything.
    if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
        return;
    }

    // Check the user's permissions.
    if ( isset( $_POST['post_type'] ) && 'page' == $_POST['post_type'] ) {

        if ( ! current_user_can( 'edit_page', $post_id ) ) {
            return;
        }

    }
    else {

        if ( ! current_user_can( 'edit_post', $post_id ) ) {
            return;
        }
    }

    /* OK, it's safe for us to save the data now. */

    // Make sure that it is set.
    if ( ! isset( $_POST['global_notice'] ) ) {
        return;
    }

    // Sanitize user input.
    $my_data = sanitize_text_field( $_POST['global_notice'] );

    // Update the meta field in the database.
    update_post_meta( $post_id, '_global_notice', $my_data );
}

add_action( 'save_post', 'save_global_notice_meta_box_data' );

メタボックスのテキストエリアに入力されるデータを利用するため、セーブされる投稿コンテンツの前にデータを表示します。

function global_notice_before_post( $content ) {

    global $post;

    // retrieve the global notice for the current post
    $global_notice = esc_attr( get_post_meta( $post->ID, '_global_notice', true ) );

    $notice = "<div class='sp_global_notice'>$global_notice</div>";

    return $notice . $content;

}

add_filter( 'the_content', 'global_notice_before_post' );

コードの説明

最初に、投稿コンテンツを含む$contentパラメータでthe_contentフィルターにフックされるglobal_notice_before_post関数を作成しました。

関数内部には、閲覧されている現在の投稿のWP_Postオブジェクトを含んだグローバル$post変数が含まれます。

ある投稿に対してセーブされたグローバルノーティスはget_post_metaで知ることができ、$global_notice変数にセーブされます。

すると、ノーティスはdivにラップされ、$notice変数にセーブされます。

最後に、グローバルノーティスがセーブされた$noticeは実際の投稿コンテンツである$contentに連結されます。

下に、投稿コンテンツの前にグローバルノーティスが付加された投稿のスクリーンショットを示します。

global notice demo

最後に

この記事では、WordPressの管理画面にメタボックスを登録する方法とメタボックスを投稿タイプに限定する方法について説明しました。また、メタボックスにフォームフィールドを加える方法や、投稿がセーブされるか公開されたときに、メタボックスに入力されたデータをセーブする方法についてレビューしました。最後に、メタボックス に入力されたデータを実際に利用する方法についても説明しました。

今後、機会があれば、ヘルプタブを投稿タイプ管理画面に加える方法について取り上げたいと考えています。

(原文:Adding Meta Boxes to Post Types in WordPress

[翻訳:関 宏也/編集:Livit

Copyright © 2017, Agbonghama Collins All Rights Reserved.

Agbonghama Collins

Agbonghama Collins

ナイジェリア出身のWeb制作者兼フリーランスライターです。人気の高いProfilePressOmniPay WordPressプラグインのクリエイターです。コードと格闘しているとき以外は、ブログを書いたり、Twitterでつぶやいたりしています。Google+はこちら

Loading...