かもメモ

自分の落ちた落とし穴に何度も落ちる人のメモ帳

WordPress CMB2でデフォルトのページテンプレートだけにカスタムフィールドを付けたい


コードベースでWordPressのカスタムフィールドを作成できる CMB2 を愛用しています。
( 以前 Custom-Metaboxes-and-Fields-for-WordPress だったものが CMB2 という名前になり開発されています。 )

デフォルトテンプレートの固定ページにのみカスタムフィールドを作成する

テーマのテンプレートを使用していない「デフォルトテンプレート」のままの固定ページにのみ、CMB2でカスタムフィールドを作成する場合は下記のように指定をすればOK

  1. カスタムフィールドを表示する投稿タイプの設定 object_typespage にする
  2. show_on オプションで ['key' => 'page-template', 'value' => 'default'] とページテンプレートのデフォルトと指定

EX:

<?php // function.php

if( file_exists(  __PLUGINS__ . '/cmb2/init.php' ) ){
  require_once( __PLUGINS__ . '/cmb2/init.php' );
  add_filter( 'cmb2_admin_init', 'add_my_custom_metaboxes' );
}

function add_my_custom_metaboxes() {
  // Page (default template)
  $prefix = '_page_';
  $cmb_page = new_cmb2_box([
    'id'           => 'page_title',
    'title'        => 'ページタイトル',
    'object_types' => ['page'],
    'show_on'      => [
      'key'   => 'page-template',
      // 'default' を指定するのがポイント!
      'value' => 'default',
    ],
    'context'      => 'side',
    'priority'     => 'default',
    'show_names'   => false,
  ]);
  $cmb_page->add_field([
    'name'   => 'page_top_title',
    'id'     => $prefix . 'top_title',
    'type'   => 'text',
    'attributes' => [
      'placeholder' => 'ページタイトルを入力してください',
    ],
  ]);
}

👇 f:id:kikiki-kiki:20170701225158p:plain
こんな感じに、簡単に「デフォルトテンプレートの固定ページ」にのみカスタムフィールドを作成することができました!

特定のテンプレートの固定ページにカスタムフィールドを作成する場合は、show_onvalueをテンプレートファイル名にするだけ。
フォルダに入れている場合は、<フォルダ名>/<テンプレートファイル名>.php とすればOKです。

CMB2とっても簡単にカスタムフィールドが作成できるので ネ申 !!


