# 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在处理时按照以下的顺序来决定是否使用某种语言:

  1. 如果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 对应的值时,则这个

值为要使用的语言;
  1. 如果浏览器发送的HTTP头有 HTTP_ACCEPT_LANGUAGE 的信息,并且得到的语言在
    SUPPORT_LANGUAGES 中有定义,则使用HTTP头中定义的语言;
  1. 最后选择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参数进行处理
  1. –uliweb 对uliweb本身进行处理。因为uliweb中有些文件中也有i18n的翻译串,所以
    可以使用这个命令来处理
  1. -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编码来处理。