V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
mywaiting
V2EX  ›  问与答

问个落后的技术问题:后端输出的 HTML 要 i18n 是怎么做的?

  •  
  •   mywaiting · 2019-02-27 11:33:42 +08:00 · 1729 次点击
    这是一个创建于 1903 天前的主题,其中的信息可能已经有所发展或是发生改变。
    都 2019 年了,都还要后端输出 HTML,还要进行 i18n 国际化的翻译,没有办法,感觉跟不上前端的 build 流程,只能直接代码里写好了

    网上找遍了 GNU xgettext 的相关文章,无奈这货不支持 HTML 的 i18n 输出啊,所有导致 Poedit 这样的软件也不支持

    还特别翻了 python django 的代码,好像也只有针对 python 内多语言的 i18n 支持

    那么问题来了:

    在 HTML 里面有这样标记 {{ _('text waited to translate') }} 有什么工具、流程、实现可以统一导出里面的待翻译的文本么?难得真要手写正则去遍历文件解决?
    第 1 条附言  ·  2019-02-28 00:01:05 +08:00
    研究了一天,特别挑了 pocco 出品的 pybabel 研究了一下,颇有心得

    1、pybabel 其实是调用 jinja2 来完成 HTML 的词法解析并导出所有的 _('xxxx') 这样的待翻译文本的,核心调用在 jinjia2.ext.babel_extract() 这个函数里面,写得很简单很容易理解的

    2、pybabel 本身自带了 python 和 javascript 两个抽取待翻译文本的词法实现,写得很简单的,压根就没有啥技术含量,其实还不如用 GNU gettext,方便还更加简单

    3、我是用 python tornado 的 template,而 pybabel 默认是使用 jinja2 的 template 语法的,两者并不兼容,如果你设置 pybabel jinja2 去抽取 HTML 里面的待翻译文本,并且开启 silent=flase (不要说我 typo,官方文档真是这个,实际也真是这个),那么你会发现 raise 的错误多到不得了

    总结下来,其实真没啥技术含量

    准备自己做个轮子!!!
    第 2 条附言  ·  2019-02-28 00:49:26 +08:00
    再写一段,作为记录

    主贴有提及过 django 是使用 GNU gettext/xgettext 来抽取 HTML 待翻译的文本的( Python 和 JS 本来 gettext 就支持的,就不过多说明了)

    那么 django 是如何做到这个的呢?很简单,你只要注意到 django/core/management/commands/makemessages 这个文件里面的这个 templatize 函数就可以了

    templatize 函数位于 django 的这里 django/utils/translation/template

    这个文件里你可以清楚看到 django 是脱裤子放屁的,用词法和正则来匹配 HTML 里面相关关键字,然后替换成 gettext 可以识别的语法

    有时候框架给予你一切,你用得舒服,但是你假如不去了解一下背后的原理,你永远不知道,其实 django 的背后实现得也相当的恶心
    10 条回复    2019-02-27 17:04:26 +08:00
    SakuraKuma
        1
    SakuraKuma  
       2019-02-27 11:37:57 +08:00
    你不是已经有答案了嘛.. 正则导出, 翻译, 按语言输出..
    就是 css 可能要再匹配了, 有些语言字符数会比较多, 有些地方可能会诡异了.
    6IbA2bj5ip3tK49j
        2
    6IbA2bj5ip3tK49j  
       2019-02-27 11:41:19 +08:00
    想起了一个有趣的轮子
    https://www.v2ex.com/t/267295
    mywaiting
        3
    mywaiting  
    OP
       2019-02-27 11:41:22 +08:00
    @SakuraKuma 有现成的话,还是用现成的吧,自己造轮子不是不可以,就是麻烦一点。

    我也是觉得很奇怪,这么基础的问题,怎么没有前人遇到过并且做几个轮子出来 [手动狗头~]
    SakuraKuma
        4
    SakuraKuma  
       2019-02-27 11:44:44 +08:00
    @mywaiting 因为貌似都是直接嵌入框架了, 还真没见过抽出来一个轮子的..
    mywaiting
        5
    mywaiting  
    OP
       2019-02-27 12:01:58 +08:00
    @SakuraKuma 其实 xgettext 这个轮子挺好的,无奈它就只支持那几种语言

    Django 内部就是用 xgettext 实现的,就是 django manage.py makemessages 这个命令搞的事情。我迟点试试强制指定为 python 语言导出试试看,搞完回头可以写个博客再 Github 写个仓库骗 star [手动狗头~]
    feiyuanqiu
        6
    feiyuanqiu  
       2019-02-27 12:06:33 +08:00 via Android
    facebook 开源了一个库 https://github.com/facebookincubator/fbt
    triptipstop
        7
    triptipstop  
       2019-02-27 12:09:05 +08:00
    laravel 自带
    mywaiting
        8
    mywaiting  
    OP
       2019-02-27 15:31:09 +08:00
    @xgfan @feiyuanqiu 这两个都是 javascript 的啊,我就是不想上 babel,不想搞一堆前端 build 的流程,要是上这个,那就简单很多了。感觉就几个命令的事情,结果要 install 一堆的 npm 包,累觉不爱
    agagega
        9
    agagega  
       2019-02-27 15:44:47 +08:00 via iPhone
    https://www.slideshare.net/mobile/idanielglh/strikinglyi18n

    虽然是 Ruby 的,但是也可以参考
    mywaiting
        10
    mywaiting  
    OP
       2019-02-27 17:04:26 +08:00
    真是神奇了,竟然没有太多这样的实现,我还天真以为这样的实现应该遍大街都是

    Django/laravel 框架确实有自带的,但是 Django 确实是调用了 GNU gettext 来完成提取翻译文本的任务的

    顺便翻遍 Python,竟然只有 PyBabel 这个跟着 Flask 出来的库,但是经过实际的试用,HTML 提取翻译文本 这个功能实现得实在不怎么样
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3039 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 27ms · UTC 15:11 · PVG 23:11 · LAX 08:11 · JFK 11:11
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.