Show last authors
1 = 如何翻译 =
2
3
4 ➡️ 介绍如何对iTop语言进行本地化
5
6
7 == 原则 ==
8
9
10 在 iTop 和 iTop 模块中,语言由两个要素确定:
11
12 * ISO 639-1 语言代码。例如:pt 表示葡萄牙语。
13 * ISO 国家代码。例如:br 表示巴西。
14
15 本地化依赖于字典文件,这些文件的名称以小写语言代码作为前缀,例如:pt_br.dictionary.itop.core.php。这些文件是数据模型的一部分,因此在每次修改后都需要进行编译(重新运行安装或使用工具包)。
16
17
18 在 iTop 中,嵌入的字典文件位于以下位置:
19
20 * <itop-root>/dictionaries/
21 * <itop-root>/datamodels/2.x/<module>/dictionaries
22
23 在模块中,这些文件位于模块的根目录。
24
25 自 iTop 3.0.0(N°2969)起,模块的字典文件可以位于模块的根文件夹或名为 dictionaries 的子文件夹中。
26
27 出于兼容性原因,作为扩展分发的模块保留了它们的字典文件在根文件夹中的方式,但iTop核心模块(datamodels/2.x)已经进行了修改。
28
29
30 == 字典文件格式 ==
31
32 字典实际上是一个PHP文件。它必须以UTF-8字符集编码(这是必须的)。我们建议像下面的示例一样省略PHP的结束标记:
33
34 (% class="box" %)
35 (((
36 <?php
37 /\*\*
38 \* Localized data
39 \*
40 \* @copyright   Copyright (C) 2015 John Foo Ltd
41 \* @author      John Foo (john@foo.com)
42 \* @license     http:~/~/opensource.org/licenses/AGPL-3.0
43 \*/
44 Dict::Add('PT BR', 'Brazilian', 'Portuguese', array(
45 'Menu:ChangeManagement' => 'Gerenciamento Mudanças',
46 'Menu:Change:Overview' => 'Visão geral',
47 'Menu:NewChange' => 'New Change~~~~',
48 ));
49 )))
50
51
52 注意事项:
53
54 * 函数调用的第一个参数是大写的语言代码。
55 * 函数调用的第二个参数是英语中的语言名称。
56 * 函数调用的第三个参数是目标语言中的语言名称。
57 * Dict::Add 函数的行在所有相同语言的字典文件中必须相同(是的,这里有冗余信息)。
58 * 请注意某些字符串末尾的 ~~~~。这个后缀不会显示给最终用户。它由Combodo在发布新版本时添加,用于显示哪些新字符串需要翻译。
59
60 == ==
61
62 == ==
63
64 == 一些通用规则 ==
65
66 一些通用规则:
67
68 * **保持一致性:** 重复使用已经翻译的术语(例如,“经理”是许多关键词中使用的词汇)。
69 * **英文术语:** 如果在上下文中更容易理解,可以保留英文术语。
70 * **避免过于口语化的表述:** iTop是一款既被公司使用又被其客户使用的产品。
71 * **不要硬编码“iTop”名称:** 使用常量(它们在 core/config.class.inc.php 中定义):
72 ** ITOP_APPLICATION:应用程序包的完整名称,例如“iTop Community”或“iTop Professional”。
73 ** ITOP_APPLICATION_SHORT:应用程序的名称,例如“iTop”。
74 * **类名命名方式:** 使用驼峰命名法。
75 * **数据模型项目命名标准:** Class:<classname>、Class:<classname>/Attribute:<fieldname>。例如:Class:Ticket、Class:Ticket/Attribute:ref、Class:UserRequest/Attribute:status/Value:new。
76 * **字段标签翻译:** 请在定义字段的类中进行翻译,而不是在子类中进行。例如,对于 Class:Ticket/Attribute:ref 是可以的,但对于 Class:Change/Attribute:ref 则不应该。如果需要后者,可以使用自定义模块将其添加到您的iTop实例中。
77 * **操作标签中的类别:** 尽量不要在通用用户的操作标签中提及类别。但对于管理员用户可以这样做。如果使用类别标签,请将其大写化,例如将“notification”改为“Notification”。
78 * **特殊条目 Class:<classname>/Attribute:friendlyname:** 在英文中显示为“Full name”,如果没有翻译,它不对应于特定的类字段,而是对应于用作外部键、对象列表和对象详情中的对象标签的魔法属性。
79
80 这些规则有助于维护和确保翻译的一致性。
81
82
83 |=Key syntax|=Purpose|=Example
84 |Class:<classname>|Translating the **name** of a class|Class:Ticket
85 |Class:<classname>/Attribute:<fieldname>|Translating a field **label**|Class:Ticket/Attribute:ref
86 |Class:<classname>/Attribute:<fieldname>/Value:<value>|Translating a **value** of an Enum attribute|Class:UserRequest/Attribute:status/Value:new
87 |Class:<classname>/Attribute|Formatting the friendlyname **value**. (//see example below//)|‘Class:Person/Name’ ⇒ ‘%2$s %1$s’
88
89 //Friendlyname 语法//: 在这个示例中
90
91 {{{'Class:Person/Name' \=> '%2$s, %1$s', /\* example: "Christie, Agatha" \*/
92 }}}
93
94 * %1$s 对应于Person类的命名XML标签中的第一个字段,因此是 first_name。
95 * %2$s 对应于Person类的命名XML标签中的第二个字段,因此是 name。
96
97 这允许指定不同的顺序,并且甚至是一些其他字符和分隔符。
98
99 您可以通过以下链接获取有关 friendlyname 的更多信息:[[friendlyname>>url:https://www.itophub.io/wiki/page?do=export_code&id=3_1_0:customization:translation&codeblock=2]]。
100
101
102 (% class="box" %)
103 (((
104 <classes\>
105 <class id\="Person"\>
106 <properties\>
107 <naming\>
108 <attributes\>
109 <attribute id\="first\_name"/> <!~-~- mapped to %1$s ~-~->
110 <attribute id\="name"/>       <!~-~- mapped to %2$s ~-~->
111 </attributes\>
112 </naming\>
113 )))
114
115 == ==
116
117 == ==
118
119 == 字典关键词的命名约定 ==
120
121 新条目的命名应根据其领域和目的,从最不具体的信息开始命名。
122
123 最常用的分隔符是’:’,但也可以找到’/‘和’-’。
124
125 (% class="box" %)
126 (((
127 'Core:BulkExport:TextFormat' \=> 'Text fields containing some HTML markup',
128 'UI:CSVImport:TextQualifierCharacter' \=> 'Text qualifier character',
129 'DayOfWeek-Sunday-Min' \=> 'Su',
130 )))
131
132
133 使用后缀来定义相同标签的变种:
134
135 * + 表示短描述(通常显示在工具提示中)
136 * ? 表示帮助/解释(可以跨多行)
137
138 (% class="box" %)
139 (((
140 'Core:SynchroAtt:update' \=> 'Update ?',
141 'Core:SynchroAtt:update+' \=> 'Used to update the object',
142 'UI:CSVImport:AdvancedMode' \=> 'Advanced mode',
143 'UI:CSVImport:AdvancedMode+' \=>
144 'In advanced mode the "id" (primary key) of the objects can be used to update and rename objects.'
145 .'However the column "id" (if present) can only be used as a search criteria'
146 .' and can not be combined with any other search criteria.',
147 )))
148
149 当建立了命名约定后,标识符应该指定为 :,就像以下示例中的方式:
150
151 (% class="box" %)
152 (((
153 'Class:Event/Attribute:date' \=> 'Date',
154 'Class:Event/Attribute:date+' \=> 'date and time at which the changes have been recorded',
155 )))
156
157 请注意,在这种情况下,分隔符应该是 ‘/’。
158
159 ==== ====
160
161 ==== ====
162
163 (% class="wikigeneratedid" %)
164 ==== ====
165
166 (% class="wikigeneratedid" %)
167 ==== ====
168
169 ==== 枚举值 ====
170
171 枚举或枚举集的值使用自己的语法:
172
173 (% class="box" %)
174 (((
175 'Class:Action/Attribute:status/Value:test'      \=> 'Being tested',
176 'Class:Action/Attribute:status/Value:test+'     \=> 'Action has maybe a different behavior than when in production',
177 'Class:Action/Attribute:status/Value:enabled'   \=> 'In production',
178 'Class:Action/Attribute:status/Value:enabled+'  \=> '',
179 'Class:Action/Attribute:status/Value:disabled' \=> 'Inactive',
180 'Class:Action/Attribute:status/Value:disabled+' \=> 'Action is not effective',
181 )))
182
183 ==== ====
184
185 ==== ====
186
187 (% class="wikigeneratedid" %)
188 ==== ====
189
190 (% class="wikigeneratedid" %)
191 ==== ====
192
193 ==== 实体覆盖 ====
194
195 子类可以覆盖属性(或值)的标签/工具提示,即使该属性已在其父类之一中定义。
196
197 (% class="box" %)
198 (((
199 'Class:ActionEmail/Attribute:status/Value:test+'       \=> 'Only the Test recipient is notified',
200 'Class:ActionEmail/Attribute:status/Value:enabled+'    \=> 'All To, Cc and Bcc emails are notified',
201 'Class:ActionEmail/Attribute:status/Value:disabled+'   \=> 'The email notification will not be sent',
202 'Class:ActionEmail/Attribute:test\_recipient'           \=> 'Test recipient',
203 )))
204
205 === ===
206
207 === ===
208
209 === 关系 ===
210
211 默认链接相关的操作/图标工具提示、弹出窗口标题和确认消息如下所示。
212
213 它们可以根据需要进行自定义,甚至可以根据类别/关联设置属性进行定制化(请参阅下文)。
214
215
216 ==== ====
217
218 ==== 1:n 关系 ====
219
220 |=通用字典条目代码|=用途|=英文|=法文
221 |UI:Links:Create:Button+|列表右上角的**加号图标**工具提示|Create a %4$s|Créer un(e) %4$s
222 |UI:Links:Create:Modal:Title|**子对象创建**弹出窗口标题|Create a %4$s in %2$s|Ajouter un(e) %4$s à %2$s
223 |UI:Links:ModifyObject:Button+|行右端的**铅笔图标**工具提示|Modify this object|Modifier cet objet
224 |UI:Links:ModifyObject:Modal:Title|**子对象修改**弹出窗口标题|Modify %5$s|Modifier %5$s
225 |UI:Links:Remove:Button+|行右端的**减号图标**工具提示|Remove this %4$s|Retirer cet(te) %4$s
226 |UI:Links:Remove:Modal:Title|**子对象从其宿主中移除**弹出窗口标题|Remove a %4$s from its %1$s|Retirer un(e) %4$s de son/sa %1$s
227 |UI:Links:Remove:Modal:Message|**子对象移除**的确认消息|Do you really want to remove %5$s from %2$s?|Voulez vous vraiment retirer %5$s de %2$s?
228 |UI:Links:Delete:Button+|行右端的**垃圾桶图标**工具提示|Delete this %4$s|Supprimer cet(te) %4$s
229 |UI:Links:Delete:Modal:Title|**子对象删除**弹出窗口标题|Delete a %4$s|Supprimer un(e) %4$s
230 |UI:Links:Delete:Modal:Message|**子对象删除**的确认消息|Do you really want to delete %5$s?|Voulez vous vraiment supprimer %5$s?
231
232 ==== ====
233
234 ==== n:n 关系 ====
235
236 |=通用字典条目代码|=用途|=英文|=法文
237 |UI:Links:Add:Button+|列表右上角的**加号图标**工具提示|Add a %4$s|Ajouter un %4$s
238 |UI:Links:Add:Modal:Title|**链接创建**弹出窗口标题|Add a %4$s to %2$s|Ajouter un %4$s à %2$s
239 |UI:Links:ModifyLink:Button+|行右端的**铅笔图标**工具提示|Modify this link|Modifier cette relation
240 |UI:Links:ModifyLink:Modal:Title|**链接修改**弹出窗口标题|Modify the link between %2$s and %5$s|Modifier la relation entre %2$s et %5$s
241 |UI:Links:Remove:Button+|行右端的**减号图标**工具提示|Remove this %4$s|Retirer ce %4$s
242 |UI:Links:Remove:Modal:Title|**链接删除**弹出窗口标题|Remove %4$s|Retirer un %4$s
243 |UI:Links:Remove:Modal:Message|**链接删除**的确认消息|Do you really want to remove %5$s from %2$s?|Voulez vous vraiment retirer %5$s de %2$s?
244
245 ===== =====
246
247 ===== **占位符** =====
248
249
250 * **$%1s**: 宿主对象类名称(本地化)
251 * **$%2s**: 宿主对象友好名称
252 * **$%3s**: 宿主对象内的当前标签名称(本地化)
253 * **$%4s**: 远程对象类名称(本地化)
254 * **$%5s**: 远程对象友好名称 注意:并非所有情况下都可用,需要检查!
255
256 ===== =====
257
258 ===== =====
259
260 ===== Specialized =====
261
262 除非为给定类的特定LinkedSet(或LinkedSetIndirect)属性定义了更具体的条目,否则使用上面的通用条目代码。
263
264 以下是考虑法语中类别属性的覆盖逻辑示例:
265
266 (% class="box" %)
267 (((
268 Dict::Add('FR FR', 'French', 'Français', [array](http:~/~/www.php.net/array)(
269 'Class:Person/Attribute:team\_list/UI:Links:Add:Button+'         \=> 'Ajouter une %4$s',
270 'Class:Person/Attribute:team\_list/UI:Links:Add:Modal:Title'     \=> 'Ajouter une %4$s à %2$s',
271 'Class:Person/Attribute:team\_list/UI:Links:Remove:Button+'      \=> 'Retirer cette %4$s',
272 'Class:Person/Attribute:team\_list/UI:Links:Remove:Modal:Title'  \=> 'Retirer une %4$s',
273 'Class:Team/Attribute:persons\_list/UI:Links:Add:Button+'        \=> 'Ajouter une %4$s',
274 'Class:Team/Attribute:persons\_list/UI:Links:Add:Modal:Title'    \=> 'Ajouter une %4$s à %2$s',
275 'Class:Team/Attribute:persons\_list/UI:Links:Remove:Button+'     \=> 'Retirer cette %4$s',
276 'Class:Team/Attribute:persons\_list/UI:Links:Remove:Modal:Title' \=> 'Retirer une %4$s'
277 ));
278 )))
279
280
281
282 === 最终用户门户 ===
283
284 如果您添加了一个新的终端用户门户,您可能希望创建一个字典条目,以便为其创建一个真实的标签,要做到这一点,请按照以下语法进行操作:
285
286 (% class="box" %)
287 (((
288 ~/~/ Default portal
289 'portal:itop-portal' \=> 'Standard portal',
290 'portal:<YOUR\_PORTAIL\_ID>' \=> 'Your new portal label',
291 )))
292
293 === ===
294
295 (% class="wikigeneratedid" %)
296 === ===
297
298 (% class="wikigeneratedid" %)
299 === ===
300
301 === UI 主题 ===
302
303 如果您为后台创建了一个新主题,您可能希望创建一个字典条目,以便用户在首选项页面中选择它时能够获得一个漂亮的标签。要做到这一点,请按照以下语法进行操作:
304
305 (% class="box" %)
306 (((
307 ~/~/ Default theme
308 'theme:fullmoon' \=> 'Full Moon ',
309 'theme:<YOUR\_THEME\_ID>' \=> 'Your new theme label',
310 )))
311
312
313 (% class="wikigeneratedid" %)
314 == ==
315
316 (% class="wikigeneratedid" %)
317 == ==
318
319 == 如何贡献改进现有语言 ==
320
321 要改进现有语言,您需要执行以下步骤:
322
323 1. 从[[iTop主存储库>>url:https://github.com/Combodo/iTop]]或相关的模块存储库创建一个分支(Fork)。
324 1. 在您的分支上进行修改,并按需改进现有语言的翻译。
325 1. 提交拉取请求(Pull Request):有关详细的提交步骤,请查看您正在修改的存储库中的CONTRIBUTING.md文件。GitHub的帮助页面也提供了关于[[从分支创建拉取请求>>url:https://help.github.com/articles/creating-a-pull-request-from-a-fork/]]的详细信息。
326
327 **为现有语言添加翻译**:使用 grep 命令查找包含 ~~~~ 的文本,并在原地进行翻译。
328
329
330 (% class="box successmessage" %)
331 (((
332 以下是在Linux命令行中查找包含 ~~~~ 标记的德语(de)字典条目的快速命令:
333 find -name "de*dict*.php" | grep -v "env-" | xargs grep "~~~~"
334 要查找其他语言的字典条目,只需将命令中的 de* 更改为您想处理的语言代码(例如fr、it、sp等),然后从安装iTop的目录运行此命令。这将帮助您找到包含 ~~~~ 标记的文本行,以便进行翻译。
335 )))
336
337 **为新语言添加翻译**:首先找到您的语言代码和国家代码。然后将英语文件(dictionary.*.php或en.dict.*.php)复制到相应的目录中,并使用相关的前缀(例如,pt_br.dict…)。然后对这些文件进行翻译。
338
339
340 (% class="box warningmessage" %)
341 (((
342 不要忘记修改 Dict::Add 函数调用的参数。如果不这样做,将在运行时用您的翻译覆盖英语文本。
343 )))
344
345 提交的拉取请求将由Combodo的维护人员进行分析,并最终合并到原始存储库中。
346
347 ----
348
349 原文:[[https:~~/~~/www.itophub.io/wiki/page?id=3_1_0:customization:translation>>url:https://www.itophub.io/wiki/page?id=3_1_0:customization:translation]]
350
351 版本:3_1_0/customization/translation.txt · Last modified: 2023/07/21 10:19 (external edit)
352
353
深圳市艾拓先锋企业管理咨询有限公司