diff --git a/developer_manual/app/view/l10n.rst b/developer_manual/app/view/l10n.rst index f26a97acd..6d45281e6 100644 --- a/developer_manual/app/view/l10n.rst +++ b/developer_manual/app/view/l10n.rst @@ -2,12 +2,19 @@ Translation =========== -.. sectionauthor:: Bernhard Posselt +.. sectionauthor:: Bernhard Posselt , Kristof Hamann + +Nextcloud provides mechanisms for internationalization (make an application translatable) and localization (add translations for specific languages). This section provides detailed instructions for both aspects. + + +Make text translatable +---------------------- + +In order to make your app translatable (internationalization), you should use Nextcloud's methods for translating strings. They are available for both the server-side (PHP, Templates) as well as for the client-side (JavaScript). -Nextcloud's translation system is powered by `Transifex `_. To start translating sign up and enter a group. If your community app should be translated by the `Nextcloud community on Transifex `_ just follow the setup section below. PHP ---- +^^^ Should it ever be needed to use localized strings on the server-side, simply inject the L10N service from the ServerContainer into the needed constructor: @@ -58,7 +65,7 @@ Strings can then be translated in the following way: private $trans; - public function __construct(IL10N $trans){ + public function __construct(IL10N $trans) { $this->trans = $trans; } @@ -71,7 +78,7 @@ Strings can then be translated in the following way: } public function getAuthorName($name) { - return $this->trans->t('Getting author %s', array($name)); + return $this->trans->t('Getting author %s', [$name]); } public function getAuthors($count, $city) { @@ -79,7 +86,7 @@ Strings can then be translated in the following way: '%n author is currently in the city %s', // singular string '%n authors are currently in the city %s', // plural string $count, - array($city) + [$city] ); } } @@ -87,7 +94,7 @@ Strings can then be translated in the following way: Templates ---------- +^^^^^^^^^ In every template the global variable **$l** can be used to translate the strings using its methods **t()** and **n()**: @@ -97,19 +104,52 @@ In every template the global variable **$l** can be used to translate the string +For the right date format use ``l('date', time()));?>``. + + + JavaScript ----------- +^^^^^^^^^^ There is a global function **t()** available for translating strings. The first argument is your app name, the second argument is the string to translate. .. code-block:: js - t('myapp', 'Hello World!'); + t(appName, 'Hello World!'); + t(appName, '{name} is available. Get more information', {name: 'Nextcloud 16', link: '...'}); For advanced usage, refer to the source code **core/js/l10n.js**; **t()** is bind to **OC.L10N.translate()**. + + +Important notes +^^^^^^^^^^^^^^^ + + +Splitting senteces +"""""""""""""""""" + +You shall never split sentences! Otherwise, translators lose the context and they have no chance to possibly re-arrange words. + +Example: + +.. code-block:: php + + t('Select file from')) . ' '; ?>t('local filesystem'));?>t(' or ')); ?>t('cloud'));?> + +Translators will translate: + +* Select file from +* local filesystem +* ' or ' +* cloud + +Translating these individual strings results in ``local filesystem`` and ``cloud`` losing case. The two white spaces surrounding ``or`` will get lost while translating as well. For languages that have a different grammatical order it prevents the translators from reordering the sentence components. + + + Hints ------ +""""" In case some translation strings may be translated wrongly because they have multiple meanings, you can add hints which will be shown in the Transifex web-interface: @@ -124,8 +164,21 @@ In case some translation strings may be translated wrongly because they have mul -Ignoring files from translation tool ------------------------------------- + + + + + + +Adding translations +------------------- + +Nextcloud's translation system is powered by `Transifex `_. To start translating sign up and enter a group. If your community app should be translated by the `Nextcloud community on Transifex `_ just follow the setup section below. + + + +Translation tool +^^^^^^^^^^^^^^^^ The translation tool scrapes the source code for method calls to **t()** or **n()** to extract the strings that should be translated. If you check @@ -139,8 +192,44 @@ the root folder of your app and specify the files one per line:: js/bruteforcesettings.js -Creating your own translatable files ------------------------------------- + +Setup of the transifex sync +^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +To setup the transifex sync within the Nextcloud community you need to add first the +transifex config to your app folder at :file:`.tx/config` (please replace **MYAPP** with your apps id):: + + [main] + host = https://www.transifex.com + lang_map = bg_BG: bg, cs_CZ: cs, fi_FI: fi, hu_HU: hu, nb_NO: nb, sk_SK: sk, th_TH: th, ja_JP: ja + + [nextcloud.MYAPP] + file_filter = translationfiles//MYAPP.po + source_file = translationfiles/templates/MYAPP.pot + source_lang = en + type = PO + +Then create a folder :file:`l10n` and a file :file:`l10n/.gitkeep` to create an +empty folder which later holds the translations. + +Now the GitHub account `@nextcloud-bot `_ needs +to get write access to your repository. It will run every night and only push +commits to the master branch once there is an update to the translation. In general +you should enable the `protected branches feature `_ +at least for the master branch. + +For the sync job there is a `configuration file `_ +available in our docker-ci repository. Adding there the repo owner and repo name +to the section named **app** via pull request is enough. Once this change is in +one member of the sysadmin team will deploy it to the sync server and the job +will then run once a day. + +If you need help then just `open a ticket with the request `_ +and we can also guide you through the steps. + + +Manual translation +^^^^^^^^^^^^^^^^^^ If Transifex is not the right choice or the app is not accepted for translation, generate the gettext strings by yourself by executing our @@ -179,36 +268,3 @@ Now the following folder structure is available:: You then just need the :file:`.json` and :file:`.js` files for a working localized app. -Setup of the transifex sync ---------------------------- - -To setup the transifex sync within the Nextcloud community you need to add first the -transifex config to your app folder at :file:`.tx/config` (please replace **MYAPP** with your apps id):: - - [main] - host = https://www.transifex.com - lang_map = bg_BG: bg, cs_CZ: cs, fi_FI: fi, hu_HU: hu, nb_NO: nb, sk_SK: sk, th_TH: th, ja_JP: ja - - [nextcloud.MYAPP] - file_filter = translationfiles//MYAPP.po - source_file = translationfiles/templates/MYAPP.pot - source_lang = en - type = PO - -Then create a folder :file:`l10n` and a file :file:`l10n/.gitkeep` to create an -empty folder which later holds the translations. - -Now the GitHub account `@nextcloud-bot `_ needs -to get write access to your repository. It will run every night and only push -commits to the master branch once there is an update to the translation. In general -you should enable the `protected branches feature `_ -at least for the master branch. - -For the sync job there is a `configuration file `_ -available in our docker-ci repository. Adding there the repo owner and repo name -to the section named **app** via pull request is enough. Once this change is in -one member of the sysadmin team will deploy it to the sync server and the job -will then run once a day. - -If you need help then just `open a ticket with the request `_ -and we can also guide you through the steps. diff --git a/developer_manual/core/translation.rst b/developer_manual/core/translation.rst deleted file mode 100644 index 7fafa9e79..000000000 --- a/developer_manual/core/translation.rst +++ /dev/null @@ -1,108 +0,0 @@ -=========== -Translation -=========== - -Make text translatable ----------------------- - -In HTML or PHP wrap it like this ``t('This is some text'));?>`` or this ``t('This is some text'));?>``. -For the right date format use ``l('date', time()));?>``. Change the way dates are shown by editing :file:`/core/l10n/l10n-{lang}.php`. - -To translate text in JavaScript use: ``t('appname','text to translate');`` - - -.. note:: ``print_unescaped()`` should be preferred only if you would like to display HTML code. Otherwise, using ``p()`` is strongly preferred to escape HTML characters against XSS attacks. - -You shall never split sentences! --------------------------------- - -Reason: -^^^^^^^ - -Translators lose the context and they have no chance to possibly re-arrange words. - -Example: -^^^^^^^^ - -.. code-block:: php - - t('Select file from')) . ' '; ?>t('local filesystem'));?>t(' or ')); ?>t('cloud'));?> - -Translators will translate: -^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -* Select file from -* local filesystem -* ' or " -* cloud - -Translating these individual strings results in ``local filesystem`` and ``cloud`` losing case. The two white spaces surrounding ``or`` will get lost while translating as well. For languages that have a different grammatical order it prevents the translators from reordering the sentence components. - -HTML on translation string: -^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -HTML tags in translation strings is ugly but usually translators can handle this. - -What about variable in the strings? -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -If you need to add variables to the translation strings do it like this: - -PHP: - -.. code-block:: php - - $l->t('%s is available. Get more information', array($data['versionstring'], $data['web'])); - -JavaScript: - -.. code-block:: javascript - - t(appName, '{name} is available. Get more information', {name: 'Nextcloud 16', link: '...'}); - -Automated synchronization of translations ------------------------------------------ - -Multiple nightly jobs have been setup in order to synchronize translations - it's a multi-step process: - -#. ``perl l10n.pl read`` will rescan all PHP and JavaScript files and generate the templates. -#. The templates are pushed to `Transifex`_ (tx push -s). -#. All translations are pulled from `Transifex`_ (tx pull -a). -#. ``perl l10n.pl write`` will write the PHP files containing the translations. -#. Finally the changes are pushed to Git. - -Please follow the steps below to add translation support to your app: -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -#. Create a folder ``l10n``. -#. Create the file ``ignorelist`` which can contain files which shall not be scanned during step 4. -#. Edit ``l10n/.tx/config`` and copy/paste a config section and adapt it by changing the app/folder name. -#. Run ``perl l10n.pl read`` within the folder :file:`l10n`. -#. Add the newly created translation template (*l10n/Templates/.pot*) to Git and commit the changes above. -#. After the next nightly sync job a new resource will appear on Transifex and from now on every night the latest translations will arrive. - -**Caution: information below is in general not needed!** - -Manual quick translation update: --------------------------------- - -.. code-block:: bash - - cd l10n/ && perl l10n.pl read && tx push -s && tx pull -a && perl l10n.pl write && cd .. - -The translation script requires Locale::PO, installable via ``apt-get install liblocale-po-perl``. - -Configure Transifex -------------------- - -.. code-block:: bash - - tx init - - for resource in calendar contacts core files media gallery settings - do - tx set --auto-local -r nextcloud.$resource "/$resource.po" --source-language=en \ - --source-file "templates/$resource.pot" --execute - done - -.. _Transifex: https://www.transifex.com/nextcloud/