在不失去理智的情况下重命名 1000 多页的‘Levels’
I’m happy to translate the article for you, but I’ll need the full text of the post (excluding the source link you’ve already provided). Could you please paste the content you’d like translated? Once I have it, I’ll keep the source line unchanged and translate the rest into Simplified Chinese while preserving all formatting, markdown, and technical terms.
挑战
一位同事在我们推送网站更改的当天早上给我发了邮件:
Hi Ice, now that we pushed the changes sa site, we need to scour the site for mentions of Level 1, Level 2, Level 1/2 and change them accordingly to
Level 1 → Intro to Neurofascial Training
Level 1/2 → Intermediate Instability Training
Level 2 → Advanced Neurofascial Training
乍一看,这似乎是一次简单的查找‑替换工作:打开 WordPress 管理后台,使用搜索功能,逐页修正,然后在午饭前完成。
但站点地图显示有 1,074 条 URL。即使只有一小部分包含 “Level” 这个词,手动点击每篇文章、搜索三个不同的字符串并判断应使用哪种替换,也至少需要整整一天,而且还有漏掉内容的风险。
重命名映射
| 旧文本 | 新文本 |
|---|---|
| Level 1 | Intro to Neurofascial Training |
| Level 1/2 | Intermediate Instability Training |
| Level 2 | Advanced Neurofascial Training |
重要的顺序细节: “Level 1/2” 必须在 Level 1 之前匹配。若使用朴素的替换,会把 “Level 1/2” 变成 “Intro to Neurofascial Training/2”。
为什么插件不足
像 Better Search Replace 这样的插件直接操作数据库。只要勾错一个复选框,就可能覆盖文章内容、文章元数据、小部件文本、主题选项中的每一个 “Level 1”,甚至包括不该被更改的地方(例如分析数据或审计日志)。
- 没有每个匹配项所在位置的预览。
- 重叠的字符串意味着操作顺序很重要,而大多数插件并不允许原子化地排列替换顺序。
我真正需要的是 一张映射表——列出每一次出现并提供足够的上下文,以判断是否安全更改,同时还能直接链接到该页面的 WordPress 编辑器。我仍然会手动执行替换,但会基于真实数据做出决定。
构建自定义扫描器
我编写了一个 Python 脚本,完成以下工作:
- 遍历站点的站点地图。
- 访问每个 URL。
- 使用带有单词边界的单个正则表达式搜索渲染后的 HTML 中的三种模式。
import re
LEVEL_PATTERN = re.compile(
r"\bLevel\s*1\s*/\s*2\b|\bLevel\s*1\b|\bLevel\s*2\b",
re.IGNORECASE,
)
单词边界(\b)可以防止出现诸如 “Level 10” 或 “Level 12‑week program” 之类的误报。交替顺序对应映射问题——“Level 1/2” 会先尝试,从而不会被更简单的 “Level 1” 模式覆盖。
脚本捕获的内容
对于每个匹配,脚本记录:
- 页面 URL
- WordPress 帖子 ID(从
class中提取,例如page-id-123或postid-123) - 直接的管理员编辑链接:
/wp-admin/post.php?post=123&action=edit - 匹配两侧约 80 个字符的上下文
- 包裹匹配的 HTML 标签(
h2、li、p等),以帮助在块编辑器中定位
所有数据导出为 CSV,进行排序,页面内的重复匹配会被合并,并过滤掉诸如 /wp-admin 和 /wp-json 等系统路径。
方法的优势
与其盲目点击 1,074 页,我现在拥有一个聚焦的列表,列出每个以任何形式提及“Level”的页面,每个页面都配有一键链接到编辑器,并提供足够的上下文,以决定应使用哪种替换。
上下文列才是真正的魔法——例如,下面这样的片段:
…我们的旗舰 Level 1 课程每周二举行…
显然表明课程名称应改为 “Intro to Neurofascial Training”,而不是偶然使用的“level”一词。
罕见的边缘情况(历史文本、推荐语等)容易被发现并跳过,而盲目的数据库替换会处理不当。
花半小时编写此扫描器立刻收回成本:节省时间、确保没有遗漏的信心,以及能够防止意外损坏的审计追踪。
References
- New XML Sitemaps Functionality in WordPress 5.5 — Make WordPress Core => WordPress 5.5 中的新 XML 站点地图功能 — Make WordPress Core
- Sitemaps XML Protocol — sitemaps.org => 站点地图 XML 协议 — sitemaps.org
body_class()Function Reference — WordPress Developer Resources =>body_class()函数参考 — WordPress Developer Resourcesget_body_class()Function Reference — WordPress Developer Resources =>get_body_class()函数参考 — WordPress Developer Resourcesre— Regular expression operations — Python 3 docs =>re— 正则表达式操作 — Python 3 文档- Better Search Replace — WordPress Plugin Directory => Better Search Replace — WordPress 插件目录
- Requests: HTTP for Humans => Requests:面向人类的 HTTP
- Beautiful Soup Documentation => Beautiful Soup 文档