WordPressで投稿タイトルをカスタムフィールドやタクソノミーから自動生成する方法

公開日
最終更新日
WordPress 投稿タイトルをカスタムフィールドやタクソノミーから自動生成

カスタムフィールドで内容を構成する記事では、投稿タイトルを手入力する必要がない(むしろ不要な)ことがあります。とはいえ、WordPressの管理上はタイトルがある方が扱いやすいものです。

結論から言うと、save_postフックで、カスタムフィールドの値やタクソノミーのタームからタイトルを組み立て、wp_update_post()で自動生成することができます。ただし、そのままだと無限ループに陥るため、その回避策もあわせて解説します。

実装コード

functions.phpに、次のコードを追記します。カスタム投稿タイプmenuで、タクソノミーmenucatのターム名と、カスタムフィールドinfo1〜3を組み合わせてタイトルを生成する例です。

function rename_post_title($post_id)
{
    global $post;

    $menucat_term      = wp_get_object_terms($post->ID, 'menucat'); // タクソノミーを使う場合はここで指定
    $menucat_term_name = $menucat_term[0]->name; // ターム名

    if ($post->post_type == 'menu') { // 投稿タイプの確認

        // タイトルになる文字列を生成
        $title = $menucat_term_name . ' / ' . get_post_meta($post_id, 'info1', true) . ' / ' . get_post_meta($post_id, 'info2', true) . ' / ' . get_post_meta($post_id, 'info3', true);

        // 現在のタイトルと異なる場合のみ更新
        if (get_the_title($post_id) !== $title) {

            // 自分をフック解除して無限ループを防ぐ
            remove_action('save_post', 'rename_post_title');

            // 生成したタイトルに書き換え
            wp_update_post(['ID' => $post_id, 'post_title' => $title]);

            // 自分を改めてフックする
            add_action('save_post', 'rename_post_title');
        }
    }
}

add_action('save_post', 'rename_post_title');

タクソノミーを使わず、カスタムフィールドの値だけでタイトルを作りたい場合は、ターム名の部分を外して$titleを組み立ててください。投稿タイプ名(menu)やフィールド名(info1など)は、実際の設定に合わせて置き換えます。

コードの中では、wp_get_object_terms()で投稿に紐づくタームを取得し、get_post_meta()でカスタムフィールドの値を取り出しています。これらを/でつなげて、1つのタイトル文字列にしています。

なお実運用では、自動保存やリビジョンの保存でもsave_postが発火します。必要に応じて、wp_is_post_revision()DOING_AUTOSAVEのチェックを加えておくと、意図しないタイミングでの実行を防げて安全です。

無限ループを防ぐのがポイント

このコードでいちばん重要なのが、無限ループの回避です。参考にした記事の通りに実装したところ、記事を更新すると読み込みが止まらず、いつまでも更新が終わらない状態になってしまいました。

原因は、save_postフックの中でwp_update_post()を呼んでいることにあります。wp_update_post()は投稿を保存する関数なので、これが再びsave_postを発火させ、またrename_post_title()が呼ばれ……と、処理が延々と繰り返されてしまうのです。

これを防ぐには、wp_update_post()を呼ぶ前に自分自身のフックを一度解除(remove_action)し、処理が終わったら改めてフックし直す(add_actionのが定石です。こうすることで、タイトル更新のための保存ではrename_post_title()が呼ばれなくなり、ループを断ち切れます。あわせて「現在のタイトルと異なる場合のみ更新する」条件も入れておくと、無駄な更新を避けられます。

まとめ

  • save_postフックで、カスタムフィールドやタームからタイトルを自動生成できる
  • wp_update_post()を使うとsave_postが再発火し、無限ループになる
  • 更新の前後でremove_actionadd_actionし、ループを防ぐ

タイトルを自動生成できると、入力の手間が減り、命名のばらつきもなくなります。カスタムフィールド主体の投稿を扱うときに、覚えておくと便利なテクニックです。

IPPEI FUKUTA(株式会社バッズブルー 代表)

IPPEI FUKUTA(株式会社バッズブルー 代表)

WordPress専門のWeb制作者として15年・150サイト以上を担当。現場でつまずいた問題と解決策を、同じ制作者・フリーランスの方に向けて発信しています。無料のWeb便利ツール集「バドツール」を開発・運営中。