当我现在想将i18n应用于该字符串时,我可能会转向gettext或框架函数。因为我来自PHP/Joomla!世界,所以我以前使用了JText::_,它的行为与gettext非常相似。在Python中,我现在使用Babel。两者都有相同的问题,可能还有更多的语言。我在这里共享的所有代码都是用Python实现的,更明确地说,是在我的Mako templates
当然,问题是:字符串中有要翻译的HTML(还有URL)。以下是我的选择,之后我将逐一解释:将原始字符串传递给gettext
把文本分成三位
用变量包围链接词
使用一个单独生成的变量
将原始字符串传递给gettext
这似乎是人们可能采取的第一种方法,如果不知道其中的含义。在
方法1:_('Welcome to my site. Check out our cool products \
you should not miss.')
对于这个msgid,您现在可以翻译它,保持HTML不变。在
优点:这在代码中看起来非常干净,而且很容易理解
如果翻译程序保持HTML的完整性,这不会产生任何问题
缺点:译者至少要懂一点HTML
字符串是完全不灵活的,例如,如果URL改变,所有的翻译都必须调整
它不允许使用路由器之类的东西动态生成URL
所以作为一个结论,当我用这个的时候,我很快达到了我的极限。我的下一个想法是:
把文本分成三位
方法2:
^{pr2}$
优点:网址现在完全灵活了
只有翻译的实际文本
缺点:把一个句子分成三部分
译者必须知道哪些部分联系在一起,否则他可能无法写出有意义的句子
代码不太好
msgid可能是一个单词,它可能会引起问题(注意上下文),但可以修复。在
我使用这种技术有一段时间了,因为我不知道PHP中的printf样式的字符串(我当时就用过)。因为这看起来很难看,所以我尝试了另一种方法:
用变量包围链接词
方法3:_('Welcome to my site. Check out our cool %sproducts%s you should not miss.' % \
('', '')
优点:单个字符串翻译,一个完整的句子
转换器从字符串中获取上下文
代码并不难看
缺点:翻译程序必须注意不要丢失%s(读起来像sproducts),这可能会造成混淆
为每个URL引入两个格式字符串变量,一个仅为
使用一个单独生成的变量
从这里我有了一些不同的方法,但我最终还是采用了我目前使用的方法(它可能看起来有点过头了,但我现在更喜欢它)。在
方法4:_('Welcome to my site. Check out our cool %s \
you should not miss.') % ('%s' % ('/products', _('products')))
让我花点时间来解释一下这种(看起来很疯狂)的方法。首先,实际的翻译字符串如下所示:_('Welcome to my site. Checkout our cool ${product_url} \
you should not miss.')
这会给翻译器留下插入内容的信息(即translationstring版本)。其次,我想确保我可以手动转义插入到HTML中的所有部分。虽然Mako提供了automatic escaping,但这样的语句没有意义:${'This is a url'}
它会破坏url,所以我必须应用|n过滤器来删除任何转义。但是,如果这其中的任何参数是用户提供的,那么它也会打开XSS,我想阻止它。不冒任何风险,我可以对任何输入进行escape(就像好的模板引擎通过defualt所做的一样),然后删除Mako对这一个字符串的转义。所以'%s' % ('/products', _('products'))
实际上看起来像'%s' % (escape('/products'), _('products'))
其中escape是从markupsafe导入的(参见Markupsafe)。在
最后一部分是通过路由器的动态url:request.route_url('products_view')
为了组合这些可能性,我必须产生一些非常难看的东西(请注意,这使用了translationstring(translationstring.TranslationString)的mapping关键字参数,但它结合了我想要/需要的所有翻译好处:
最终结果:_('Welcome to my site. Checkout our cool ${product_url} \
you should not miss.', mapping={'product_url': '%s' %\
(escape(request.route_url('products_view')), _('products'))})
优点:完整的HTML Escaping
完全动态的
非常好的msgids翻译
缺点:模板(或程序)中的极其丑陋的构造
lingua提取器没有捕获_('products'),所以我们必须手动提取
就这样,这就是我解决这个问题的方法。也许我在做一些复杂的事情,你有更好的想法,或者这是一个取决于具体类型的可译文本的问题(必须选择正确的方法)。在
我是否错过了任何解决方案或任何可以改进我的方法的方法?在