ODOO翻译

翻译类型

TRANSLATION_TYPE = [
    ('field', 'Field'),                         # deprecated
    ('model', 'Object'),
    ('report', 'Report/Template'),
    ('selection', 'Selection'),
    ('view', 'View'),                           # deprecated
    ('help', 'Help'),                           # deprecated
    ('code', 'Code'),
    ('constraint', 'Constraint'),
    ('sql_constraint', 'SQL Constraint')
]

ir.translation.py中声明了上述几种翻译的类型,但是实际上在使用的只有这几个:code,sql_constraint,constraint,model,selection。他们的对应关系分别是:model,field,hep,view四种类型对应model;code,constraint,sql_constraint,selection分别对应的各自名称的类型

系统如何选取翻译

2.1.type=model时

选取翻译的时候根据当前模型,可翻译的字段,记录的id以及语言去确定唯一的翻译值的,如果根据这几个条件检索出来的翻译值多余1条,则取id值最大的那条。

匹配关系例子,英文环境下id为1的部门名称翻译值选取:部门(hr.department),可翻译字段(name),记录的id(1),语言(en_US)。找到的对应的翻译值是ir_translation表中的name字段是“hr.department,name”,lang字段是“en_US”,并且res_id为1的翻译记录。如果这时候有多条翻译值,id分别为(1,2,3),则系统会显示id为3的翻译值。

** field,help,view三种类型均是按照model类型来处理的。**
缓存bug:手动增加一条错误的翻译,然后修改正确之后,系统的翻译没有读取到,重启之后正常了。

2.2.type=code,constraint,sql_constraint时

选取翻译根据src的值和lang类型去匹配翻译,从数据库中匹配的第一个值来显示。所以如果这个翻译值的src有重复的话,显示的翻译可能是有问题的。

2.3.type=selection时

先从数据库中选出所有name字段匹配的翻译,然后再根据显示值去查找对应的翻译,如果没有找到则显示翻译值。

2.4.字段定义时 translate=function时,通过定义function来查找翻译

示例可以查看 xml_translate,html_translate

其他注意事项

点击可翻译字段的右侧按钮事件

如果该可翻译字段没有翻译值,点击按钮会为这个字段的src的插入所有语言的翻译。(源码中只插入非英语翻译,在一段patch中修改了这段代码,把非英语过滤取消掉了。)

在界面上修改翻译

在非英文的状态下修改可翻译字段的值时只会修改该语言对应的翻译值;

英文状态下会修改记录的原始值以及翻译的src和value的值。(源码中只会修改原值,不修改翻译值,因为系统默认英文不翻译。)这一段修改是在base_addons/addons/patch_timezone/models.py:547

重写字段如何翻译

某个字段从一个模块移动到另一个模块时,该字段的“所在模块”字段并不会改变。所以需要手动去修改字段的ir_model_data数据,不然在导出翻译的时候无法导出该字段的翻译。

翻译加载机制

在系统更新或者手动加载翻译时,系统会依次去加载各个模块的po文件。

然后把所有的翻译全部写入到一个临时表中(tmp_ir_translation_import),然后根据“是否覆盖原有翻译”去更新所有已经存在的翻译,并且插入不存在的翻译。

原有的更新判断条件如下:

self._parent_table  = 'ir_translation'
self._table_name = 'tmp_ir_translation_import'
find_expr = """
        irt.lang = ti.lang
    AND irt.type = ti.type
    AND irt.name = ti.name
    AND (
            (ti.type = 'model' AND ti.res_id = irt.res_id AND ti.src = irt.src)
         OR (ti.type = 'view' AND (irt.res_id IS NULL OR ti.res_id = irt.res_id) AND irt.src = ti.src)
         OR (ti.type = 'field')
         OR (ti.type = 'help')
         OR (ti.type NOT IN ('model', 'view', 'field', 'help') AND irt.src = ti.src)
    )
"""
if self._overwrite:
    cr.execute("""UPDATE ONLY %s AS irt
        SET value = ti.value,
            src = ti.src,
            state = 'translated'
        FROM %s AS ti
        WHERE %s AND ti.value IS NOT NULL AND ti.value != '' and irt.is_customer=False
        """ % (self._parent_table, self._table_name, find_expr))

因为邮件模板的翻译经常被覆盖的问题[1] 我们对邮件模板的body_html字段做了特例。

针对所有的非html字段和mail.template,body_html字段的翻译,只判断name和res_id相等就判定已经存在,不新增翻译。

其他的html字段会保持原有的判断条件:name,res_id,src三个字段均相等才判定翻译已存在。

修改后的代码如下

find_expr = """
        irt.lang = ti.lang
    AND irt.type = ti.type
    AND irt.name = ti.name
    AND (
            (ti.type = 'model' AND ti.res_id = irt.res_id AND irt.name NOT IN %s)
         OR (ti.type = 'model' AND ti.res_id = irt.res_id AND irt.src = ti.src AND irt.name IN %s)
         OR (ti.type = 'view' AND (irt.res_id IS NULL OR ti.res_id = irt.res_id) AND irt.src = ti.src)
         OR (ti.type = 'field')
         OR (ti.type = 'help')
         OR (ti.type NOT IN ('model', 'view', 'field', 'help') AND irt.src = ti.src)
    )
    """ % (str(tuple(html_field_list)), str(tuple(html_field_list)))

插入判断条件跟更新的查询条件一致

cr.execute("""INSERT INTO %s(name, lang, res_id, src, type, value, module, state, comments, is_customer, is_public, create_uid, create_date, write_uid, write_date)
    SELECT name, lang, res_id, src, type, value, module, state, comments, False, False, 1, now(), 1, now()
      FROM %s AS ti
      WHERE NOT EXISTS(SELECT 1 FROM ONLY %s AS irt WHERE %s);
      """ % (self._parent_table, self._table_name, self._parent_table, find_expr))

_翻译说明

_方法去翻译,实际上就是去查找对应的src的任一一条翻译值(sql语句选出来的第一条),需要注意的是语言环境的传递,查找语言环境的优先级是(context.get(‘lang’),kwargs.get(‘lang’),self.env.lang,localcontext,request.env.lang)

配置文件新增参数说明

    ignore_lang 为True则不进行翻译加载操作

    lang_module_dirs  只加载该参数指定的目录的模块的翻译

[1]html字段在编辑不保存的情况下会自动新增一个

标签,当在英文状态下修改模板内容时,不做任何修改的情况下body_html的值仍然判定为修改。这个时候会同时修改src,而翻译字段的右侧按钮会在点击的同时更新所有的翻译值的src(这个功能已经被去掉了,因为这个动作在我们不知晓的情况下修改了src,很多翻译问题无法准确定位,影响就是存在很多src不一样的同一个字段值的翻译记录)。

注:
当使用_()方法来翻译python代码的时候,如果传入这个方法的字符串里面有占位符,正确的做法应该是在这个方法调用后来传入占位符:(“hello,%s”) % name,这样在对应的翻译中应该要保留"%s"这个占位符,而不是写成(“hello,%s” % name),因为这个name变量是可变的

不过,这样也有问题,name可变,就是说它翻译不出来了。。比如有时候name=‘张三’,有的时候name=‘zhang three’。本身就不应该翻译变量,应该翻译常量。

字段移动过模块,需要更新字段对应的ir_model_data中的模块字段,不然无法导出翻译

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值