Php 带变量的HTML i18n/l10n的编码样式

Php 带变量的HTML i18n/l10n的编码样式,php,python,html,localization,internationalization,Php,Python,Html,Localization,Internationalization,我从事web开发已经有相当一段时间了,我一直在努力寻找一个干净的解决方案来解决我在处理HTML字符串(主要是锚定标记)的i18n过程中遇到的问题 首先,让我向你们展示一个典型的有问题的例子。这是HTML模板中经常遇到的字符串: Welcome to my site. Check out our cool <a href="/products">products</a> you should not miss. 欢迎来到我的网站。看看我们的酷 你不应该错过。 如何在仍

我从事web开发已经有相当一段时间了,我一直在努力寻找一个干净的解决方案来解决我在处理HTML字符串(主要是锚定标记)的i18n过程中遇到的问题

首先,让我向你们展示一个典型的有问题的例子。这是HTML模板中经常遇到的字符串:

Welcome to my site. Check out our cool <a href="/products">products</a> 
you should not miss.
欢迎来到我的网站。看看我们的酷
你不应该错过。
如何在仍具有以下属性的情况下转换此字符串:

  • 动态生成URL(例如,使用路由器)
  • 尽可能可读的可翻译字符串(因此翻译人员可以在不查看代码的情况下进行翻译)
  • 由于字符串包含HTML,我可能希望转义我插入的某些部分(例如URL),因此如果此URL包含用户输入,我不会使自己易受XSS攻击
  • 它在代码中也应该看起来尽可能好

当字符串包含动态内容和HTML时,如何翻译它们?

当我现在想对该字符串应用i18n时,我可能会转向
gettext
或一个框架函数。因为我来自PHP/world,所以我以前使用了
JText::
,其行为与
gettext
非常相似。在Python中,我现在使用。两者都有相同的问题,可能还有更多的语言。我在这里分享的所有代码都是用Python编写的,更明确地说,是在我的

当然,问题是:我们的字符串中有要翻译的HTML(以及URL)。以下是我的选择,我将在以后逐一解释:

  • 将原始字符串传递给
    gettext
  • 将文本分成三位
  • 用变量包围链接词
  • 使用一个单独生成的变量
将原始字符串传递给
gettext
这似乎是一个人可能采取的第一种方法,如果不知道其含义的话

方法1:

