I18N 使用说明

Uliweb支持标准的gettext的i18n的处理。在程序中和在模板中都可以使用,甚至在ini文件 中也可以使用。

I18N的配置

为了使用i18n,需要在settings.ini中的INSTALLED_APPS中添加 'uliweb.contrib.i18n' , 同时uliweb.contrib.i18n下的settings.ini还定义了一些配置项,如:

[I18N]
LANGUAGE_COOKIE_NAME = 'uliweb_language'
LANGUAGE_CODE = 'en'
LOCALE_DIRS = []
SUPPORT_LANGUAGES = []
  • LANGUAGE_COOKIE_NAME 是用来将语言的选择存在cookie中使用的,一般不需要修改。
  • LANGUAGE_CODE 是表示缺省的语言,缺省为英文。
  • LOCALE_DIRS 可以用来设置语言文件所在的目录,可以是多个。同时在其中还可以定 义一些特殊的变量,如: $[PROJECT] 表示项目目录, $[plugs] 表示plugs模块所在的目录。 所以通过这些变量可以引用一些与项目有关的相对路径。

    0.2.5版本 之前,上面变量的写法是 ${PROJECT} 。请注意Uliweb的版本和写法的变化。

    语言文件目录结构应该为: path/locale/LC_MESSAGES/xxxx ,你只要把path设置 上就可以了。

  • SUPPORT_LANGUAGES 表示网站所支持的语言种类。除原本开发所使用的语言外,如果浏 览器自动希望某种语言,并且这种语言在 SUPPORT_LANGUAGES 所支持的范围之内时,才会 生效。

一旦配置了I18N,则会自动应用 'uliweb.i18n.middle_i18n.I18nMiddle' 这个middleware, 这个可以在uliweb.contrib.i18n/settings.ini中看到。

I18N语言的判定规则

判定规则

在Uliweb中,可以有许多种方式来决定使用哪种语言,比如:在session中,在cookie中, 通过浏览器发送的HTTP头来自动判断,还有就是在settings中的 LANGUAGE_CODE 来决定。 Uliweb在处理时按照以下的顺序来决定是否使用某种语言:

  1. 如果url的Query_String上有 lang=xxx 的信息,则这个值为要使用的语言。 (0.0.1増加)

    lang 的名字是可以在settings.ini中配置的,缺省为空,需要设置此功能才会启动。 配置选项如下:

    [I18N]
    URL_LANG_KEY = 'lang'
  2. 如果session中存在 uliweb_language 的定义,则这个值为要使用的语言;
  3. 如果cookie中存在与settings.ini中 I18N/LANGUAGE_COOKIE_NAME 对应的值时,则这个 值为要使用的语言;
  4. 如果浏览器发送的HTTP头有 HTTP_ACCEPT_LANGUAGE 的信息,并且得到的语言在 SUPPORT_LANGUAGES 中有定义,则使用HTTP头中定义的语言;
  5. 最后选择settings.ini中定义的 LANGUAGE_CODE

所以如果你的网站支持多种语言,可以按照上面的说明来选择不同的模式。简单情况下只 要定义 LANGUAGE_CODE='zh_CN' 就可以支持中文了。如果想支持浏览器自动识别,可以定义 settings.ini为:

[I18N]
LANGUAGE_CODE = 'en'
SUPPORT_LANGUAGES = ['en', 'zh_CN']

上面的定义说明当前网站支持两种语言,缺省为 'en'

调试

为了方便了解判定的结果,uliweb提供了当在URL输入 __debug__=1 的参数时,会在后台输出判定 的依据,输出结果类似于:

Detect from settings of LANGUAGE_CODE=en

可能的结果是 cookie, session, HTTP header, settings等。

I18N字符串的定义

为了使用i18n,首先要在程序中进行i18n的定义,根据文件格式的不同,使用略有不同。

程序文件

这里是指.py文件。示例如下:

from uliweb.orm import *
from uliweb.i18n import ugettext_lazy as _

class User(Model):
    username = Field(str, verbose_name=_('Username'), max_length=30, unique=True, index=True, nullable=False)
    email = Field(str, verbose_name=_('Email'), max_length=40)
    password = Field(str, verbose_name=_('Password'), max_length=128, nullable=False)

