luci-mod-network: fixes to i18n
[project/luci.git] / docs / i18n.md
1 # Internationalization (i18n)
2
3 See [online wiki](https://github.com/openwrt/luci/wiki/i18n) for latest version.
4
5 ## Use translation function
6
7 ### Translations in JavaScript
8
9 Wrap translatable strings with `_()` e.g. `_('string to translate')` and the `i18n-scan.pl` and friends will correctly identify these strings as they do with all the existing translations.
10
11 If you have multi line strings you can split them with concatenation:
12 ```js
13 var mystr = _('this string will translate ' +
14 'correctly even though it is ' +
15 'a multi line string!');
16 ```
17
18 You may also use line continuations `\` syntax:
19
20 ```js
21 var mystr = _('this string will translate \
22 correctly even though it is \
23 a multi line string');
24 ```
25
26 Usually if you have multiple sentences you may need to use a line break then use the `<br />` HTML tag:
27 ```js
28 var mystr = _('Port number.<br />' +
29 'E.g. 80 for HTTP');
30 ```
31
32 To simplify a job for translators it may be better to split into separate keys without the `<br />`:
33 ```js
34 var mystr = _('Port number.') + '<br />' +
35 _('E.g. 80 for HTTP');
36 ```
37 Please use `<br />` and **not** `<br>` or `<br/>`.
38
39 If you have a link inside a translation then try to move its attributes out of a translation key like:
40 ```js
41 var mystr = _('For further information <a %s>check the wiki</a>')
42 .format('href="https://openwrt.org/docs/" target="_blank" rel="noreferrer"')
43 ```
44 This will generate a full link with HTML `For further information <a href="https://openwrt.org/docs/" target="_blank" rel="noreferrer">check the wiki</a>`. The `noreferrer` is important when making a link that is opened in a new tab (`target="_blank"`).
45
46 ### Translations in LuCI lua+html templates
47 Use the `<%: text to translate %>` as documented on [Templates](./Templates.md)
48
49 ### Translations in Lua controller code and Lua CBIs
50 As hinted at in the Templates doc, the `%:` invokes a `translate()` function.
51 In most controller contexts, this is already available for you, but if necessary, is available for include in `luci.i18n.translate`
52
53
54 ## Translation files
55 Translations are saved in the folder `po/` within each individual LuCI component directory, e.g. `applications/luci-app-acl/po/`.
56 The template is in `po/templates/<package>.pot`.
57 The actual translation files can be found at `po/[lang]/[package].po`.
58
59 In order to use the commands below you need to have the `gettext` utilities (`msgcat`, `msgfmt`, `msgmerge`) installed on your system.
60 On Debian/Ubuntu, install them with `sudo apt install gettext`.
61
62 ### Initialize po files
63
64 When you add or update an app, run from your `applications/luci-app-acl/` app folder:
65
66 ../../build/i18n-add-language.sh
67
68 This creates the skeleton .po files for all available languages open for translation for your app.
69
70 Or from the luci repo root:
71
72 ./build/i18n-add-language.sh
73
74 This creates the skeleton .po files for all existing languages open for translation for all sub-folders.
75
76 ### Rebuild po files (for existing languages)
77 After you make changes to a package, run:
78
79 ./build/i18n-sync.sh applications/[application]
80
81 Example:
82
83 ./build/i18n-sync.sh applications/luci-app-acl
84
85 This only updates those language .po files that already exist in `applications/luci-app-acl/po/`. See the previous step to add a new language.
86
87 Note: the directory argument can be omitted to update all po template and po files.
88
89
90 Some packages share translation files, in this case you need to scan through all their folders:
91
92 ./build/i18n-scan.pl applications/[package-1] applications/[package-2] applications/[package-n] > [location of shared template]/[application].pot
93
94 This is what the `mkbasepot.sh` script does for the `luci-base` module:
95
96 ./build/i18n-scan.pl \
97 modules/luci-base modules/luci-compat modules/luci-lua-runtime \
98 modules/luci-mod-network modules/luci-mod-status modules/luci-mod-system \
99 protocols themes \
100 > modules/luci-base/po/templates/base.pot
101
102 *Note:* The translation catalog for the base system covers multiple components. Use the following commands to update it:
103
104 ./build/mkbasepot.sh
105 ./build/i18n-update.pl
106
107 ### LMO files
108 The `*.po` files are big so Luci needs them in a compact compiled [LMO format](./LMO.md).
109 Luci reads `*.lmo` translations from the `/usr/lib/lua/luci/i18n/` folder.
110 E.g. `luci-app-acl` has an Arabic translation in `luci-i18n-acl-ar` package that installs `/usr/lib/lua/luci/i18n/acl.ar.lmo` file.
111
112 In order to quickly convert a single `.po` file to `.lmo` file for testing on the target system use the `po2lmo` utility.
113 You will need to compile it from the `luci-base` module:
114
115 $ cd modules/luci-base/src/
116 $ make po2lmo
117 $ ./po2lmo
118 Usage: ./po2lmo input.po output.lmo
119
120 Now you can compile and upload the translation:
121
122 ./po2lmo ../../../applications/luci-app-acl/po/ar/acl.po ./acl.ar.lmo
123 scp ./acl.ar.lmo root@192.168.1.1:/usr/lib/lua/luci/i18n/
124
125 You can change languages in [System /Language and Style](http://192.168.1.1/cgi-bin/luci/admin/system/system) and check the translation.