【WordPress】タイトルの入力チェックを実装する方法|wp_insert_post_dataで確実にサーバー側検証

投稿のタイトルが短すぎる・未入力のまま公開されてしまうのを防ぎたい場面があります。この記事では、ブラウザ側のJavaScriptに頼らず、サーバー側で確実に検証する方法を解説します。

この記事でわかること

  • JavaScriptだけの検証が信頼できない理由
  • wp_insert_post_data で公開時にタイトルの文字数をチェックする方法
  • チェックに引っかかった場合に管理画面へ通知を表示する方法
スポンサーリンク

なぜサーバー側での検証が必要か

JavaScriptだけの検証は「動かない」うえに「迂回できる」
よくある実装例として、管理画面でタイトル入力を監視するjQueryを wp_enqueue_scripts フックで読み込む方法が紹介されていることがありますが、wp_enqueue_scripts はフロントエンド専用のフックで、管理画面では発火しませんwp_head() 内で呼ばれる仕組みのため)。管理画面用のスクリプトを読み込むには admin_enqueue_scripts を使う必要があります。さらに、旧クラシックエディタの #title という要素IDは、現行のブロックエディタには存在しませんeditor-post-title__input というリッチテキスト要素に置き換わっています)。たとえフックとセレクタを両方直しても、JavaScriptによる検証はブラウザの開発者ツールで簡単に無効化・迂回できるため、確実性が必要な検証には向きません。本当に検証を強制したい場合は、サーバー側(PHP)で行う必要があります

wp_insert_post_dataで公開時にタイトルの文字数をチェックする(推奨)

wp_insert_post_data フィルターを使うと、投稿が保存される直前にデータを検査・変更できます。公開しようとした際にタイトルが短すぎる場合は、強制的に下書きへ差し戻します

functions.php:公開時にタイトルの文字数をチェック
function validate_title_length_on_publish( $data, $postarr ) {
    $min_length = 10; // タイトルに必要な最小文字数

    // 公開しようとしている場合のみチェック(下書き保存時は妨げない)
    if ( 'publish' !== $data['post_status'] ) {
        return $data;
    }

    // 投稿タイプを限定したい場合はここでチェック(例: 'post'のみ対象)
    if ( 'post' !== $data['post_type'] ) {
        return $data;
    }

    $title_length = mb_strlen( trim( wp_strip_all_tags( $data['post_title'] ) ) );

    if ( $title_length < $min_length ) {
        $data['post_status'] = 'draft'; // 公開を許可せず下書きに戻す

        // 次回の管理画面表示で通知するためのフラグを保存
        set_transient( 'title_validation_error_' . get_current_user_id(), $min_length, 30 );
    }

    return $data;
}
add_filter( 'wp_insert_post_data', 'validate_title_length_on_publish', 10, 2 );
公開時だけをチェックする理由
post_statuspublish のときだけチェックすることで、下書き保存中(自動保存を含む)は妨げず、「公開」ボタンを押した瞬間だけ検証が働くようにしています。書きかけの短いタイトルのまま下書き保存できないと、執筆の邪魔になってしまうためです。

管理画面に警告メッセージを表示する

タイトルが短くて下書きに差し戻された場合、なぜ公開されなかったのかが分からないと混乱するため、管理画面に通知を表示します。

functions.php:タイトル不足を管理画面に通知
function show_title_validation_notice() {
    $min_length = get_transient( 'title_validation_error_' . get_current_user_id() );

    if ( false === $min_length ) {
        return;
    }

    delete_transient( 'title_validation_error_' . get_current_user_id() );
    ?>
    <div class="notice notice-error is-dismissible">
        <p><?php printf( esc_html__( 'タイトルは%d文字以上入力してください。下書きとして保存されました。', 'textdomain' ), esc_html( $min_length ) ); ?></p>
    </div>
    <?php
}
add_action( 'admin_notices', 'show_title_validation_notice' );

動作確認

  • タイトルを9文字以下にして「公開」を押すと、公開されず下書きのままになり、管理画面に警告が表示されること
  • タイトルを10文字以上にして「公開」を押すと、通常どおり公開できること
  • タイトルが短いままでも「下書き保存」は問題なくできること

よくある質問(FAQ)

Q文字数の基準を投稿タイプごとに変えたいです。
A$postarr['post_type']で投稿タイプを判定し、投稿タイプごとに$min_lengthの値を切り替える条件分岐を追加します。
Qタイトルなしで投稿を保存するとスラッグはどうなりますか?
AWordPressはpost_idを元に自動でスラッグを生成します(例: /?p=123)。パーマリンク設定によってはURLが数字ベースになります。後から手動でスラッグを設定することもできます。
QJavaScriptによるリアルタイム表示(あと何文字か等)は不要ですか?
A執筆中に文字数を都度確認できるUXは便利ですが、あくまで補助的な表示にとどめ、実際の強制は必ずサーバー側(wp_insert_post_data)で行うのが安全です。JavaScriptを実装する場合はadmin_enqueue_scriptsを使い、$hook_suffixで投稿編集画面(post.php/post-new.php)に限定してください。

まとめ

  • 避ける:JavaScriptだけの検証(迂回可能・フック/セレクタの誤りで動かないことも)
  • 推奨wp_insert_post_dataで公開時に強制的にチェック
  • あわせてadmin_noticesで理由を通知する

入力チェックを「本当に強制したい」場合は、必ずサーバー側で実装しましょう。