【WordPress】apartment morning実装のハマりどころ、4つ



「apartment morningを支える設計判断」の続きです。今回は、作りながら実際にぶつかった落とし穴を4つ紹介します。WordPressの標準機能が思わぬところで悪さをする話が中心です。
WordPress標準の「404救済機能」が別作品の同じ番号の篇を誤爆
apartment morningでは、篇の通し番号が作品ごとに01から始まる設計です。複数作品で「02」という番号が重複するのは仕様どおりなのですが、ここでWordPress標準のwp_guess_404_permalink()という機能に足をすくわれました。
これは「404のときに近い投稿を推測してリダイレクトする」機能なのですが、post_typeとpost_nameだけで検索してしまい、独自のメタ絞り込み(_am_work)を一切見ていませんでした。結果、未公開の2作目「02」にアクセスすると404になり、そこから1作目の「02」へ301リダイレクトされる、という事故が起きました。
wp_redirectフィルタにwp_debug_backtrace_summary()を仕込んでスタックトレースを追い、原因の関数を特定。最終的にはpre_redirect_guess_404_permalink(WP 5.5以降のフィルタ)でこの推測機能自体を無効化して解決しました。
同じバグの兄弟:wp_unique_post_slugの暗黙のグローバル一意性
原因は上と同じでした。2作目の「01」を投稿した瞬間、WordPressが勝手にスラッグを「01-2」にリネームしていたのです。スラッグの一意性チェックが投稿タイプ単位でしか見ておらず、カスタムメタでの作品区別を知らないために起きていました。
こちらもフィルタでam_episodeのスラッグ重複回避そのものを無効化して解決しています(URLの一意性はルーティング側で別途担保しているので問題ありません)。
CSS詳細度の落とし穴
クライマックス篇用に「円を2つ出す」機能を追加したとき、新しい修飾クラス.am-orb--bokuの位置指定が、ベースクラス.am-orbに負けて無視されるという古典的なバグを踏みました。詳細度は同じなのに、ファイル内で後に書かれているベースクラスが勝ってしまう、というパターンです。
/* Before:詳細度が同じで、あとに書かれた方が勝つ */
.am-orb--boku { left: 60%; }
.am-orb { left: 40%; }
/* After:複合セレクタで詳細度を上げる */
.am-orb.am-orb--boku { left: 60%; }
複合セレクタにして詳細度そのものを上げることで解決しました。CSSの「後に書いた方が勝つ」は、詳細度が完全に同じときだけの話、というのを再確認させられました。
キャッシュ層がコード修正の反映を妨げる
アセットのバージョン文字列を固定値”1.0″からfilemtime()ベースに変えて、ブラウザキャッシュ対策をしました。ところがAutoptimizeが生成するハッシュ付きCSSバンドル自体は、これだけでは自動追従しないことがありました。
「CSSを直したのに反映されない」の犯人がここで、autoptimizeCache::clearall()を明示的に叩く必要がある場面が何度かありました。キャッシュは1層だけじゃない、ということを思い出させてくれるバグです。
さいごに
今回の4つは、どれも「WordPressの標準機能が思ったより広い範囲を見ている」というのが原因でした。次回はデータ設計、特に原稿とリナンバリングの話をまとめます。





