Amazonで商品を見る セール会場へ

WordPress│編集記事下にCSSとJSの入力欄を追加する方法

投稿・固定ページごとにCSSとJavaScriptを保存し、そのページを表示するときだけ読み込みます。

入力できるのはmanage_options・unfiltered_html・対象記事の編集権限を持つ利用者だけです。

一般の投稿者へJavaScript入力を開放する用途には使いません。

目次

著者

WEB制作をしているデジタルノマド
WordPressのカスタマイズが好きで、色々と自作しています。

WordPressのカスタマイズに困ったらご相談ください!

導入前の確認

子テーマのfunctions.phpをバックアップし、既存のPHP領域へ下記を追加します。

先頭の<?phpは既にある場合は重ねません。

テーマに同等の機能がある場合はそちらに統一し、二重出力を避けます。

旧版のadd_custom_code_meta_box、save_custom_code_meta_box_data、output_custom_css、output_custom_jsと対応するフックは撤去してから置き換えてください。

旧custom_css/custom_jsは自動移行しません。

旧入力を確認してから新しい欄にコピーします。

コードは入力者を信頼して実行する仕組みで、JSの安全性を自動判定するものではありません。

マルチサイトなどでunfiltered_htmlがない利用者には欄を表示しません。

入力欄・保存・公開側の読み込み

<?php
function waza_code_allowed($id) {
    return current_user_can('manage_options') && current_user_can('unfiltered_html') && current_user_can('edit_post', $id);
}
function waza_code_valid($value) {
    return is_string($value) && !preg_match('~</(?:script|style)~i', $value);
}
add_action('add_meta_boxes', function ($type, $post) {
    if (!in_array($type, ['post', 'page'], true) || !waza_code_allowed($post->ID)) return;
    add_meta_box('waza-page-code', '記事専用 CSS / JS', function ($post) {
        wp_nonce_field('waza-code-' . $post->ID, 'waza_code_nonce');
        foreach (['css', 'js'] as $kind) {
            $value = get_post_meta($post->ID, '_waza_code_' . $kind, true);
            echo '<p><label for="waza-code-' . esc_attr($kind) . '">' . esc_html(strtoupper($kind)) . '</label></p>';
            echo '<textarea id="waza-code-' . esc_attr($kind) . '" name="waza_code_' . esc_attr($kind) . '" rows="8" style="width:100%">' . esc_textarea(is_string($value) ? $value : '') . '</textarea>';
        }
        echo '<p>タグを付けずにコードだけを入力します。script/style の終了タグを含む入力は保存されません。</p>';
    }, $type, 'normal', 'default');
}, 10, 2);
function waza_code_save($id) {
    if ((defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) || wp_is_post_revision($id) || wp_is_post_autosave($id)) return;
    if (!in_array(get_post_type($id), ['post', 'page'], true) || !waza_code_allowed($id)) return;
    if (!isset($_POST['waza_code_nonce']) || !is_string($_POST['waza_code_nonce']) || !wp_verify_nonce(wp_unslash($_POST['waza_code_nonce']), 'waza-code-' . $id)) return;
    $values = [];
    foreach (['css', 'js'] as $kind) {
        $key = 'waza_code_' . $kind;
        if (!isset($_POST[$key]) || !is_string($_POST[$key])) return;
        $values[$kind] = wp_unslash($_POST[$key]);
        if (!waza_code_valid($values[$kind])) return;
    }
    foreach ($values as $kind => $value) {
        // update_post_meta() が外すスラッシュを補い、JSのバックスラッシュを保つ。
        update_post_meta($id, '_waza_code_' . $kind, wp_slash($value));
    }
}
add_action('save_post', 'waza_code_save');
function waza_code_enqueue() {
    if (!is_singular(['post', 'page'])) return;
    $id = get_queried_object_id();
    $css = get_post_meta($id, '_waza_code_css', true);
    $js = get_post_meta($id, '_waza_code_js', true);
    if (waza_code_valid($css) && $css !== '') {
        wp_register_style('waza-page-code', false);
        wp_enqueue_style('waza-page-code');
        wp_add_inline_style('waza-page-code', $css);
    }
    if (waza_code_valid($js) && $js !== '') {
        wp_register_script('waza-page-code', false, [], null, true);
        wp_enqueue_script('waza-page-code');
        wp_add_inline_script('waza-page-code', $js);
    }
}
add_action('wp_enqueue_scripts', 'waza_code_enqueue');

