WordPress 独自カスタムフィールドをfunctions.phpに記述する方法
WordPressで独自のカスタムフィールドをfunctions.phpに記述する方法です。
カスタムフィールドを利用すれば、タイトル・本文以外の入力フィールドが追加できます。これから紹介する方法はプラグインなしで、PHPを書いてカスタムフィールドを追加しようというものです。ちょっと玄人向けの記事になりますかね。
カスタムフィールドを便利に使えるようにできるプラグインはたくさんあります。有名なのは「Advanced Custom Fields」ですね。筆者もよく使うプラグインです。
今回、この記事を書こうと思ったきっかけは、「All in One SEO」というプラグインを停止しようと思ったからです。「All in One SEO」は、とても高機能で優秀なプラグインではありますが、正直、バージョン4.0.0以降は使いにくくなったし、脆弱性も確認されたし、謎のログがテーブルに膨大に蓄積されるし、なんといっても遅いし。ならば停止して、独自実装してしまおうと考えました。なので「タイトル(title)」「説明(description)」「キーワード(keywords)」のカスタムフィールドで追加する方法がメインとなります。プラグインは使いません。
ここでは WordPressで独自のカスタムフィールドをfunctions.phpに記述する方法 を紹介します。
Sponsored Links
目次
完成イメージ
完成イメージは下記のとおりです。SEO設定というボックス内に、「タイトル(title)」「説明(description)」「キーワード(keywords)」のカスタムフィールドが追加されます。
見ての通り、デザインは「All in One SEO」プラグインを参考にしています。
Sponsored Links
カスタムフィールドを追加する
今回は、固定ページと投稿ページにカスタムフィールドの入力を追加します。
フィールドの定義
各フィールドの定義は下記のようになります。
- タイトル:my_seo_title テキストボックス
- 説明:my_seo_description テキストエリア
- キーワード:my_seo_keywords テキストボックス
functions.php
下記のコードを「function.php」へコピペします。
/** * 投稿と固定ページにカスタムフィールドを追加 */ add_action( 'admin_menu', 'add_my_custom_field' ); function add_my_custom_field() { $screens = array( 'post', 'page' ); foreach ( $screens as $screen ) { add_meta_box( 'my_seo', 'SEO設定', 'add_my_seo_fields', $screen, 'normal' ); } } // カスタムフィールドのHTMLを追加する時の処理 function add_my_seo_fields() { global $post; $title_name = "my_seo_title"; $description_name = "my_seo_description"; $keywords_name = "my_seo_keywords"; // nonceの追加 wp_nonce_field( 'action-'.$title_name, 'nonce-'.$title_name ); wp_nonce_field( 'action-'.$description_name, 'nonce-'.$description_name ); wp_nonce_field( 'action-'.$keywords_name, 'nonce-'.$keywords_name ); // 値を取得 $title_value = get_post_meta($post->ID, $title_name, true); $description_value = get_post_meta($post->ID, $description_name, true); $keywords_value = get_post_meta($post->ID, $keywords_name, true); // html作成 $fields = '<div class="myseo-content">'; $fields .= ' <div class="myseo-settings-row myseo-row">'; $fields .= ' <div class="myseo-col col-xs-12 col-md-3 text-xs-left">'; $fields .= ' <div class="settings-name">'; $fields .= ' <div class="name align">タイトル</div>'; $fields .= ' </div>'; $fields .= ' </div>'; $fields .= ' <div class="myseo-col col-xs-12 col-md-9 text-xs-left">'; $fields .= ' <div class="settings-content">'; $fields .= ' <div class="myseo-input">'; $fields .= ' <input type="text" class="medium" name="'.$title_name.'" value="'.$title_value.'">'; $fields .= ' </div>'; $fields .= ' <div class="myseo-description">ほとんどの検索エンジンのタイトルは最大 60 文字です。</div>'; $fields .= ' </div>'; $fields .= ' </div>'; $fields .= ' </div>'; $fields .= ' <div class="myseo-settings-row myseo-row">'; $fields .= ' <div class="myseo-col col-xs-12 col-md-3 text-xs-left">'; $fields .= ' <div class="settings-name">'; $fields .= ' <div class="name align">説明</div>'; $fields .= ' </div>'; $fields .= ' </div>'; $fields .= ' <div class="myseo-col col-xs-12 col-md-9 text-xs-left">'; $fields .= ' <div class="settings-content">'; $fields .= ' <div class="myseo-input">'; $fields .= ' <textarea class="myseo-textarea" rows="5" cols="8" name="'.$description_name.'">'.$description_value.'</textarea>'; $fields .= ' </div>'; $fields .= ' <div class="myseo-description">ほとんどの検索エンジンの説明は最大 160 文字です。</div>'; $fields .= ' </div>'; $fields .= ' </div>'; $fields .= ' </div>'; $fields .= ' <div class="myseo-settings-row myseo-row">'; $fields .= ' <div class="myseo-col col-xs-12 col-md-3 text-xs-left">'; $fields .= ' <div class="settings-name">'; $fields .= ' <div class="name align">キーワード</div>'; $fields .= ' </div>'; $fields .= ' </div>'; $fields .= ' <div class="myseo-col col-xs-12 col-md-9 text-xs-left">'; $fields .= ' <div class="settings-content">'; $fields .= ' <div class="myseo-input">'; $fields .= ' <input type="text" class="medium" name="'.$keywords_name.'" value="'.$keywords_value.'" placeholder="ホームページ,制作,墨田区,Webデザイン">'; $fields .= ' </div>'; $fields .= ' <div class="myseo-description">カンマ区切りで入力します。</div>'; $fields .= ' </div>'; $fields .= ' </div>'; $fields .= ' </div>'; $fields .= '</div>'; echo $fields; } // カスタムフィールドの値を保存 add_action('save_post', 'save_seo_fields'); function save_seo_fields( $post_id ) { $fields = array('my_seo_title', 'my_seo_description', 'my_seo_keywords' ); foreach( $fields as $field ) { if ( isset( $_POST['nonce-'.$field] ) && $_POST['nonce-'.$field] ) { // リクエストが有効な nonce を持っているかチェック if ( check_admin_referer( 'action-'.$field, 'nonce-'.$field ) ) { if ( isset( $_POST[$field] ) && $_POST[$field] ) update_post_meta( $post_id, $field, $_POST[$field] ); else delete_post_meta( $post_id, $field, get_post_meta( $post_id, $field, true ) ); } } } } /** * 管理画面にCSSファイルを読み込む */ add_action( 'admin_enqueue_scripts', 'my_admin_style' ); function my_admin_style(){ wp_enqueue_style( 'my_admin_style', get_template_directory_uri().'/css/seo.css' ); }
簡単に説明すると「add_meta_box」関数を使って独自のカスタムフィールドの追加し、callback関数でhtmlを出力しています。
add_meta_box( $id, $title, $callback, $screen, $context, $priority, $callback_args );
途中、「wp nonce field」関数にて、hiddenを追加する記述をしています。これは、不正なリクエストではないことを認証するために使われます。
wp_nonce_field( $action, $name, $referer, $echo );
保存前には「check_admin_referer」関数を使って、リクエストが有効かテストをおこない、テーブルへ保存します。
seo.css
下記のコードをCSSファイルに記述します。場所はどこでも構いません。PHP側の「my_admin_style」関数でパスを調整してください。
今回はテーマのルートにcssフォルダを作って、その中に「seo.css」というファイルを新規に作っています。
/* * 管理画面カスタムフィールド用 */ .myseo-content { background: #fff; border-top: 0; padding: 15px; } .myseo-settings-row { margin-bottom: 16px; padding-bottom: 16px; } .myseo-row { box-sizing: border-box; display: flex; flex: 0 1 auto; flex-direction: row; flex-wrap: wrap; margin-right: -0.5rem; margin-left: -0.5rem; } .myseo-settings-row { margin-bottom: 22px; padding-bottom: 16px; border-bottom: 1px solid #E8E8EB; } .myseo-settings-row:last-of-type { margin-bottom: 0; padding-bottom: 0; border-bottom: 0; } @media only screen and (min-width: 912px) { .myseo-col.col-md, .myseo-col.col-md-1, .myseo-col.col-md-2, .myseo-col.col-md-3, .myseo-col.col-md-4, .myseo-col.col-md-5, .myseo-col.col-md-6, .myseo-col.col-md-7, .myseo-col.col-md-8, .myseo-col.col-md-9, .myseo-col.col-md-10, .myseo-col.col-md-11, .myseo-col.col-md-12, .myseo-col.col-md-offset-0, .myseo-col.col-md-offset-1, .myseo-col.col-md-offset-2, .myseo-col.col-md-offset-3, .myseo-col.col-md-offset-4, .myseo-col.col-md-offset-5, .myseo-col.col-md-offset-6, .myseo-col.col-md-offset-7, .myseo-col.col-md-offset-8, .myseo-col.col-md-offset-9, .myseo-col.col-md-offset-10, .myseo-col.col-md-offset-11, .myseo-col.col-md-offset-12 { box-sizing: border-box; flex: 0 0 auto; padding: 0.5rem; } } @media only screen and (min-width: 912px) { .myseo-col.col-md-3 { flex-basis: 25%; max-width: 25%; } } .myseo-col.text-xs-left { text-align: left !important; justify-content: flex-start; } .myseo-settings-row .settings-name { color: #141B38; } .myseo-settings-row .settings-name .name.align { line-height: 40px; } .myseo-settings-row .settings-name .name { font-weight: 600; font-size: 14px; display: flex; align-items: center; } @media only screen and (min-width: 912px) { .myseo-col.col-md-9 { flex-basis: 75%; max-width: 75%; } } .myseo-settings-row .settings-content { font-size: 14px; } .myseo-description { font-size: 12px; line-height: 1.8; margin: 8px 0 0; color: #141B38; } .myseo-input { position: relative; width: 100%; } .myseo-input input.medium { height: 40px; padding: 12px; font-size: 14px; } .myseo-input input { height: 48px; width: 100%; background-color: #fff; border: 1px solid #D0D1D7; border-radius: 3px; padding: 15px; font-size: 16px; position: relative; overflow: hidden; margin: 0; } .myseo-input textarea { min-height: 36px; width: 100%; background-color: #fff; border: 1px solid #D0D1D7; border-radius: 4px; padding: 10px; font-size: 14px; margin: 0; }
カスタムフィールドを表示する
投稿ページで保存した内容
記入した内容はこんな感じです。
header.php
header.phpへ下記を追記します。既存のtitleタグや、descriptionとkeywordsのmetaタグはコメントアウトしてください。
<?php if( is_page() || is_single() ) { //固定ページ・シングルページ ?> <title><?php echo get_post_meta($post->ID, 'my_seo_title', true); ?></title> <meta name="description" content="<?php echo get_post_meta($post->ID, 'my_seo_description', true); ?>"> <meta name="keywords" content="<?php echo get_post_meta($post->ID, 'my_seo_keywords', true); ?>"> <?php } else { //トップページ・その他 ?> <title><?php wp_title('|',true,'right'); bloginfo('name'); ?></title> <meta name="description" content="<?php bloginfo('description'); ?>"> <meta name="keywords" content="ホームページ,制作,墨田区,Webデザイン"> <?php } ?>
表示の確認
ふむ、開発者ツールで出力が確認できました。
Sponsored Links
まとめ
WordPressで独自のカスタムフィールドをfunctions.phpに記述する方法を紹介しました。
これで「All in One SEO」で使っていたフィールドは用意できました。記事数が多いので、すでに「All in One SEO」のフィールドに設定したタイトル・説明・キーワードを、どう移行するかが課題ですかね。これから検討します。
追記:All in one SEOからの移行
すでに「All in One SEO」のフィールドに設定したタイトル・説明・キーワードを、どう移行するかって課題についての追記です。
結局、データ移行ではなく独自SEO設定がなくてAll in one SEOに設定があれば表示するという方法をとることにしました。
funciton.phpのadd_my_seo_fields関数で「値を取得」ってやっているところを下記のコードに書き換えれば完了です。
// 独自SEO設定がなく、All in one SEOに設定があれば表示する $title_value = ( empty(get_post_meta($post->ID, $title_name, true)) ) ? get_post_meta($post->ID, '_aioseop_title', true) : get_post_meta($post->ID, $title_name, true); $description_value = ( empty(get_post_meta($post->ID, $description_name, true)) ) ? get_post_meta($post->ID, '_aioseop_description', true) : get_post_meta($post->ID, $description_name, true); $keywords_value = ( empty(get_post_meta($post->ID, $keywords_name, true)) ) ? get_post_meta($post->ID, '_aioseop_keywords', true) : get_post_meta($post->ID, $keywords_name, true);
3.0系は「aioseop_」、4.0系は「aioseo_」にて取得できる。
詳しくは「All in One SEOで設定した値を取得する方法」で紹介しているのでチェックしてみてください。
おつかれさまでした。
Sponsored Links