-------------------
更新时间:
15:52 2016-09-28 星期三 增加模型名翻译
17:26 2016-05-20 星期五
17:58 2016-05-17 星期二
12:14 2016-02-24 星期三
-------------------
* 翻译概述:
每个模块都可以提供自己的翻译文件,存放在i18n(其来源是英文单词 internationalization的首末字符i和n,
18为中间的字符数)目录下,文件名为LANG.po LANG为语言,如中文简体 zh_CN.po
│- stock #模块
│ │- i18n #翻译目录
│ │ │- stock.pot #翻译模板
│ │ │- zh_CN.po #中文简体
│ │ │- (..).po #其它语言翻译文件
* 翻译支持的类型
/openerp/addons/base/ir/ir_translation.py
('field', 'Field'), 字段
('model', 'Object'), 模型
('rml', 'RML (deprecated - use Report)'), # Pending deprecation - to be replaced by report! 以前的报表
('report', 'Report/Template'), 报表
('selection', 'Selection'), 选择项
('view', 'View'), 视图
('wizard_button', 'Wizard Button'), 向导按钮
('wizard_field', 'Wizard Field'), 向导字段
('wizard_view', 'Wizard View'), 向导视图
('xsl', 'XSL'), 表格
('help', 'Help'), 帮助
('code', 'Code'), 代码
('constraint', 'Constraint'), 自定义约束
('sql_constraint', 'SQL Constraint') sql约束
* /addons/web/i18n
这里要把 zh_CN.po 复制一份 命名为zh.po
这样这个目录下 有 zh_CN.po zh.po 这两个文件
主要解决了数据库管理界面不能翻译的bug
* 翻译方法
=================================代码类开始===================================
@python代码片段中的翻译
#. module: stock
#: code:addons/stock/stock.py:1677
#, python-format
msgid " (%s reserved)"
msgstr " (%s 被保留)"
------
addons/stock/stock.py
info += _(' (%s reserved)') % str(reserved_available)
-------
第一行 #. module: stock 格式为 #. module: 模块的目录名
第二行 #: code:addons/stock/stock.py:1677
格式为 #: code:python代码相对根目录的文件名:第几行(相差几行没关系)
注意一下code:addons... 一般第三方代码不会放在addons下
一般新建一个目录 addonscustom ,这时这里要相应的更改
第三行 #, python-format 是python代码,这个照写就可以
可以看到代码中可以翻译的字符,都用 _()引起来了
注:对应的python 要导出翻译模块:
from openerp.tools.translate import _
@ 弹出窗体提醒翻译
#. module: stock
#: code:addons/stock/stock.py:3922
#, python-format
msgid "Warning: wrong UoM!"
msgstr "警告!错误的计量单位!"
-----------
if selected_uom.category_id.id != product.uom_id.category_id.id:
res['warning'] = {
'title': _('Warning: wrong UoM!'),
'message': _('The selected UoM for product %s is not compatible with the UoM set
on the product form. \nPlease choose an UoM within the same UoM category.') % (product.name)
}
-----------
@js代码片段的翻译
#. module: web
#. openerp-web
#: code:addons/web/static/src/js/chrome.js:279
#, python-format
msgid "Ok"
msgstr "确定"
------
addons/web/static/js/chrome.js/chrome
{text: _t("Ok"), click: function() { this.parents('.modal').modal('hide'); }}
-------
第一行 #. module: web 格式为 #. module: 模块的目录名
第二行 #. openerp-web 这个固定的页面模块
第三行 #: code:addons/web/static/src/js/chrome.js:279
格式为 #: code:js代码相对根目录的文件名:第几行(相差几行没关系)
注意一下code:addons... 一般第三方代码不会放在addons下
一般新建一个目录 addonscustom ,这时这里要相应的更改
第四行 #, python-format 这个照写就可以
可以看到代码中可以翻译的字符,都用 _t()引起来了
@xml代码中的翻译,这里指 /static/下面的
#. module: web_graph
#. openerp-web
#: code:addons/web_graph/static/src/xml/web_graph.xml:23
#, python-format
msgid "Heat Map"
msgstr "热图"
----
addons/web_graph/static/src/xml/web_graph.xml:
<label class="btn btn-default" data-mode="both" title="Heat Map">
----
第一行 #. module: web_graph 格式为 #. module: 模块的目录名
第二行 #. openerp-web 这个固定的页面模块
第三行 #: code:addons/web_graph/static/src/xml/web_graph.xml:23
格式为 #: code:js代码相对根目录的文件名:第几行(相差几行没关系)
注意一下code:addons... 一般第三方代码不会放在addons下
一般新建一个目录 addonscustom ,这时这里要相应的更改
第四行 #, python-format 这个照写就可以
可以看到代码中可以翻译的字符,这里是title的值 ,也可以是<p>...</p>中的内容
=================================代码类结束===================================
=================================字段名类开始=================================
@字段翻译
#. module: stock
#: field:stock.warehouse,partner_id:0
msgid "Address"
msgstr "地址"
------
addons/stock/stock.py
class stock_warehouse(osv.osv):
_name = "stock.warehouse" #模型名
_description = "Warehouse"
_columns = {
...
'partner_id': fields.many2one('res.partner', 'Address'),
...
}
--------
stock_view.xml 对应的视图显示
<record id="view_warehouse_tree" model="ir.ui.view">
<field name="name">stock.warehouse.tree</field>
<field name="model">stock.warehouse</field>
<field name="arch" type="xml">
<tree string="Warehouse">
<field name="name"/>
<field name="lot_stock_id" groups="stock.group_locations"/>
<field name="partner_id"/>
</tree>
</field>
</record>
-----------
第一行 #. module: stock 格式为 #. module: 模块的目录名
第二行 #: field:stock.warehouse,partner_id:0
格式为 #: field:模型名:要翻译的字段名:0
partner_id 是在数据表中字段
Address 在显示名称
@ 字段帮助翻译
#. module: stock
#: help:stock.config.settings,group_uom:0
msgid "Allows you to select and maintain different units of measure for products."
msgstr "允许你选择和维护产品的不同计量单位"
------
res_config.py
class stock_config_settings(osv.osv_memory):
_name = 'stock.config.settings'
_inherit = 'res.config.settings'
_columns = {
...
'group_uom': fields.boolean("Manage different units of measure for products",
implied_group='product.group_uom',
help="""Allows you to select and maintain different units of measure for products."""),
...
-------
res_config_view.xml
<record id="view_stock_config_settings" model="ir.ui.view">
<field name="name">stock settings</field>
<field name="model">stock.config.settings</field>
<field name="arch" type="xml">
...
<div>
<field name="group_uom" class="oe_inline"/>
<label for="group_uom"/>
</div>
...
----------
第一行 #. module: stock 格式为 #. module: 模块的目录名
第二行 #: help:stock.config.settings,group_uom:0
格式为 #: help:模型名,字段名
=================================字段名类结束==============================
=================================约束开始==============================
@条件约束中文翻译
#. module: account
#: constraint:account.move.line:0
msgid "Account and Period must belong to the same company."
msgstr "帐户和帐期必须属于同一家公司。"
----------------
addons/account/account_move_line.py
class account_move_line(osv.osv):
_name = "account.move.line"
....
def _check_company_id(self, cr, uid, ids, context=None):
lines = self.browse(cr, uid, ids, context=context)
for l in lines:
if l.company_id != l.account_id.company_id or l.company_id != l.period_id.company_id:
return False
return True
....
_constraints = [
...
(_check_company_id, 'Account and Period must belong to the same company.', ['company_id']),
...
-------------------
第一行 #. module: account 格式为 #. module: 模块的目录名
第二行 #: constraint:account.move.line:0
格式为 #:constraint:模型名:0
第三行 msgid "Account and Period must belong to the same company."
要翻译的字符串
@sql 字段约束中文翻译
#. module: account
#: sql_constraint:account.move.line:0
msgid "Wrong credit or debit value in accounting entry !"
msgstr "错误的出纳会计分录"
----------------------
addons/account/account_move_line.py
class account_move_line(osv.osv):
_name = "account.move.line"
....
_sql_constraints = [
('credit_debit1', 'CHECK (credit*debit=0)', 'Wrong credit or debit value in accounting entry !'),
---------------------
第一行 #. module: account 格式为 #. module: 模块的目录名
第二行 #: sql_constraint:account.move.line:0
格式为 #:sql_constraint:模型名:0
第三行 msgid "Wrong credit or debit value in accounting entry !"
要翻译的字符串
=================================字段约束结束==============================
@ 下拉选择内容翻译
#. module: stock
#: selection:stock.move,state:0
msgid "Available"
msgstr "可用"
--------
stock.py
class stock_move(osv.osv):
_name = "stock.move"
_description = "Stock Move"
...
_columns = {
...
'state': fields.selection([('draft', 'New'),
('cancel', 'Cancelled'),
('waiting', 'Waiting Another Move'),
('confirmed', 'Waiting Availability'),
('assigned', 'Available'),
('done', 'Done'),
], 'Status', readonly=True, select=True, copy=False,
...
第一行 #. module: stock 格式为 #. module: 模块的目录名
第二行 #: selection:stock.move,state:0
格式为 #:selection:模型名,字段名
第三行 msgid "Available" 下拉选择项的显示名称
@ xsl 文件中文翻译
<report
id="account_transfers"
model="account.transfer"
name="account.transfer"
string="Transfers"
xml="account/report/transfer.xml"
xsl="account/report/transfer.xsl"
/>
#. module: account
#: xsl:account.transfer:0
msgid "Document"
msgstr "单据"
--------------
addons/account/report/transfer.xsl:
<para>
<b t="1">Document</b>: <i><xsl:value-of select="name"/></i>
</para>
--------------
第一行 #. module: account 格式为 #. module: 模块的目录名
第二行 #: xsl:account.transfer:0
格式为 #:xsl:xsl文件对应的名字空间:0 这里取 name="account.transfer"
这时你要搜索文件名对应定义的 report
第三行 msgid "Document" xsl文件出现要翻译的字符串
=================================报表类开始=================================
@ 报表界面翻译
报表动作定义:
class ir_actions_report_xml(osv.osv):
_name = 'ir.actions.report.xml'
_inherit = 'ir.actions.actions'
_table = 'ir_act_report_xml'
#. module: stock
#: model:ir.actions.report.xml,name:stock.action_report_lot_barcode
msgid "Lot BarCode"
msgstr "批次条形码"
----------
stock_report.xml
<report id="action_report_lot_barcode" model="stock.production.lot"
report_type="qweb-pdf" name="stock.report_lot_barcode"
string="Lot BarCode" file="stock.report_lot_barcode"/>
--------
第一行 #. module: stock 格式为 #. module: 模块的目录名
第二行 #: model:ir.actions.report.xml,name:stock.action_report_lot_barcode
格式为 #: model:ir.actions.report.xml,name:模块的目录名.记录外部标识符
name 对应的是 string 和往常有点差别, 上面xml中的name, 则映射到数据表中
report_name 指要采用哪个模板文件
记录外部标识符 这里很显然是 报表id
第三行 msgid "Lot BarCode" 报表里的string 内容拷贝出来翻译
<report><report>是 <record id="###" model="ir.actions.report.xml">...</record>
只是在定义纸章时,不能用简标签
@报表模板中的中文翻译
#. module: stock
#: view:website:stock.report_lot_barcode
msgid "Lot"
msgstr "批次"
--------------
addons/stock/views/report_lot_barcode.xml
报表模板
<template id="report_lot_barcode">
........
<tr>
<th>Product</th>
<th>Lot</th>
</tr>
.......
</template>
--------
第一行 #. module: stock 格式为 #. module: 模块的目录名
第二行 #: view:website:stock.report_lot_barcode
格式为 #: view:webiste:模块的目录名.记录外部标识符(模板id)
第三行 msgid "Lot" 把模板对应要翻译的字符复制过来
--------
@rml文件内中文的翻译
<data>
<report auto="False" id="ir_module_reference_print"
model="ir.module.module" name="ir.module.reference"
rml="base/module/report/ir_module_reference.rml"
string="Technical guide"/>
</data>
#. module: base
#: report:ir.module.reference:0
msgid "Menu :"
msgstr "菜单:"
-----------
openerp/addons/base/module/report/ir_module_reference:
<para style="terp_default_8_underline">Menu :</para>
----------
第一行 #. module: base 格式为 #. module: 模块的目录名
第二行 #: report:ir.module.reference:0
格式为 #: report:报表文件的命名空间 这里取 name="ir.module.reference"
里面的的值
第三行 msgid "Menu :" 把模板对应要翻译的字符复制过来
=================================报表类结束=================================
=================================视图界面类开始===============================
@ 视图中文字翻译
#. module: stock
#: view:stock.location.route:stock.stock_location_route_form_view
msgid "Applicable On"
msgstr "适用于"
------
stock_view.xml
<record id="stock_location_route_form_view" model="ir.ui.view">
<field name="name">stock.location.route.form</field>
<field name="model">stock.location.route</field>
...
<separator string="Applicable On"/>
...
第一行 #. module: stock 格式为 #. module: 模块的目录名
第二行 #: view:stock.location.route:stock.stock_location_route_form_view
格式为 #: view:模型名:模块的目录名.视图的id名
第三行 msgid "Applicable On" 把视图对应要翻译的那段复制过来
这里是放在 string="str"
有<p>str</p>
注:同一个模型的视图要翻译的字符串多次只有第一次的有效,后面再翻译会忽略,
若是同一个模型在多个视图中要分别翻译,只能在不同的视图把要翻译的字符串
区分开来。
这里适应较多情况:
@ 搜索翻译
#. module: stock
#: view:stock.picking:stock.view_picking_internal_search
msgid "Draft"
msgstr "草稿"
@ 搜索帮助翻译
#. module: stock
#: view:stock.picking:stock.view_picking_internal_search
msgid "Draft Moves"
msgstr "迁移草稿"
----
stock_view.xml
<record id="view_picking_internal_search" model="ir.ui.view">
<field name="name">stock.picking.internal.search</field>
<field name="model">stock.picking</field>
<field name="arch" type="xml">
<search string="Picking Lists">
<field name="name" string="Picking List" filter_domain="['|',('name','ilike', self),('origin','ilike',self)]"/>
<filter icon="terp-check" name="draft" string="Draft" domain="[('state','=','draft')]" help="Draft Moves"/>
....
------
@ 界面按钮翻译
#. module: stock
#: view:stock.move:stock.view_move_tree
msgid "Process"
msgstr "处理"
-------
stock_view.xml
<record id="view_move_tree" model="ir.ui.view">
<field name="name">stock.move.tree</field>
<field name="model">stock.move</field>
...
<button name="action_done" states="confirmed,assigned" string="Process" type="object"
groups="stock.group_stock_user" icon="gtk-go-forward" help="Done"/>
-------
@ 界面占位符翻译
#. module: product
#: view:product.template:product.product.product_template_form_view
msgid "Tags..."
msgstr "产品标签.."
----------
<record id="product_template_form_inherit" model="ir.ui.view">
<field name="name">product.template.view.form</field>
<field name="model">product.template</field>
<field name="inherit_id" ref="product.product_template_form_view"/>
<field name="arch" type="xml">
<xpath expr="//h1" position="after">
<field name="tag_ids" widget="many2many_tags" placeholder="Tags..."/>
</xpath>
</field>
</record>
----------
@ 组标题提示翻译
#. module: stock
#: view:stock.location:stock.view_location_form
msgid "Additional Information"
msgstr "其它信息"
----------
stock_view.xml
<group string="Additional Information">
<field name="usage"/>
<field name="partner_id"/>
<field name="company_id" groups="base.group_multi_company" widget="selection"/>
<field name="scrap_location"/>
<field name="active"/>
</group>
--------
=================================视图界面类结束===============================
=================================模型记录类开始===============================
@ 模型名描述
#. module: payment_notice
#: model:ir.model,name:payment_notice.model_payment_notice
msgid "Receiving payment notice"
msgstr "到款通知"
--------
class PaymentNotice(models.Model):
_name = "payment.notice"
_inherit = ['mail.thread']
_description = "Receiving payment notice"
-------
第一行 #. module: payment_notice 格式为 #. module: 模块的目录名
第二行 #: model:ir.model,name:payment_notice.model_payment_notice
格式为 #: ir.model,name:模块的目录名.model_模型名
第三行 msgid "Receiving payment notice" 对应到_description 后面的值
@ 记录名称翻译
一般一条记录会翻译name字段,也可以是其它字段
#. module: stock
#: model:ir.model,name:stock.model_stock_inventory_line
msgid "Inventory Line"
msgstr "盘点表明细"
--------
stock.py
class stock_inventory_line(osv.osv):
_name = "stock.inventory.line"
_description = "Inventory Line"
--------
---------
ir_model 表
对应的数据表记录:
id model name state info create_uid create_date write_uid write_date
308 stock.inventory.line Inventory Line base
对应外记录表 ir_model_data
id .... name .....
7885 model_stock_inventory_line
--------
第一行 #. module: stock 格式为 #. module: 模块的目录名
第二行 #: model:ir.model,name:stock.model_stock_inventory_line
格式为 #: model:记录的模型名,name:模块的目录名.记录外部标识符
若翻译总无效 则改为 格式为 #: model:记录的模型名,name:记录外部标识符
不要模块的目录名,
这时 name 可以换成其它的 字段 像info 但要是这记录有的字段
第三行 msgid "Inventory Line" 记录对应 name 字段的值
--------
这里记录的name翻译,记得这个字段要可以翻译 如:'name': fields.char('Payment Term', translate=True, required=True)
translate=True, 若没有这个,你添加翻译也不会显示出来
注:js 异步调用时要带上 {context:self.session.user_context} ,否则记录的name对就不会翻译了
如:instance.web.Model('res.users').call('get_challenge_suggestions', [],{context:self.session.user_context})
对应在py里面一般带上了context 里面有语言值
这个是模型记录翻译的通用模板,下面那些只是这个模板的特例
@ 动作窗体xml帮助翻译
针对窗体表的记录对应字段的值翻译
动作窗体定义 /openerp/addons/base/ir/ir_action.py:
class ir_actions_act_window(osv.osv):
_name = 'ir.actions.act_window'
_table = 'ir_act_window'
...
-------------
#. module: stock
#: model:ir.actions.act_window,help:stock.action_warehouse_form
msgid ""
"<p class=\"oe_view_nocontent_create\">\n"
" Click to define a new warehouse.\n"
" </p>\n"
" "
msgstr ""
"<p class=\"oe_view_nocontent_create\">\n"
" 单击定义新仓库\n"
" </p>\n"
" "
----------
stock_view.xml
<record id="action_warehouse_form" model="ir.actions.act_window">
<field name="name">Warehouses</field>
<field name="res_model">stock.warehouse</field>
<field name="type">ir.actions.act_window</field>
<field name="view_type">form</field>
<field name="view_id" ref="view_warehouse_tree"/>
<field name="help" type="html">
<p class="oe_view_nocontent_create">
Click to define a new warehouse.
</p>
</field>
</record>
----------
第一行 #. module: stock 格式为 #. module: 模块的目录名
第二行 #: model:ir.actions.act_window,help:stock.action_warehouse_form
格式为 #: model:ir.actions.act_window,help:模块的目录名.id名
ir.actions.act_window 是动作窗体的模型名
help是动作窗体记录字段
这是针对 help字段的值 ,像上面也有 name 字段值 为 Warehouses
这时换成name 就可以了,还有很多,具体看动作窗体定义了哪些字段
第三行 把 name="help" 容器中的内容拷贝出来翻译
@ 菜单翻译
#. module: stock
#: model:ir.ui.menu,name:stock.menu_stock_inventory_control
msgid "Inventory Control"
msgstr "盘点管理"
-------
stock_view.xml
<menuitem id="menu_stock_inventory_control" name="Inventory Control" parent="menu_stock_root" sequence="2"/>
-------
第一行 #.module: stock 格式为 #. module: 模块的目录名
第二行 #: model:ir.ui.menu,name:stock.menu_stock_inventory_control
格式为 #: model:ir.ui.menu,name:模块的目录名.id名
若有时翻译不进来(一般是目录名过长引起),就把 模块的目录名 去了变为 #: model:ir.ui.menu,name:id名
第三行 msgid "Inventory Control" 显示名称
@ 客户动作事件翻译
客户动作事件模型定义
class ir_actions_act_client(osv.osv):
_name = 'ir.actions.client'
_inherit = 'ir.actions.actions'
_table = 'ir_act_client'
#. module: stock
#: model:ir.actions.client,name:stock.action_client_warehouse_menu
msgid "Open Warehouse Menu"
msgstr "打开仓库菜单"
-------
res_config_view.xml
<record id="action_client_warehouse_menu" model="ir.actions.client">
<field name="name">Open Warehouse Menu</field>
<field name="tag">reload</field>
<field name="params" eval="{'menu_id': ref('menu_stock_root')}"/>
</record>
-------
第一行 #. module: stock 格式为 #. module: 模块的目录名
第二行 #: model:ir.actions.client,name:stock.action_client_warehouse_menu
格式为 #: model:ir.actions.client,name:模块的目录名.客户事件id名
第三行 msgid "Open Warehouse Menu" 显示名称 视图有对应的拷贝过来就可
@ 权限组翻译
用户组模型定义:
class res_groups(osv.osv):
_name = "res.groups"
_description = "Access Groups"
_rec_name = 'full_name'
#. module: stock
#: model:res.groups,name:stock.group_tracking_owner
msgid "Manage Different Stock Owners"
msgstr "管理不同库存拥有者"
--------
security/stock_security.xml
<record id="group_tracking_owner" model="res.groups">
<field name="name">Manage Different Stock Owners</field>
<field name="category_id" ref="base.module_category_hidden"/>
</record>
--------
第一行 #. module: stock 格式为 #. module: 模块的目录名
第二行 #: model:res.groups,name:stock.group_tracking_owner
格式为 #: model:res.groups,name:模块的目录名.分组id名
若security.xml文件中 id 为 group_tracking_owener 则为模块的目录名.分组id名
为 base.group_tracking_owener 则为 分组id名
第三行 msgid "Manage Different Stock Owners" 权限组显示名称
@ 模块说明翻译
在本地安装模块时就会显示中文了
#. module: base
#: model:ir.module.module,description:base.module_stock_specific_inventory
msgid ""
"\n"
"Stock Specific Inventory\n"
"==========================\n"
"This module adds the possibility to make inventories on a product selection.\n"
msgstr ""
"\n"
"最体产品估值\n"
"==========================\n"
"这个模块增加可以指定具体的产品进行估值\n"
"\n"
--------
__openerp__.py
'description': """
Stock Specific Inventory
==========================
This module adds the possibility to make inventories on a product selection.
""",
--------
翻译要添加到 /openerp/addons/base/i18n/zh_CN.po 中 不能加在自己模块的翻译文件中
第一行 #. module: base 格式为 #. module: base 这个是定死的
第二行 #: model:ir.module.module,description:base.module_stock_specific_inventory
格式为 #: model:ir.module.module,description:base.module_模块的目录名
这里有对应关键字段 description 配置文件里还有name ,shortdesc, summary, category, 等
对应改一下
第三行 msgid "" 'description'里面的描述
第四行 msgstr ""
=================================模型记录类结束===============================
翻译表很容易出问题,特别在添加翻译时,会导致系统启动不来,
日志报错如下:
InternalError: current transaction is aborted, commands ignored until end of transaction block
这时,就要针对 ir_translate 这个表,重建索引就可以。
注:总是翻译无效时,可以搜索旁边的 翻译,从而参照 写翻译条
关键的标点符号要全英文,不能中文的
注意我们中文的翻译文件名是 zh_CN.po 不要写错了
# create_uid Created by 创建人
# create_date Created on 创建时间
# write_uid Last Updated by 最后更新人
# write_date Last Updated on 最后更新时间
消息主菜碟里的英文,像 Whole Compnay Company News 等要通过更改菜单项来解决
财务相关翻译
# journal entry 会计凭证
# journal items 会计分录
# Account Move 会计凭证
# Reconciled 核销
# Group By 分组
# Validate 审核
# Approve 审批
# Confirm 确认