_('Welcome to my site. Check out our cool <a href="/products">products</a> \
you should not miss.')
_('Welcome to my site. Check out our cool ') + '<a href="/products">' +\
_('products') + '</a>' + _(' you should not miss.')
_('Welcome to my site. Check out our cool %sproducts%s you should not miss.' % \
('<a href="/products">', '</a>')
_('Welcome to my site. Check out our cool %s \
you should not miss.') % ('<a href="%s">%s</a>' % ('/products', _('products')))
_('Welcome to my site. Checkout our cool ${product_url} \
you should not miss.', mapping={'product_url': '<a href="%s">%s</a>' %\
(escape(request.route_url('products_view')), _('products'))})
优点:

  • URL现在是完全灵活的
  • 仅翻译实际文本
缺点:

  • 把一个句子分成三部分
  • 译者必须知道哪些部分相互关联,否则他可能无法写出有意义的句子
  • 代码不是很漂亮
  • msgid
    可能是单个单词,这可能会导致问题(注意上下文),但可以修复
我使用这种技术有一段时间了,因为我不知道PHP中的
printf
样式字符串(我当时使用的)。因为这看起来很难看,我尝试了另一种方法:

用变量包围链接词 方法3:

_('Welcome to my site. Check out our cool <a href="/products">products</a> \
you should not miss.')
_('Welcome to my site. Check out our cool ') + '<a href="/products">' +\
_('products') + '</a>' + _(' you should not miss.')
_('Welcome to my site. Check out our cool %sproducts%s you should not miss.' % \
('<a href="/products">', '</a>')
_('Welcome to my site. Check out our cool %s \
you should not miss.') % ('<a href="%s">%s</a>' % ('/products', _('products')))
_('Welcome to my site. Checkout our cool ${product_url} \
you should not miss.', mapping={'product_url': '<a href="%s">%s</a>' %\
(escape(request.route_url('products_view')), _('products'))})
让我花点时间来解释一下这种(看似疯狂的)方法。首先,实际的翻译字符串如下所示:

_('Welcome to my site. Checkout our cool ${product_url} \
you should not miss.')
${'This is a <a href="/">url</a>'}
这会给翻译人员留下插入的信息(即版本)。其次,我想确保可以手动转义插入HTML的所有部分。虽然Mako提供了,但这在这样的陈述中是没有意义的:

_('Welcome to my site. Checkout our cool ${product_url} \
you should not miss.')
${'This is a <a href="/">url</a>'}
实际上看起来像

'<a href="%s">%s</a>' % (escape('/products'), _('products'))
优点:

  • 完整HTML网页
  • 全动态
  • 非常适合翻译
    msgid
    s
缺点:

  • 模板(或程序)中极其丑陋的结构
  • lingua提取器无法捕获
    \('products')
    ,因此我们必须手动进行提取
就这样,这就是我解决这个问题的方法。也许我正在做一些复杂的事情,而你有很多更好的想法,或者这是一个取决于特定类型的可翻译文本的问题(必须选择正确的方法)


我是否错过了任何可以改进我的方法的解决方案或任何东西?

当我现在想对该字符串应用i18n时,我可能会转向
gettext
或一个框架函数。因为我来自PHP/world,所以我以前使用了
JText::
,其行为与
gettext
非常相似。在Python中,我现在使用。两者都有相同的问题,可能还有更多的语言。我在这里分享的所有代码都是用Python编写的,更明确地说,是在我的

当然,问题是:我们的字符串中有要翻译的HTML(以及URL)。以下是我的选择,我将在以后逐一解释:

  • 将原始字符串传递给
    gettext
  • 将文本分成三位
  • 用变量包围链接词
  • 使用一个单独生成的变量
将原始字符串传递给
gettext
这似乎是一个人可能采取的第一种方法,如果不知道其含义的话

方法1:

_('Welcome to my site. Check out our cool <a href="/products">products</a> \
you should not miss.')
_('Welcome to my site. Check out our cool ') + '<a href="/products">' +\
_('products') + '</a>' + _(' you should not miss.')
_('Welcome to my site. Check out our cool %sproducts%s you should not miss.' % \
('<a href="/products">', '</a>')
_('Welcome to my site. Check out our cool %s \
you should not miss.') % ('<a href="%s">%s</a>' % ('/products', _('products')))
_('Welcome to my site. Checkout our cool ${product_url} \
you should not miss.', mapping={'product_url': '<a href="%s">%s</a>' %\
(escape(request.route_url('products_view')), _('products'))})
优点:

  • URL现在是完全灵活的
  • 仅翻译实际文本
缺点:

  • 把一个句子分成三部分
  • 译者必须知道哪些部分相互关联,否则他可能无法写出有意义的句子
  • 代码不是很漂亮
  • msgid
    可能是单个单词,这可能会导致问题(注意上下文),但可以修复
我使用这种技术有一段时间了,因为我不知道PHP中的
printf
样式字符串(我当时使用的)。因为这看起来很难看,我尝试了另一种方法:

用变量包围链接词 方法3:

_('Welcome to my site. Check out our cool <a href="/products">products</a> \
you should not miss.')
_('Welcome to my site. Check out our cool ') + '<a href="/products">' +\
_('products') + '</a>' + _(' you should not miss.')
_('Welcome to my site. Check out our cool %sproducts%s you should not miss.' % \
('<a href="/products">', '</a>')
_('Welcome to my site. Check out our cool %s \
you should not miss.') % ('<a href="%s">%s</a>' % ('/products', _('products')))
_('Welcome to my site. Checkout our cool ${product_url} \
you should not miss.', mapping={'product_url': '<a href="%s">%s</a>' %\
(escape(request.route_url('products_view')), _('products'))})
让我花点时间来解释一下这种(看似疯狂的)方法。首先,实际的翻译字符串如下所示:

_('Welcome to my site. Checkout our cool ${product_url} \
you should not miss.')
${'This is a <a href="/">url</a>'}
这会给翻译人员留下插入的信息(即版本)。其次,我想确保可以手动转义插入HTML的所有部分。虽然Mako提供了,但这在这样的陈述中是没有意义的:

_('Welcome to my site. Checkout our cool ${product_url} \
you should not miss.')
${'This is a <a href="/">url</a>'}
实际上看起来像李