公開済みのHTMLが何十本もあるとき、内容の一部だけを一括で差し替えたい場面がある。手編集はミスの元、単純な文字列置換は事故の元。実際に運用している「マーカーコメント+冪等+dry-run」の型を、最小のコード例で書く。
手編集ゼロで公開済みファイルを安全に一括更新するためのマーカーコメント設計と、何度実行しても壊れないことを保証する冪等+dry-runの型。
公開中の記事が数十本ある状態で、共通のブロック(広告・CTA・注記など)を全部に挿入したり、既存のリンクを書き換えたりする作業は、地味だが頻度が高い。1本ずつ手で開いて編集するのは非現実的だし、単純な文字列置換スクリプトを流すのも危険が伴う。
危険なのは「全ファイルが同じ状態のはず」という前提だ。実際には、すでに手動で編集済みのファイルや過去に別バージョンのブロックが入っているファイルが紛れ込んでいることがある。ここに無条件の置換をかけると、二重挿入や上書き事故が起きる。実際に運用しているのは、この前提を疑ってかかる3点セットの型だ。
Kindle書籍のCTAブロックを公開済み記事に一括挿入するスクリプトを例に、実際の構成を書く。
挿入するHTMLの前後に、目印になるコメントを置く。<!-- BOOK-CTA-START --> と <!-- BOOK-CTA-END --> のように、そのブロック専用の一意な名前を付ける。このマーカーが、後で「すでに挿入済みかどうか」を判定する唯一の根拠になる。
スクリプトの本体は単純で、対象ファイルを読み、マーカーが既に存在すればそのファイルは skip、存在しなければ挿入して changed、挿入位置(</footer> や </main> の手前など)が見つからなければ error として扱う。この3分岐だけで、同じスクリプトを何度実行しても2回目以降は全件skipになり、二重挿入が構造的に起きなくなる。
実際に書き込む前に、--dry-run オプションで対象ファイルと判定結果(skip / would-change / error)だけを一覧表示する。件数と対象範囲が意図通りかを目で確認してから、オプションを外して本実行に切り替える。
# 判定ロジックの骨格(概念コード)
if MARKER_START in text or MARKER_END in text:
return "skipped(既に挿入済み)"
insert_idx = find_insert_index(text) # か の手前
if insert_idx == -1:
return "error(挿入位置が見つからない)"
if dry_run:
return "would-change(書き込みはしない)"
# ここで初めてファイルに書き込む
ここが核心。安全さを生んでいるのは高度なロジックではなく、「マーカーの有無」という単一の判定条件だけだ。判定条件を1つに絞ることで、スクリプトの動きが予測しやすくなり、レビューも一目でできる。
一括挿入した後、そのブロックの中身(価格表記やリンク先など)を後日また一括で更新したくなることがある。このときも同じマーカーが効く。全ファイルを走査し、マーカーで囲まれた範囲だけを対象にして、中身が既に新しい状態なら skip、旧い状態なら置換する。マーカーは「挿入位置の目印」であると同時に、「後からの再編集を安全にする取っ手」でもある。
実際に、挿入済みのCTAブロック内のリンクにアソシエイトタグと開示文言を追加する改修を、同じ「対象文字列が既にあるか」の判定だけで全ファイルに安全に適用できた。新しく判定ロジックを書き直す必要はなかった。
記事サイトに限らず、テンプレート化されたファイルを何十枚も横断編集する場面ならそのまま使える。