Loading...
 
Skip to main content

History: Creating or maintaining translations

Source of version: 31 (current)

Copy to clipboard
This page explains the common processes for creating and maintaining Tiki translations, including translations of your own site customizations (~np~_custom~/np~).

! The basic idea
In PHP files, translatable text is written as ''tra("here goes the string");''.
In Smarty templates (''.tpl''), use the ~np~{tr}~/np~ block: ~np~{tr}Hello world{/tr}~/np~.
In JavaScript and Vue files (''.js'', ''.vue''), use the same ''tra("...")'' or ''tr("...")'' call (single, double, or backtick-quoted strings all work).

This is how you mark text in Tiki as translatable. Once code is written this way, the __''translation:getstrings''__ console command scans it and adds any new strings to the language files, untranslated.

Source code: [https://gitlab.com/tikiwiki/tiki/-/blob/master/lib/core/Tiki/Command/GetStringsCommand.php|GetStringsCommand.php]

! Quick start: translating an existing language
This is the most common task: someone wants to continue or improve an existing translation (e.g. French, ''fr'').

1. From the Tiki root, get the latest strings to work from:
{CODE()}
php console.php translation:getstrings --lang=fr --skip-remove
{CODE}
This updates ~np~lang/fr/language.php~/np~ with any new English strings. __Always add --skip-remove__ when refreshing an existing translation, without it, any string no longer found by the scan is deleted, including ones you already translated.
2. Edit ~np~lang/fr/language.php~/np~. Untranslated strings are commented out:
{CODE()}
// "Save" => "Save",
{CODE}
3. Uncomment and translate:
{CODE()}
"Save" => "Enregistrer",
{CODE}
4. Commit and push.

You can re-run the same command anytime to pick up newly added English strings - your existing translations are always kept, whether or not the string is still found by a fresh scan of the same file.

^Strings can be cached, so a browser may not show your new translation until the cache is cleared. Use the __Exterminator__ on the __System Admin__ page (see ((doc:System Admin))), or ~np~php console.php cache:clear~/np~.^

! Creating a brand new language
# Figure out the language code, following [http://www.ietf.org/rfc/rfc1766.txt|RFC 1766]:
** 2-letter code ([http://www.w3.org/WAI/ER/IG/ert/iso639.htm#2letter|ISO 639]) in lower case
** optionally "-" and a 2-letter country code ([http://www.iso.ch/iso/en/prods-services/iso3166ma/02iso-3166-code-lists/index.html|ISO 3166]) in upper case
** For example: ''en'' = English, ''es'' = Spanish, ''pt-BR'' = Brazilian Portuguese
# Edit ~np~lang/langmapping.php~/np~ to add the new language code and name.
# Create a new directory under ~np~lang/~/np~ named after the language code, with write permission for the web server.
# Create a starting ~np~language.php~/np~ in that directory - the ''translation:getstrings'' command (or the legacy script) updates an existing file. Either:
** copy ~np~language.php~/np~ from a language you're familiar with, or from ~np~lang/en/~/np~, as a starting point, or
** create an new one yourself.
# Now populate it with every current Tiki string, untranslated:
** __Current Tiki (console available)__:
{CODE()}
php console.php translation:getstrings --lang=fr
{CODE}
~hs~ ~hs~ ~hs~ ~hs~  ~hs~ ~hs~ ~hs~ ~hs~ ~hs~ ~hs~ ~hs~ ~hs~  ~hs~ 12.  __Very old Tiki / SVN checkout__: run ~np~get_strings.php?lang=fr~/np~ (change ''fr'' to your language code) as admin in the browser. This legacy script collects all the strings from the Tiki code the same way the console command does.
~hs~ ~hs~ 13.  Tiki detects the new language automatically once the file exists.
~hs~ ~hs~ 14.  Edit/translate ~np~lang/fr/language.php~/np~ as described in the Quick start above.

Don't forget the file must be __UTF-8 encoded__ to display correctly in Tiki.

! Translating your site customizations (_custom)
If your site has a ~np~_custom/~/np~ directory (site-specific code, themes, templates - see [https://gitlab.com/tikiwiki/tiki/-/tree/master/_custom_dist|_custom]), a normal run of ''translation:getstrings'' __also automatically__ scans it, plus translatable strings from wiki pages, and writes the result to ~np~_custom/shared/lang/<lang>/custom.php~/np~. Your core ~np~lang/~/np~ files are never touched by this pass, and vice versa.

{CODE()}
php console.php translation:getstrings --lang=fr --skip-remove
// scans core AND _custom/, updates both lang/fr/language.php and _custom/shared/lang/fr/custom.php
{CODE}

To update __only__ the customizations, skipping the core scan entirely:
{CODE()}
php console.php translation:getstrings --custom --lang=fr --skip-remove
{CODE}

~np~_custom/shared/lang/<lang>/custom.php~/np~ must already exist (even as an empty skeleton) before the first run for that language:
{CODE()}
<?php
$lang_custom = array(
);
$lang = array_merge($lang, $lang_custom);
{CODE}

__Always use --skip-remove when working with _custom__: strings there are frequently hand-added overrides with no matching source file, and without the flag they are silently deleted on every run.

! Understanding language.php
Each entry in a language file is either:
* __Translated__: ~np~"Save" => "Enregistrer",~/np~ - used as-is.
* __Untranslated__: ~np~// "Save" => "Save",~/np~ - commented out. Uncomment and fill in the translation; remove the ~np~//~/np~ or the next run will overwrite it.

By default, a string no longer found by the scan (its source file changed or was removed) is __deleted__, translation included. Pass __--skip-remove__ to keep translated strings across runs regardless of whether their source is currently found - only genuinely untranslated placeholders for a removed source are dropped.

! Command options
{CODE()}
php console.php translation:getstrings [options]
{CODE}

||
__Option__ | __Effect__
~np~--lang=xx~/np~ | Only process language xx (e.g. --lang=fr). Default: all languages found.
~np~--skip-remove~/np~ | Keep strings/translations no longer found by the scan instead of deleting them.
~np~--custom~/np~ | Only scan _custom/ and wiki pages, skipping the core scan.
~np~--outputfiles~/np~ | Add a comment with the file(s) each string was found in.
~np~--exclude=dir1,dir2~/np~ | Directories excluded from the default scan.
~np~--include=file1,file2~/np~ | Individual files scanned even inside an excluded directory.
~np~--basedir=dir~/np~ | Legacy: use a single directory as both scan root and language files location. Prefer ~np~--custom~/np~ for _custom/.
~np~--filename=name.php~/np~ | Use a different file name instead of language.php (e.g. language_r.php).
||

! Maintaining translations between branches
See ((tw:Translation branching strategy)).

Two tools are available to facilitate the merge between trunk and other branches:

* ~np~doc/devtools/mergelang.php~/np~ helps merge translations between branches - see the documentation [https://gitlab.com/tikiwiki/tiki/-/blob/master/doc/devtools/mergelang.php|in the file itself].
* ~np~get_strings.php?lang=xx&patch=lang/xx/language.patch~/np~ where the ~np~lang/xx/language.patch~/np~ is the ~np~language.php~/np~ with new translations

!- Translating as PO files
If you're more familiar with GNU Gettext's PO files, see the ((tw:PO convertor for TikiWiki)) - it makes it easier to keep translations up to date using familiar PO tooling.

!- Text editor suggestions
The file must be __UTF-8 encoded__. Any editor that supports UTF-8 works: [http://www.gnu.org/software/emacs/emacs.html|GNU Emacs] (''set-buffer-file-coding-system'', bound to 'C-x RET f'), gedit, [http://www.esperanto.mv.ru/UniRed/ENG/|UniRed] or [http://winmerge.sourceforge.net|WinMerge] on Windows (codepage 65001 for UTF-8), or [http://www.scintilla.org/SciTE.html|SciTE].

! Related
((Translations Revamp))

! Alias
* (alias(Code Howto: Add a language))
* (alias(How to add a language))
Show PHP error messages