WordPress:Custom Field Suiteの使い方からカスタマイズまで
wordpressのカスタムフィールドプラグインとして人気の高い「Custom Field Suite」の表示方法、チェックボックスの追加方法などを解説します。
「Advanced Custom Fields」も人気があるプラグインですが「Custom Field Suite」には、「Advanced Custom Fields」では有料バージョンにしかないフィールドのリピート機能があります。
また「Custom Field Suite」の方が構造がシンプルなので、他のプラグインとコンフリクトすることも無いでしょう。
Custom Field Suiteのフィールド追加方法
使い方はシンプルです。必要なフィールドを追加していくだけです。
「デフォルト値」や「必須フィールド」なども設定できます。
カスタムフィールドの表示
追加したカスタムフィールドの値を表示は、フィールドタイプによって異なります。
基本的な表示方法
入力されたフィールドを表示することができます。
「テキスト」や「テキストエリア」「日付」「リンク」「カラーピッカー」など、殆どのカスタムフィールドの値はこのコードで表示できます。
PHP
<?php echo cfs()->get('フィールド名'); ?>
カテゴリーやアーカイブなど、記事を一覧で表示させるページでは、下記のコードで値を表示させることができます。
PHP
<?php echo get_post_meta($post->ID , 'フィールド名' ,true); ?>
//テキストエリアの改行を反映させる場合は下記
<?php echo nl2br(get_post_meta($post->ID , 'フィールド名' ,true)); ?>
チェックボックスのON/OFF(真/偽)
チェックボックがONの場合に表示されます。
PHP
<?php if ( get_post_meta($post->ID, 'フィールド名' ,TRUE) ): ?>
//チェックONの場合に表示
<?php endif; ?>
チェックボックスがONかOFFで分岐表示します。
PHP
<?php if ( get_post_meta($post->ID, 'フィールド名' ,TRUE) ): ?>
//チェックボックスがONの場合に表示
<?php else: ?>
//チェックボックスがOFFの場合に表示
<?php endif; ?>
ハイパーリンク PHP
ハイパーリンクで「HTML」を選択した場合は、基本的な表示方法でOKです。
ハイパーリンクでPHPを選択した場合、配列を取得できます。
配列は「URL」「text」「target」の3つがあります。
PHP
<?php
$link = CFS()->get( 'フィールド名' );
echo $link['url']; //リンク先URLを表示します
?>
アップロードしたファイルの表示
画像、音声、動画ファイルをアップロードすることができます。
基本的な表示方法にすると、ファイルのURLを取得できます。例えば下記のようなコード。
PHP
<img src="<?php $cfs->get('フィールド名'); ?>">
画像ファイルの場合「wp get attachment image」を利用して、下記のコードにするとIMGタグで表示されます。
画像
<?php if(get_post_meta($post->ID,'フィールド名',true)): ?>
//画像があるとき
<?php echo wp_get_attachment_image(post_custom('フィールド名')); ?>
<?php endif; ?>
ファイルIDから画像を表示するには下記の方法があります。
画像
<?php $fieldname = get_post_meta($post->ID, 'フィールド名', true); ?>
<?php $fieldname = wp_get_attachment_image_src($fieldname, 'large'); ?>
<img src="<?php echo $fieldname[0]; ?>">
ドロップダウン
ドロップダウンで選択した値を表示します。
PHP
<?php
$values = CFS()->get( 'フィールド名' );
foreach ( $values as $key => $label ):
?>
<span><?php echo $label; ?></span>
<?php endforeach; ?>
関連ポスト
関連ポストを表示させることができます。変数を使ってタイトルや画像を表示させています。
PHP
<?php
$values = CFS()->get('cf_test');
foreach ($values as $post_id):
setup_postdata( $post_id );
$rslink = get_permalink($post_id);
$rstitle = get_the_title($post_id);
$rsimg = get_the_post_thumbnail($post_id,'large');
?>
<p>
<a href="<?php echo $rslink ?>">
<?php echo $rstitle ?>
</a>
<figure><?php echo $rsimg ?></figure>
</p>
<?php endforeach; ?>
タームを表示
カテゴリーやタクソノミーのターム名、タグ名を値として表示できます。
これだけでは意味がないので、値を引数としてカテゴリーの記事一覧を表示させたりします。
PHP
<?php
$values = CFS()->get( 'cf_test' );
foreach ( $values as $term_id ):
$the_term = get_term($term_id);
?>
<span><?php echo $the_term->name; ?></span>
<?php endforeach; ?>
ループを表示
Custom Field Suiteの最大のメリットであるループを使ったフィールドを表示します。
サンプルでは画像をループで表示させています。
ループで画像表示
<?php
$fields = $cfs->get('ループフィールド名');
foreach ($fields as $field) :
?>
<figure><img src="<?php echo $field['フィールド名']; ?>" /></figure>
<?php endforeach; ?>
ループの中のループを表示
ループの中に「テキスト入力」と、子ループの中に「テキスト入力」と「画像アップロード」があるサンプルです。
ループinループ
<?php
$fields = $cfs->get('親ループフィールド名');
foreach ($fields as $field) :
?>
<span><?php echo $field['フィールド名']; ?></span>
<?php
$subfields = $field['子ループフィールド名'];
if($subfields):
?>
<?php
foreach ($subfields as $subfield):
?>
<?php echo '<span>' .$subfield['フィールド名']. '</span>'; ?>
<?php echo '<figure><img src="' .$subfield['画像フィールド名']. '" /></figure>'; ?>
<?php endforeach; endif; ?>
<?php endforeach; ?>
表示の分岐方法
フィールドが未入力・入力かで分岐させます。
フィールドが未記入の場合は、非表示になります。
未記入の場合、何も表示しない場合は<?php else: ?>は不要です。
PHP
<?php if(get_post_meta($post->ID,'フィールド名',true)): ?>
//入力がある場合
<?php echo $cfs()->get('フィールド名'); ?>
<?php else: ?>
//入力がない場合
<?php endif; ?>
ループの中での分岐
ループの中のフィールドで、分岐したいフィールドがある場合は下記になります。
PHP
<?php
$fields = $cfs->get('ループフィールド名');
foreach ($fields as $field) :
?>
<?php
$iffield = $field['分岐させたいフィールド名'];
if($iffield) :?>
<?php echo $field['分岐させたいフィールド名']; ?>
<?php else : ?>
フィールドがない場合
<?php endif; ?>
<?php endforeach; ?>
フィールドタイプにチェックボックを追加する方法
フィールドタイプにチェックボックが利用できるようにカスタマイズします。
ドロップダウンの複数選択でも良いのですが、複数選択はチェックボックスの方が使いやすいです。カスタマイズすると下記の図のように使えます。
まず、ファイル名「cfs_checkbox.php」として下記コードを記述します。
PHP
<?php
class cfs_checkbox extends cfs_field
{
function __construct() {
$this->name = 'checkbox';
$this->label = __('checkbox', 'cfs');
}
function html( $field ) {
$multiple = '';
$field->input_class = empty( $field->input_class ) ? '' : $field->input_class;
if ( isset( $field->options['multiple'] ) && '1' == $field->options['multiple'] ) {
$multiple = ' multiple';
$field->input_class .= ' multiple';
}
if ( '[]' != substr( $field->input_name, -2 ) && empty( $field->options['force_single'] ) ) {
$field->input_name .= '[]';
}
?>
<?php foreach ($field->options['choices'] as $val => $label) : ?>
<?php $val = ('{empty}' == $val) ? '' : $val; ?>
<?php $checked = in_array($val, (array) $field->value) ? ' checked="checked"' : ''; ?>
<input type='checkbox' name='<?php echo $field->input_name; ?>' value='<?php echo esc_attr($val); ?>'<?php echo $selected; ?> class="<?php echo $field->input_class; ?>"<?php echo $checked;?>> <?php echo esc_attr($label); ?><br>
<?php endforeach; ?>
<?php
}
function input_head( $field = null ) {
?>
<script>
(function($) {
$(function() {
$(document).on('cfs/ready', '.cfs_add_field', function() {
$('.cfs_select:not(.ready)').init_select();
});
$('.cfs_select').init_select();
});
$.fn.init_select = function() {
this.each(function() {
var $this = $(this);
$this.addClass('ready');
});
}
})(jQuery);
</script>
<?php
}
function options_html( $key, $field ) {
if ( isset( $field->options['choices'] ) && is_array( $field->options['choices'] ) ) {
foreach ( $field->options['choices'] as $choice_key => $choice_val ) {
$field->options['choices'][ $choice_key ] = "$choice_key : $choice_val";
}
$field->options['choices'] = implode( "\n", $field->options['choices'] );
}
else {
$field->options['choices'] = '';
}
?>
<tr class="field_option field_option_<?php echo $this->name; ?>">
<td class="label">
<label><?php _e('Choices', 'cfs'); ?></label>
<?php _e('Enter one choice per line', 'cfs'); ?>
</td>
<td>
<?php
CFS()->create_field(array(
'type' => 'textarea',
'input_name' => "cfs[fields][$key][options][choices]",
'value' => $this->get_option($field, 'choices'),
));
?>
</td>
</tr>
<tr class="field_option field_option_<?php echo $this->name; ?>">
<td class="label">
<label><?php _e('Multi-select?', 'cfs'); ?></label>
</td>
<td>
<?php
CFS()->create_field(array(
'type' => 'true_false',
'input_name' => "cfs[fields][$key][options][multiple]",
'input_class' => 'true_false',
'value' => $this->get_option($field, 'multiple'),
'options' => array('message' => __('This is a multi-select field', 'cfs')),
));
?>
</td>
</tr>
<tr class="field_option field_option_<?php echo $this->name; ?>">
<td class="label">
<label><?php _e('Validation', 'cfs'); ?></label>
</td>
<td>
<?php
CFS()->create_field(array(
'type' => 'true_false',
'input_name' => "cfs[fields][$key][options][required]",
'input_class' => 'true_false',
'value' => $this->get_option($field, 'required'),
'options' => array('message' => __('This is a required field', 'cfs')),
));
?>
</td>
</tr>
<?php
}
function format_value_for_api( $value, $field = null ) {
$value_array = array();
$choices = $field->options['choices'];
if ( is_array( $value ) ) {
foreach ( $value as $val ) {
$value_array[ $val ] = isset( $choices[ $val ] ) ? $choices[ $val ] : $val;
}
}
return $value_array;
}
function prepare_value( $value, $field = null ) {
return $value;
}
function pre_save_field( $field ) {
$new_choices = array();
$choices = trim( $field['options']['choices'] );
if ( ! empty( $choices ) ) {
$choices = str_replace( "\r\n", "\n", $choices );
$choices = str_replace( "\r", "\n", $choices );
$choices = ( false !== strpos( $choices, "\n" ) ) ? explode( "\n", $choices ) : (array) $choices;
foreach ( $choices as $choice ) {
$choice = trim( $choice );
if ( false !== ( $pos = strpos( $choice, ' : ' ) ) ) {
$array_key = substr( $choice, 0, $pos );
$array_value = substr( $choice, $pos + 3 );
$new_choices[ $array_key ] = $array_value;
}
else {
$new_choices[ $choice ] = $choice;
}
}
}
$field['options']['choices'] = $new_choices;
return $field;
}
}
「cfs_checkbox.php」をテンプレートと同じディレクトリにアップします。
functions.phpに下記コードを追記します。
PHP
<?php
add_filter('cfs_field_types', 'my_custom_field_type');
function my_custom_field_type($field_types){
$field_types['checkbox'] = get_theme_root().'/cfs_checkbox.php'; //cfs_checkbox.phpのURLを記述
return $field_types;
}
?>
ここまでくるとCustom Field Suiteの新規フィールドにチェックボックが追加されているので、チェックボックスを使ったカスタムフィールドを使うことができます。
値を表示させるコードのサンプルとして下記で表示できます。
PHP
<?php
$values = CFS()->get('フィールド名');
echo '<p>';
foreach ($values as $value) {
echo $value . '<br/>';
}
echo '</p>';
?>
レファレンスのオリジナルサイトが分からないのですが感謝いたします。
ブロックエディターが使えるようになったので、カスタムフィールドとブロックエディターを上手く使い分ける必要になってきますね。
Custom Field Suiteを使った応用
ウェブサイト制作案件などでたまに使うCustom Field Suiteの応用をいくつかご紹介します。
ループ画像からランダムに1枚だけ表示
ループで追加した複数の画像から、ランダムに1枚だけ表示したい場合があります。
ループが「cg_img_loop」で、画像用のカスタムフィールドが「cf_img」の場合は下記になります。
PHP
<?php
$cf_loop = $cfs->get('cf_works_img_loop');
$cf_loop_one = $cf_loop[array_rand($cf_loop)];
$cf_loop_one_image = $cf_loop_one['cf_works_img'];
echo '<figure><img src="' .$cf_loop_one_image. '"></figure>';
?>?>
以上でリロードされる度にランダムでループで設定した複数の画像からランダムで1枚表示されます。
ランダムには「array_rand」を使用していますが、shuffleやmt_randなどを使用することも可能です。
ランダムを複数回発生させる場合
デザインで複数の画像を無限横スクロールさせたりすることがあります。
下記は5回ランダムに画像を表示させています。
PHP
<?php
$cf_loop = $cfs->get('cf_works_img_loop');
for ($i=0;$i<5;$i++) {
$cf_loop_one = $cf_loop[array_rand($cf_loop)];
$cf_loop_one_image = $cf_loop_one['cf_works_img'];
echo '<figure><img src="' .$cf_loop_one_image. '"></figure>';
}
?>
先程の画像をランダムに取得することを5回繰り返しているだけです。
Custom Field Suiteのテクニックは随時追加していきますね。