luci-proto-openconnect: updated SSL VPN option list and update sha1 hash wording
[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 for translation.
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. Use the `<br />` HTML tag like so:
27 ```js
28 var mystr = _('Port number.') + '<br />' +
29 _('E.g. 80 for HTTP');
30 ```
31 Use `<br />` and **not** `<br>` or `<br/>`.
32
33 If you have a link inside a translation, move its attributes out of a translation key:
34 ```js
35 var mystr = _('For further information <a %s>check the wiki</a>')
36 .format('href="https://openwrt.org/docs/" target="_blank" rel="noreferrer"')
37 ```
38 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 so that it is opened in a new tab (`target="_blank"`).
39
40 ### Translations in LuCI lua+html templates
41 Use the `<%: text to translate %>` as documented on [Templates](./Templates.md)
42
43 ### Translations in Lua controller code and Lua CBIs
44 As hinted at in the Templates doc, the `%:` invokes a `translate()` function.
45 In most controller contexts, this is already available for you, but if necessary, is available for include in `luci.i18n.translate`
46
47
48 ## Translation files
49 Translations are saved in the folder `po/` within each individual LuCI component directory, e.g. `applications/luci-app-acl/po/`.
50 The template is in `po/templates/<package>.pot`.
51 The individual language translation files can be found at `po/[lang]/[package].po`.
52
53 In order to use the commands below you need to have the `gettext` utilities (`msgcat`, `msgfmt`, `msgmerge`) installed on your system.
54 On Debian/Ubuntu, install them with `sudo apt install gettext`.
55
56 ### Initialize po files
57
58 When you add or update an app, run from your `applications/luci-app-acl/` app folder:
59
60 ../../build/i18n-add-language.sh
61
62 This creates the skeleton .po files for all available languages open for translation for your app.
63
64 Or from the luci repo root:
65
66 ./build/i18n-add-language.sh
67
68 This creates the skeleton .po files for all existing languages open for translation for all sub-folders.
69
70 ### Rebuild po files (for existing languages)
71 After you make changes to a package, run:
72
73 ./build/i18n-sync.sh applications/[application]
74
75 Example:
76
77 ./build/i18n-sync.sh applications/luci-app-acl
78
79 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.
80
81 Note: the directory argument can be omitted to update all po template and po files.
82
83
84 Some packages share translation files, in this case you need to scan through all their folders:
85
86 ./build/i18n-scan.pl applications/[package-1] applications/[package-2] applications/[package-n] > [location of shared template]/[application].pot
87
88 This is what the `mkbasepot.sh` script does for the `luci-base` module:
89
90 ./build/i18n-scan.pl \
91 modules/luci-base modules/luci-compat modules/luci-lua-runtime \
92 modules/luci-mod-network modules/luci-mod-status modules/luci-mod-system \
93 protocols themes \
94 > modules/luci-base/po/templates/base.pot
95
96 *Note:* The translation catalog for the base system covers multiple components. Use the following commands to update it:
97
98 ./build/mkbasepot.sh
99 ./build/i18n-update.pl
100
101 ### LMO files
102 The `*.po` files are big so Luci needs them in a compact compiled [LMO format](./LMO.md).
103 Luci reads `*.lmo` translations from the `/usr/lib/lua/luci/i18n/` folder.
104 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.
105
106 In order to quickly convert a single `.po` file to `.lmo` file for testing on the target system use the `po2lmo` utility.
107 You will need to compile it from the `luci-base` module:
108
109 $ cd modules/luci-base/src/
110 $ make po2lmo
111 $ ./po2lmo
112 Usage: ./po2lmo input.po output.lmo
113
114 Now you can compile and upload the translation:
115
116 ./po2lmo ../../../applications/luci-app-acl/po/ar/acl.po ./acl.ar.lmo
117 scp ./acl.ar.lmo root@192.168.1.1:/usr/lib/lua/luci/i18n/
118
119 You can change languages in [System /Language and Style](http://192.168.1.1/cgi-bin/luci/admin/system/system) and check the translation.