在uliweb.i18n中定义了几组gettext函数,常用的就是gettext, ugettext, gettext_lazy 和ugettext_lazy。带u的表示返回为unicode字符串,否则为字符串。后缀有lazy的表示 在运行时会根据当时的上下文环境自动进行语言的切换。因此一般使用带有lazy的函数。

使用lazy的函数不能支持 _('%s') % 'name' 这种形式,但是可以使用 format() 函数,详见格式化.

模板

因为uliweb的模板会编译为.py文件,所以除了不用导入gettext函数外,和在程序中无差别。 一旦你配置了i18n的app,会自动向模板环境中添加 _() 函数。示例:

<div>hi, {{=_('name')}}</div>

所以要编辑的串,都要放在 {{}} 中,并且使用 _() 进行处理。

在模板中 _() 中的字符串不要使用 u'' 的形式,并且整个模板以utf-8来保存。

settings.ini

在settings.ini中也可以使用翻译函数,如:

[DEFAULT]
NAME = _('username')

I18N字符串的特殊处理

格式化

有时我们需要对符串进行格式化处理,如 "%s" % 'hello'"{}".format('hello') ,这两种都是目前 Python支持的格式化处理方式,对于 i18n 字符串,可以使用format的形式来处理格式化,如:

_('Hello, {}').format('name')

I18N字符串的提取

命令行用法

uliweb.contrib.i18n App提供了一个i18n的命令它提供以下参数:

--apps

如果设置,将从存在于项目中的所有app中进行抽取,并将 .po 文件保存在每个app下的 locale 目录中。

-p

如果设置,将从项目目录抽取翻译信息。

-d DIRECTORY

如果设置,将从指定目录抽取翻译信息。

--uliweb

如果设置,将从uliweb包中抽取翻译信息。

-l LOCALE

目标语言,缺省是 en

--exact

如果设置,则在旧的.po中存在,但是在.pot中不存在的项目将被删除。 (0.0.1新増)

-t TEMPLATE, --template=TEMPLATE

PO文件中一些静态信息的定义,如:charset, translater等模板的定义。

因此i18n支持几种语言提取方式:

  1. --apps 这种方式会在每个app下都生成一个locale的目录。注意这种方式只处理存在于项目目录下的app,对于已经安装但是不存在于项目目录下的app将不做处理。
  2. -p 这种方式会将项目下创建一个locale目录,将整个项目所有的内容都放在一个文件中
  3. -d 按指定目录进行处理。比如plugs它只是一个app的集合,并不是一个完整的项目,所以 上述参数无法使用,但是可以使用这个-d参数进行处理
  4. --uliweb 对uliweb本身进行处理。因为uliweb中有些文件中也有i18n的翻译串,所以 可以使用这个命令来处理
  5. -t 它允许你写一个po的模板文件,在uliweb.i18n下已经提供了一个示例,名为: po_template.ini 其内容为:

    [I18N]
    First_Author = 'FIRST AUTHOR <EMAIL@ADDRESS>'
    Project_Id_Version = 'PACKAGE VERSION'
    Last_Translator = 'FULL NAME <EMAIL@ADDRESS>'
    Language_Team = 'LANGUAGE <LL@li.org>'
    Content_Type_Charset = 'utf-8'
    Content_Transfer_Encoding = '8bit'
    Plural_Forms = 'nplurals=1; plural=0;'

你可以修改其中的内容,它们将自动填充到生成的pot和po文件中。

使用示例:

uliweb i18n -p -l zh_CN

注意, -l 参数如果不提供则自动为 'en' 。因此,如果要翻译中文一定要加上 -l zh_CN

plugs 的处理

针对plugs项目,可以使用以下命令来提取翻译串:

cd <plugs项目目录下>
uliweb i18n -d plugs -l zh_CN

编码注意事项

在i18n中提供gettext和ugettext,它们的区别是:前者返回字符串,后者返回unicode。 为了正确处理中文编码,建议:程序、模板包括ini文件都使用utf-8编码来处理。