WordPressでカスタムフィールドを追加するfunctions.php

phpソースコード

投稿画面にカスタムフィールドを追加する

カスタムフィールドとは?

初期段階では表示されない投稿エリアです。標準の投稿表示だけでは物足りないときに重宝しますが、結構組み込むのが面倒くさい(分かりにくい?)のです。

編集画面にカスタムフィールドを追加するにはfunctions.phpに以下の関数を使います。

add_meta_box( $id, $title, $callback, $screen, $context, $priority, $callback_args );

$id - 任意のID
$title - 表示されるフィールド名
$callback - フィールドを表示する際に読み込まれる関数
$screen - カスタムフィールドを表示させる投稿タイプ
$context - 編集部分が表示される場所
$priotiry - 表示される優先度
$callback_args - $callbackで呼ばれる関数に渡す値

【参考】WordPress – 関数リファレンス / add_meta_box

さっそく追加してみる

追加するには最低2つの関数を用意する必要があります。「編集画面にフィールドを表示する関数」と「フィールドに入力された値を保存する関数」です。

追加するにはアクションフックの「add_meta_boxes」と「save_post」を使用します。

add_action( 'add_meta_boxes', '編集画面に表示する関数' );
add_action( 'save_post', '保存する関数' );

詳しくは上出の関数リファレンスのサンプルコードをご覧ください(丸投げ)。

保存用関数を定義する際には、「wp_nonce_field」を呼び出す必要があるので忘れないようにしましょう。

【参考】WordPress – 関数リファレンス / wp_nonce_field

いろんなところで活用できるようクラスを定義する

他のWordPressサイトでも使いまわしが効くようにカスタムフィールドを組み込むクラスを定義してみます。

3つのクラスを用意しました。

  • カスタムフィールドを追加・保存するクラス
  • 編集画面に実際に表示させる(レンダリングする)クラス
  • サイトに合わせたフィールドを定義するクラス(1つ目の子クラス)

3つ目がサイト毎に変化するクラスとなります。

追加・保存を扱うクラス

ひとつめのクラスです。編集画面にフィールドを表示させるクラスを読み込んでいます。

<?php
require_once 'レンダリングクラス.php';
class AddMetaBox{
  protected static $_fields = array();

  function __construct(){
    // アクションフックを実行
    add_action('add_meta_boxes', array($this,'addMetaBox'));
    add_action('save_post', array($this,'save'));
  }

  function addMetaBox($post_type){
    // 子クラスで定義されたフィールド情報を取得
    $metas = static::$_fields;

    // 現編集画面の投稿タイプが定義されていなければ実行しない
    if(!in_array($post_type, array_keys($metas)))
      return;

    // 投稿タイプが何も定義されていない場合
    // 今回の場合は、投稿と固定ページ
    if( !array_key_exists('post', $metas) && !array_key_exists('page', $metas) ){
      return;
    }

    $fields = $metas[$post_type];
    if(!is_array($fields))
      $fields = array($fields);

    $count = 0;
    foreach ($fields as $key => $render) {
      $boxinfo = array(
        'title' => $key,
        'field_name' => 'meta-input-'.$count,
        'rendering' => $render // レンダリングするフィールドのinputタイプ
      );
      add_meta_box($boxinfo['field_name'], $key, array($this, 'render'), $post_type, 'advanced', 'high', $boxinfo);
      ++$count;
    }
  }

  function save($post_id){
    if(!isset($_POST['nonce']))
      return $post_id;

    $nonce = $_POST['nonce'];

    if(!wp_verify_nonce($nonce,'meta_nonce_box'))
      throw new Exception("invalid nonce");

    if(defined('DOING_AUTOSAVE') && DOING_AUTOSAVE)
      return $post_id;

    if($_POST['post_type'] == 'page'){
      if(!current_user_can('edit_page', $post_id))
        return $post_id;
    }else{
      if(!current_user_can('edit_post', $post_id))
        return $post_id;
    }

    $field_keys = array_keys(static::$_fields[$_POST['post_type']]);

    foreach ($field_keys as $key => $value) {
      $inputName = $this->makeInputName($key);
      if( !isset($_POST[$inputName]) || empty($_POST[$inputName]) )
        continue;

      $data = sanitize_text_field($_POST[$inputName]);
      update_post_meta($post_id, $value, $data);
    }
  }

  // フィールドを表示
  function render($post,$callbackArgs){
    wp_nonce_field('meta_nonce_box','nonce');
    $value = get_post_meta($post->ID, $callbackArgs['args']['title'], true);
    $field = new RenderField;
    $field->setName($callbackArgs['args']['field_name']);
    $field->setValue($value);
    // レンダリングクラスの関数を呼び出す
    $field->$callbackArgs['args']['rendering']();
  }

  // フィールドネームがダブらないようにする
  protected function makeInputName($num){
    return 'meta-input-'.$num; }
  }
?>

フィールドをレンダリングするクラス

カスタムフィールドのinput形式(テキストやテキストエリアなど)に応じてレンダリングする関数を定義しています。

<?php
class RenderField{
  const TEXT = 'renderTextInput';
  const TEXTAREA = 'renderTextarea';

  private $_name;
  private $_value;

  function getName(){ return $this->_name; }
  function getValue(){ return $this->_value; }
  function setName($val){ $this->_name = $val; }
  function setValue($val){ $this->_value = $val; }

  function renderTextarea(){
    // テキストエリアをレンダリングする処理
  }

  function renderTextInput(){
    // テキストフィールドをレンダリングする処理
  }
}
?>

サイトに応じたフィールドを定義するクラス

このクラスは一つ目のクラスの子クラスになります。サイトに応じて必要となるカスタムフィールドの数や名前、種類を定義します。

このクラスの中身はサイトによって変わってきますが、変わってくるのは配列の中身だけで大まかなところ同じになります。

<?php
require_once '追加・保存をあつかうクラス.php';

class CustomFields extends AddMetaBox{

  /*
  [投稿タイプ] =>
    [フィールドに表示される名前] => [適応するレンダリング処理]
  */
  protected static $_fields = array(
    'post' => array(
      'フィールドその1' => RenderField::TEXT,
      'フィールドその2' => RenderField::TEXT,

    'page' => array(
      'テキストエリアサンプル' => RenderField::TEXTAREA
    )
  );
}
?>

functions.phpに読み込ませる

上記のクラスが定義できたらfunctions.phpに下記のように定義します。

<?php
  require_once('サイトに応じたフィールドを定義するクラス.php');

  if( is_admin() ){
    add_action('load-post.php', 'addMetaBox');
    add_action('load-post-new.php', 'addMetaBox');
  }

  function addMetaBox(){
    new サイトに応じたフィールドを定義するクラス();
  }
?>

これでフィールドが表示されます。

長々とお付き合いいただきましてありがとうございました!

(Visited 1,464 times, 1 visits today)