【WordPress】記事ごとにCSSなどを記述できるカスタムフィールドを追加

全てをstyle.cssに書き連ねると……

昔は少数の記事でしか使わないCSSも全て子テーマのstyle.cssに記述していたため、ずっと前に運営していたWordPressブログでは、気付いたら子テーマのstyle.cssが数千行という大きさになっていたりしました。
きちんと整理して記述してあればまだ良かったのですが、どの部分がどの記事に使われているのかもよくわからないという有様で、さすがにまずいと思って色々検索してみた結果、記事ごとにCSSやJSなどを記述できるカスタムフィールドを実装することに。

当時は<head>内に出力するための簡単なカスタムフィールドを追加して使っていたのですが、</body>直前に出力したかったり、インラインでCSSを記述したいことがわりとあって、すごく使い勝手が良いとまではいきませんでした。

そこで現在は、</head>直前・その手前(<style> </style>の間に出力)・</body>手前、の3か所に記述できるカスタムフィールドを実装しています。(↓こちらの記事で紹介されているものをカスタマイズして使用させてもらっています)

参考 「この記事だけで使うCSS、JavaScript」をカスタムフィールドで記述するためのカスタマイズぺらラボ

実装したイメージ

子テーマの「function.php」に以下を追加すると、投稿画面の記事入力欄下にこんなカスタムフィールドが現れます。
カスタムフィールド

各カスタムフィールドの挙動

一番上の「ADD to head」

ここに記述したものは、そのページの</head>直前に出力されます。

真ん中の「ADD CSS」

ここに記述したものは「ADD to head」の挿入場所のすぐ手前に出力されます。(「ADD to head」が空の場合は</head>直前に入ります)
<style></style>に挟まれて出力されるので、直接CSSを記述することができます。

一番下の「ADD to body」

ここに書いたものは、そのページの</body>直前に出力されます。

実装する方法

子テーマの function.php に以下を記述するだけです。

注意
子テーマまたは該当ファイルがない場合は、新しく作成してください。
バックアップを取ってから作業することをおすすめします。

こちらはHTML5で記述されているので、XHTMLのテーマをお使いの方には参考リンク先のオリジナルのものの方がおすすめです。

function.php

//ページごとにhead内に追記するカスタムフィールド
add_action(
	'add_meta_boxes', 
	function(){
		$screens = array('post', 'page');
		foreach($screens as $scrn){
			add_meta_box(
				'peralab-custombox-css-internal',
				'この記事に追加',
				'PeralabCssInternal_CustomBoxCreate',
				$scrn,
				'normal',
				'default',
				null);
		}
	}
);

//メタボックスを作成
function PeralabCssInternal_CustomBoxCreate($post){
	$data_str = get_post_meta($post->ID, "metakey_css", true);
	$ext_str = get_post_meta($post->ID, "metakey_ext", true);
	$body_str = get_post_meta($post->ID, "metakey_body", true);
	//if($data_str == ''){}	
	wp_nonce_field('action-noncekey-css-internal', 'noncename-css-internal');

	?>
	<div>	
	<p><label>ADD to head<br>
	<textarea id="id-metabox_ext_textarea" name="name-metabox_ext_textarea" rows="5" cols="30" style="width:100%;"><?php echo esc_attr($ext_str); ?></textarea>
	</label></p>

	<p><label>ADD CSS<br>
	<textarea id="id-metabox_css_textarea" name="name-metabox_css_textarea" rows="5" cols="30" style="width:100%;"><?php echo esc_attr($data_str); ?></textarea>
	</label></p>

	<p><label>ADD to body<br>
	<textarea id="id-metabox_body_textarea" name="name-metabox_body_textarea" rows="5" cols="30" style="width:100%;"><?php echo esc_attr($body_str); ?></textarea>
	</label></p>	
	</div>
	<?php
}

//カスタムボックス内のフィールド値更新処理
add_action(
	'save_post', 
	function($post_id){
		if(isset($_POST['noncename-css-internal']) == false 
				|| wp_verify_nonce($_POST['noncename-css-internal'], 'action-noncekey-css-internal') == false) {
			return;
		}
		if(defined('DOING_AUTOSAVE') && DOING_AUTOSAVE){
			return;
		}
		if(isset($_POST['post_type'])){
			if($_POST['post_type'] == 'page'){
				if(!current_user_can('edit_page', $post_id)){
					return;
				}
			}
			else{
				if(!current_user_can('edit_post', $post_id)){
					return;
				}
			}
		}
		
		if(isset($_POST['name-metabox_css_textarea'])){
			update_post_meta($post_id, "metakey_css", $_POST['name-metabox_css_textarea']);
		}
		if(isset($_POST['name-metabox_ext_textarea'])){
			update_post_meta($post_id, "metakey_ext", $_POST['name-metabox_ext_textarea']);
		}
		if(isset($_POST['name-metabox_body_textarea'])){
			update_post_meta($post_id, "metakey_body", $_POST['name-metabox_body_textarea']);
		}
	}
);

//出力用のアクションフックを登録
add_action(
	'wp_head',
	function(){
		if(is_single() == false && is_page() == false){
			return;
		}		
		$data_str = get_post_meta(get_the_ID(), "metakey_css", true);
		if($data_str != '' && ctype_space($data_str) == false){
			echo '<style>' . PHP_EOL . $data_str . PHP_EOL . '</style>' . PHP_EOL;
		}		
		$data_str = get_post_meta(get_the_ID(), "metakey_ext", true);
		if($data_str != '' && ctype_space($data_str) == false){
			echo $data_str . PHP_EOL;
		}
	},
	1000
);

add_action(
	'wp_footer',
	function(){
		if(is_single() == false && is_page() == false){
			return;
		}		
		$data_str = get_post_meta(get_the_ID(), "metakey_body", true);
		if($data_str != '' && ctype_space($data_str) == false){
			echo $data_str . PHP_EOL;
		}
	},
	1000
);