CSS・JSはタグを付けずに入力します。

終了タグを含む入力、片方の欄が欠けた送信、nonce不一致などは両方とも保存せず以前の値を維持します。

保存後に編集画面を再読み込みして値を確認してください。

nonceだけで権限を判断せず、保存時にも権限と投稿種別を確認します。

終了タグの検査は、CSSやJavaScriptの構文チェックではありません。

構文が誤っていてもこの検査を通る場合があるため、欄に値が保存されたことと公開ページで正常に動いたことは分けて確認します。

保存後も動かない場合は入力内容を確認し、JavaScriptではブラウザーのコンソールにエラーが出ていないかを調べてください。

バックスラッシュを含むコードはwp_unslashでフォームのスラッシュを外し、update_post_metaの仕様に合わせてwp_slashを付けて保存します。

公開側では対象記事IDを使い、JSはwp_add_inline_scriptでフッターに追加します。

テーマのwp_head・wp_footerが必要です。

動作確認用のボタン

記事のカスタムHTMLブロックへ次を入れ、CSS・JSは新しい入力欄へ別々に貼り付けます。

CSSはこのクラスを持つ要素だけに適用します。

ページ単位の読み込みでもbodyなどを指定すればページ全体へ作用する点に注意してください。

<button type="button" class="waza-code-test">動作を確認</button>
.waza-code-test { border: 3px solid #a21d32; padding: .7em 1em; }
document.querySelectorAll('.waza-code-test').forEach(function (button) {
  button.addEventListener('click', function () {
    button.textContent = 'JavaScriptが動作しました';
  });
});

ボタン部分の動く見本

次のボタンは上のCSS・JSと同じ動作を記事内で表示したものです。

管理画面のメタボックス保存を検証する見本ではありません。

実際に保存して確認した結果

スクロールできます
確認した操作結果
記事専用CSS・JSを入力して保存再読み込み後も両欄を保持
公開側でボタンを操作PCのEnter・375px幅のSpaceで文字が変化
JS欄に終了タグを入力して保存CSS・JSとも以前の値を保持
両欄を空にして保存再読み込み後も空欄・公開側の追加枠と文字変更を解除
コードを入れていない別の記事専用CSS・JSの出力なし

SWELL標準の「カスタムCSS & JS」と、このコードで追加する「記事専用 CSS / JS」は別の入力欄です。

この記事の実装を使う場合は「記事専用 CSS / JS」の欄へ入力し、同じコードを両方の欄へ重複して入れないでください。

2026年10月2日、WordPress 7.1.2・SWELL 2.19.0の単一サイトで管理者による保存を確認しました。

2026年10月4日の隔離環境での実HTTP出力では、コードを保存した個別ページにCSS・JSがそれぞれ1回出力され、その記事を含む一覧ページには出力されないことを確認しました。

一覧に記事本文や抜粋が表示されても、この記事専用コードが一覧へ引き継がれる仕組みではありません。

ビジュアルエディター本文の描画、マルチサイト、Pjaxとの組み合わせは未検証です。

隔離WordPressで記事専用JavaScriptを実行しボタンの文字が変わった画面
2026年10月2日撮影:隔離WordPressの編集画面で保存したCSS・JSによるボタン操作の結果。

確認と解除

保存後は編集画面を再読み込みして、CSS・JS両方の値が残っていることを先に確認します。

公開側では枠とボタンの文字変化を確認し、Tabで移動してEnterとSpaceでも操作します。

別の記事と一覧ページへの読み込み、PC・スマホの横はみ出しも導入環境で確認してください。

解除するときはCSS・JS両方の欄を空にして記事を更新します。

仕組み自体を外す場合は追加した関数とフックをまとめて削除し、functions.phpを元へ戻します。

保存済みメタ値は仕組みを外しても残りますが、このコードからは出力されません。

キャッシュを使う場合は更新後に対象ページのキャッシュも更新してください。

旧記事のGitHubサンプルとスクリーンショットは今回の権限チェック付き実装に同期していません。

本文のコードを使用してください。

  • URLをコピーしました!

実装を任せたい方へ

WordPressのカスタマイズ代行

ブロックの追加、テーマの改修、管理画面の調整など、記事で紹介している内容の実装を承ります。1時間 ¥8,000〜(税込)。

WAZAの有料記事のサブスクリプションも開始しました。

サービス

Service

WordPressサイトのカスタマイズのサービスに関心がありましたら、ぜひ詳細をご覧ください。

目次