WordPressの保守i-Willink
WordPressのテーマ更新で設定が消える原因と対策
WordPressのテーマを入れ直すと、ロゴや写真などカスタマイザーの設定が初期値に戻ることがあります。原因は設定の保存先がテーマのフォルダ名に結びついていることです。仕組みと、フォルダ名を固定する対策、引き継ぎの安全網をまとめます。
カスタマイザーの設定は「theme_mods_テーマのフォルダ名」という名前で保存されます。フォルダ名が変わると別の保存先を読むので、設定が消えたように見えます。フォルダ名を固定すれば起きません。
「テーマを更新したら、トップの写真が古いものに戻った」。WordPressのサイトを保守していると、ときどき出会う事象です。ロゴ、トップ画像、色、電話番号など、カスタマイザーで設定した値が、テーマを入れ直したのを境に一斉に初期値に戻ります。
WordPressの不具合と思われがちですが、実際は設定の保存の仕組みから来る、再現できる問題です。この記事では、私たちが保守しているサイトで実際に直したときの原因と対策を書きます。
この記事の要点
- 1カスタマイザーの設定は、テーマのフォルダ名を含む名前で保存される。フォルダ名が変わると設定を見失う
- 2本命の対策は、フォルダ名に版の番号を入れず固定し、更新は同じフォルダへの上書きにすること
- 3それでも名前が変わったときに備え、テーマの切り替え時に直前のテーマから設定を写す安全網を入れる
原因: 設定の保存先がフォルダ名に結びついている
設定は「theme_mods_」に、有効なテーマのフォルダ名をつなげた名前で保存されます。フォルダ名が変わると、空の保存先を読みにいきます。
カスタマイザーの値は、WordPress のデータベースの設定表(options)に、まとめて1行で保存されます。公式のリファレンスにある get_theme_mods 関数の中身を見ると、保存先の名前は「theme_mods_」に、有効なテーマのフォルダ名(stylesheet という設定値)をつなげたものです。
ここで、テーマを my-theme-1.5.0 から my-theme-1.5.1 のように、版の番号つきのフォルダ名で入れ直すと何が起きるか。保存先の名前も theme_mods_my-theme-1.5.0 から theme_mods_my-theme-1.5.1 に変わります。新しい名前の保存先にはまだ何も入っていないので、画面は初期値に戻ります。古い設定は消えたのではなく、前の名前のまま残っています。
対策1: フォルダ名を固定する
テーマのフォルダ名に版の番号を入れず、いつも同じ名前のフォルダに上書きします。版の番号はテーマの説明ファイルと変更履歴で管理します。
いちばん確実なのは、原因そのものをなくすことです。テーマのフォルダ名を版に関係のない固定の名前にし、更新は同じフォルダへの上書きにします。版の番号は、テーマの style.css にある Version の欄と、変更履歴(git)の目印で管理します。
こうすれば保存先の名前はずっと変わらないので、更新で設定が戻ることは起きません。テーマを圧縮ファイルで配るときも、中のフォルダ名が固定になっているかを確かめます。
対策2: 切り替え時に設定を写す安全網
フォルダ名が変わってしまったときに備え、テーマを切り替えた直後に、直前のテーマの設定を新しい保存先へ写す処理を入れておきます。
運用の手違いでフォルダ名が変わることもあります。その備えとして、after_switch_theme というフックを使います。公式のリファレンスによると、このフックはテーマを切り替えたあとの次の読み込みで動き、直前のテーマの名前と、直前のテーマそのもの(WP_Theme)を渡してくれます。
考え方を最小の形にすると、次のようになります。新しい保存先が空のときだけ、直前のテーマの設定を写します。下の例は1段目だけで、直前のテーマも空だったときに最新の版を探す処理は省いています。
add_action( 'after_switch_theme', function ( $old_name, $old_theme ) {
$new = get_option( 'stylesheet' );
if ( get_option( 'theme_mods_' . $new ) ) {
return; // すでに設定があれば何もしない
}
$old = get_option( 'theme_mods_' . $old_theme->get_stylesheet() );
if ( $old ) {
update_option( 'theme_mods_' . $new, $old );
}
}, 10, 2 );気をつけたいのは、写す元の選び方です。「最初に見つかった theme_mods を写す」と素朴に作ると、古い版の設定を拾って、古い写真に戻す事故が起きます。私たちは、WordPress が渡す直前のテーマを第一に使い、それが空のときだけ、設定の入っている版のうち番号がいちばん新しいものを選ぶようにしました。
検証: 実際にテーマを切り替えて確かめる
「設定が消えない」は、実際にテーマを切り替えないと確かめられません。手元の検証用の WordPress で3つの場面を試しました。
WordPress が用意している検証用の環境(@wordpress/env、通称 wp-env)を手元で立ち上げ、実際にテーマのフォルダを複製して有効化し、次の3つの場面で引き継ぎの動きを確かめました。
- 固定の名前のフォルダに切り替えたとき、直前のテーマから設定が引き継がれる
- 直前のテーマの設定が空でも、設定の入っている最新の版が選ばれる(古い版は選ばない)
- 同じ固定のフォルダに上書きしても、設定が保たれる
本番のサイトで試す前に、手元で壊して確かめられる環境があると、こうした仕組みの不具合を安全に直せます。
よくある質問
設定が消えてしまったら、元に戻せますか?
古い設定は前のフォルダ名の保存先に残っていることが多いので、その値を新しい保存先へ写せば戻せます。作業の前には、データベースのバックアップを取っておきます。
子テーマを使っていても同じことが起きますか?
保存先の名前は有効なテーマのフォルダ名で決まるので、子テーマを使っている場合は子テーマのフォルダ名が変わると同じことが起きます。子テーマの名前も固定にしておきます。
公式ディレクトリのテーマを自動更新した場合も起きますか?
公式ディレクトリからの更新は通常、同じフォルダへの上書きなので、フォルダ名は変わりません。起きやすいのは、自作や配布されたテーマを、版の番号つきのフォルダで入れ直す場合です。
ウィジェットやメニューの設定も消えますか?
メニューの場所の割り当てなどはテーマごとの設定に含まれるため、同じ影響を受けることがあります。入れ直したあとは、カスタマイザーとあわせてメニューやウィジェットも確かめます。
参考・出典
- get_theme_mods()(WordPress Developer Resources)(保存先の名前が「theme_mods_」と有効なテーマのフォルダ名から作られること)
- after_switch_theme(WordPress Developer Resources)(テーマの切り替え後に動き、直前のテーマを渡すフック)