xgettext提取Bottle的SimpleTemplate模板时遗漏标签属性翻译字符串如何解决
Bottle SimpleTemplate 模板属性内翻译字符串提取问题解决方案
你遇到的遗漏问题是因为xgettext的Python语言提取模式默认会跳过HTML标签属性内的嵌入代码段,pybabel的JavaScript提取器也默认不处理属性内的翻译标记,加上STPL语法没有官方的babel提取器,所以才有适配问题,以下是可直接落地的方案:
- 方案一:自定义正则提取脚本(最推荐,无兼容问题)
STPL语法简单,自己写几十行代码即可扫描所有_()包裹的可翻译字符串,完全不受模板语法、字符串位置的限制,兼容{{!base}}等特有语法,参考实现如下:
import re from pathlib import Path # 匹配_()包裹的翻译字符串,支持单/双引号、转义字符 TRANS_PATTERN = re.compile(r"_\(\s*([\"'])(.*?[^\\])\1\s*\)", re.DOTALL) def extract_stpl_translations(tpl_dir: str, output_pot_path: str): # POT文件标准头,可根据自己的项目修改 pot_head = '''msgid "" msgstr "" "Content-Type: text/plain; charset=UTF-8\\n" "Plural-Forms: nplurals=2; plural=(n != 1);\\n" "MIME-Version: 1.0\\n" "Content-Transfer-Encoding: 8bit\\n" ''' found = set() # 遍历目录下所有模板文件 for tpl_file in Path(tpl_dir).rglob("*.html"): with open(tpl_file, "r", encoding="utf-8") as f: content = f.read() for match in TRANS_PATTERN.finditer(content): msgid = match.group(2).replace('\\"', '"').replace("\\'", "'") # 若需要记录行号,可自行添加计算逻辑 found.add(msgid) # 输出POT文件 with open(output_pot_path, "w", encoding="utf-8") as f: f.write(pot_head) for msgid in sorted(found): f.write(f'msgid "{msgid}"\nmsgstr ""\n\n') if __name__ == "__main__": # 修改为你自己的模板目录和输出路径 extract_stpl_translations("./views", "./locale/templates/messages.pot")
运行后即可提取包括标签属性内的所有_()标记的翻译字符串。
- 方案二:使用xgettext无语法限制模式
你可以将xgettext的语言参数改为--language=C,C语言模式会尽可能扫描所有符合_("xxx")格式的字符串,不会受HTML语法限制,命令参考:
xgettext --keyword=_ --language=C --from-code=utf-8 -o messages.pot views/*.html
该方案的缺点是可能会扫到注释中的无关内容,需要后续手动过滤。
- 方案三:配置Poedit自定义提取规则
如果你用Poedit管理翻译文件,可以在提取器设置中添加针对STPL模板的正则提取规则,匹配规则和方案一的正则一致,无需写代码即可完成提取。
内容的提问来源于stack exchange,提问作者neurino
相关产品推荐
相关产品推荐