エンジニアのためのWordPress開発入門 (Engineer's Library)

エンジニアのためのWordPress開発入門 (Engineer's Library)

WordPress 管理画面 固定ページ一覧にスラッグとテンプレート名を表示させたい

WordPressでWEBサイトを作る際に特定のページを作成するために固定ページのテンプレートを作成したりする事があります。
ただテンプレートの選択やページのURLの指定はWordPressの管理画面から行うので、テスト環境と本番環境があるような場合、本番環境でテンプレートが選択できてなかったとか、URL(スラッグ)がテスト環境と同じに設定できてなかったという事故が起こりかねません。
これらが固定ページ一覧のリスト上に表示できれば、ミスがあっても早期発見して修正できるように思います。

固定ページ一覧に表示する要素を変更する

管理画面の一覧ページに表示するカラムのカスタマイズは、manage_{$post_type}_posts_columns フィルターを使います。

(WordPress3.1以前では `manage_edit-{$post_type}_columns フィルター)

今回は固定ページなのでフィルターは manage_page_posts_columns となります。

<?php // function.php

// 固定ページ一覧に表示するカラムの変更
add_filter('manage_page_posts_columns', 'my_manage_page_columns');
function my_manage_page_columns( $columns ) {
  // 表示する順序を変えたいので一度 unset でデフォルトのカラムを外す
  unset($columns['date']);
  unset($columns['author']);
  unset($columns['comments']);
  // slug と template を表示する カラムを追加
  $columns['slug'] = __('Slug');
  $columns['template'] = __('Template');
  // unset したカラムで必要なものを戻す
  $columns['author'] = __('Author');
  $columns['date'] = __('Date');
  return $columns;
}

これで管理画面の固定ページ一覧に スラッグ と テンプレート のカラムがたされた状態になります。
見出しを変更したい場合は、__('Slug') の部分を "URL" などの表示したい文字に変えればOK。

管理画面 固定ページ 一覧の表示のカスタマイズ

カラムに表示するもののカスタマイズは manage_{$post_type}_posts_custom_column フィルターを使います。
カスタム投稿タイプなら manage_posts_custom_column とすれば投稿とカスタム投稿タイプを一括で設定できるのですが、固定ページはこのフィルターでは動作しません。
固定ページは manage_pages_custom_column というフィルターになります。

function.php に固定ページ一覧の表示をカスタマイズするコードを追加します。

<?php // function.php

// 固定ページ一覧の表示をカスタマイズ
add_action('manage_pages_custom_column', 'my_pages_custom_column', 10, 2);
function my_pages_custom_column( $column_name, $post_id ) {
  // Slug
  if( $column_name === 'slug' ) {
    $column = get_post_field('post_name', $post_id, 'display');
  }
  
  // Template Name
  if( $column_name === 'template' ) {
    $column = get_page_template_slug($post_id);
    // または
    // $column = get_post_meta( $post_id, '_wp_page_template', true );
  }

  if( isset($column) && ( $column || $column === 0 ) ) {
    echo $column;
  } else {
    echo __('None');
  }
}

👇

□タイトル スラッグ テンプレート 作成者 日時
□ HOME - フロントページ home page-home.php KiKiKi 公開済み
2017年7月1日
□ About about page-about.php KiKiKi 公開済み
2017年7月1日
□ サンプルページ sample-page なし KiKiKi 公開済み
2017年6月30日
□ Blog - 投稿ページ blog なし KiKiKi 公開済み
2017年6月30日

こんな感じに管理画面の固定ページ一覧にページのURL(Slug)と使用しているテンプレートファイル名を表示する事ができました。

固定ページのテンプレートの取得に関して

固定ページのテンプレート名は get_page_template_slug( $post_id ) で取得することができます。
ただし、特にテンプレートを設定していないデフォルトの場合 get_page_template_slug()NULLを返します。

get_post_meta( $post_id, '_wp_page_template', true ); でもテンプレート名を取得することができ、こちらの場合、テンプレートが設定されていない場合は default という文字列が返ります。

上の例では、最後に$columnが空なら__('None')を返し「なし」と表示するようにしていますが、defaultと表示させたい場合は get_post_meta( $post_id, '_wp_page_template', true ); を使うのが良いと思います。

Function Reference/get page template slug

The function get_page_template_slug() returns an empty string when the value of ‘_wp_page_template’ is either empty or 'default'.

Custom fields starting with an underscore do not display in the Edit screen’s Custom Fields module. To retrieve a Page’s custom template metadata, you can also use:

get_post_meta( $post->ID, ‘_wp_page_template’, true )
出典: Function Reference/get page template slug « WordPress Codex


[参考]

PHP json_decode がnullになるにハマる

PHPjson_decodeは値が " (ダブルコーテーションで)囲まれていないと null になるっぽい。

json_decode() でnull になるJSONのパターン

1. " で囲われていない値がある

json = {1: "星宮いちご"}
<?php
json_decode( json ); // => NULL

2. 値が ' (シングルコーテーション)で囲まれている

json = {"1": '<b class="idol">星宮いちご</b>'}
<?php
json_decode( json ); // => NULL

` ←コレもダメ

json = {"1": `星宮いちご`}
<?php
json_decode( json ); // => NULL

3. 行末に , がある

json = {"1": "星宮いちご",}
<?php
json_decode( json ); // => NULL

すべてのキーと値が " で囲まれていて、最後に不要な , もない場合ならOK

json = '{"1": "星宮いちご"}';
<?php
json_decode( json );
// => object  { ["1"]=> string(15) "星宮いちご" }
json_decode( json, true );
// => array(1) { [1]=> string(15) "星宮いちご" }

"で囲まれた値の中で'が使われているのはOK。
例えばHTMLタグを入れるような場合、値となる文字列は " で囲み、属性は'で囲めば大丈夫

json = ["<b class='idol'>星宮いちご</b>", "霧矢あおい", "紫吹蘭"];
<?php
json_decode( json );
// => array(3)  { [0]=> string(35) "<b class='idol'>星宮いちご</b>" [1]=> string(15) "霧矢あおい" [2]=> string(9) "紫吹蘭" }
json_decode( json, true );
// => array(3)  { [0]=> string(35) "<b class='idol'>星宮いちご</b>" [1]=> string(15) "霧矢あおい" [2]=> string(9) "紫吹蘭" }

PHP上の文字列でJSONを作る場合は全体を'で囲むか、値を囲む"エスケープすればOK (最初からObjectや配列作れば良くね?需要あるのか謎だけど...)

<?php
$json = '{"みくるの": "みらくる!"}';
json_decode( $json );
// => object  { ["みくるの"]=> string(15) "ミラクル!" }
$json = "{\"みくるの\": \"ミラクル!\"}";
json_decode( $json );
// => object  { ["みくるの"]=> string(15) "ミラクル!" }

 
javascriptだと問題ないようなjsonPHPjson_decode()だとnull になって少しハマりました。
PHPのバージョンが上がって解消されるといいな...


[参考]