# 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模块所在的目录。 所以通过这些变量可以引用一些与项目有关的相对路径。
{% alert class=warning %} 在 0.2.5版本 之前,上面变量的写法是 ${PROJECT} 。请注意Uliweb的版本和写法的变化。 {% endalert %}
语言文件目录结构应该为: 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在处理时按照以下的顺序来决定是否使用某种语言:
如果url的Query_String上有 lang=xxx 的信息,则这个值为要使用的语言。 (0.0.1増加)
{% alert class=info %} lang 的名字是可以在settings.ini中配置的,缺省为空,需要设置此功能才会启动。 配置选项如下:
` [I18N] URL_LANG_KEY = 'lang' `
{% endalert %}
1. 如果session中存在 uliweb_language 的定义,则这个值为要使用的语言; 1. 如果cookie中存在与settings.ini中 I18N/LANGUAGE_COOKIE_NAME 对应的值时,则这个
值为要使用的语言;
- 如果浏览器发送的HTTP头有 HTTP_ACCEPT_LANGUAGE 的信息,并且得到的语言在
- SUPPORT_LANGUAGES 中有定义,则使用HTTP头中定义的语言;
- 最后选择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的函数。
{% alert class=info %} 使用lazy的函数不能支持 _(‘%s’) % ‘name’ 这种形式,但是可以使用 format() 函数,详见[格式化](#format). {% endalert %}
### 模板
因为uliweb的模板会编译为.py文件,所以除了不用导入gettext函数外,和在程序中无差别。 一旦你配置了i18n的app,会自动向模板环境中添加 _() 函数。示例:
`
<div>hi, {{=_('name')}}</div>
`
所以要编辑的串,都要放在 {{}} 中,并且使用 _() 进行处理。
{% alert class=warning %} 在模板中 _() 中的字符串不要使用 u’‘ 的形式,并且整个模板以utf-8来保存。 {% endalert %}
### settings.ini
在settings.ini中也可以使用翻译函数,如:
`
[DEFAULT]
NAME = _('username')
`
## I18N字符串的特殊处理
### 格式化 {#format}
有时我们需要对符串进行格式化处理,如 “%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将不做处理。 1. -p 这种方式会将项目下创建一个locale目录,将整个项目所有的内容都放在一个文件中 1. -d 按指定目录进行处理。比如plugs它只是一个app的集合,并不是一个完整的项目,所以
上述参数无法使用,但是可以使用这个-d参数进行处理
- –uliweb 对uliweb本身进行处理。因为uliweb中有些文件中也有i18n的翻译串,所以
- 可以使用这个命令来处理
- -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编码来处理。