]> source.dussan.org Git - nextcloud-server.git/commitdiff
Added OC.L10N namespace with translation functions
authorVincent Petry <pvince81@owncloud.com>
Fri, 17 Oct 2014 17:47:37 +0000 (19:47 +0200)
committerThomas Müller <thomas.mueller@tmit.eu>
Wed, 29 Oct 2014 09:09:12 +0000 (10:09 +0100)
Added addTranslations and fixed de.js file

Fixed de.js to use OC.L10N.register() and use to correct expected
format.

Added JS unit tests for OC.L10N class

Include translations JS script for all apps

17 files changed:
apps/files/index.php
apps/files_encryption/appinfo/app.php
apps/files_external/appinfo/app.php
apps/files_sharing/appinfo/app.php
apps/files_trashbin/appinfo/app.php
apps/files_versions/appinfo/app.php
apps/user_ldap/appinfo/app.php
apps/user_webdavauth/appinfo/app.php
core/js/core.json
core/js/js.js
core/js/l10n.js [new file with mode: 0644]
core/js/tests/specHelper.js
core/js/tests/specs/l10nSpec.js [new file with mode: 0644]
lib/base.php
lib/private/template/functions.php
lib/private/util.php
lib/public/util.php

index bc74e17aee131b9ea429c6d502646c154591477d..4142a02b97e04f17627d2dd0d851ce53216f42c7 100644 (file)
@@ -28,6 +28,7 @@ OCP\User::checkLoggedIn();
 OCP\Util::addStyle('files', 'files');
 OCP\Util::addStyle('files', 'upload');
 OCP\Util::addStyle('files', 'mobile');
+OCP\Util::addTranslations('files');
 OCP\Util::addscript('files', 'app');
 OCP\Util::addscript('files', 'file-upload');
 OCP\Util::addscript('files', 'jquery.iframe-transport');
index 922d9885164e14120b913ccd3993c827529aac3d..aa709fbac652e4255df65bb0640be765a4073aad 100644 (file)
@@ -14,6 +14,7 @@ OC::$CLASSPATH['OCA\Encryption\Helper'] = 'files_encryption/lib/helper.php';
 OC::$CLASSPATH['OCA\Encryption\Exceptions\MultiKeyEncryptException'] = 'files_encryption/lib/exceptions.php';
 OC::$CLASSPATH['OCA\Encryption\Exceptions\MultiKeyDecryptException'] = 'files_encryption/lib/exceptions.php';
 
+\OCP\Util::addTranslations('files_encryption');
 \OCP\Util::addscript('files_encryption', 'encryption');
 \OCP\Util::addscript('files_encryption', 'detect-migration');
 
index 3486b8db51be1233ddf91ea04f07c22906a42ea3..ea14f7adbcf69c46d59c3f4786077dca3ab5de0e 100644 (file)
@@ -21,6 +21,8 @@ OC::$CLASSPATH['OC\Files\Storage\SFTP'] = 'files_external/lib/sftp.php';
 OC::$CLASSPATH['OC_Mount_Config'] = 'files_external/lib/config.php';
 OC::$CLASSPATH['OCA\Files\External\Api'] = 'files_external/lib/api.php';
 
+OCP\Util::addTranslations('files_external');
+
 OCP\App::registerAdmin('files_external', 'settings');
 if (OCP\Config::getAppValue('files_external', 'allow_user_mounting', 'yes') == 'yes') {
        OCP\App::registerPersonal('files_external', 'personal');
index f2c454a9ae27bfd3dfd33879fa2cc017ed20a99d..a01f8d98c7d1f49bb92eb0d8dc713a49e6257b42 100644 (file)
@@ -22,6 +22,7 @@ OC::$CLASSPATH['OCA\Files_Sharing\Exceptions\BrokenPath'] = 'files_sharing/lib/e
 OCP\Share::registerBackend('file', 'OC_Share_Backend_File');
 OCP\Share::registerBackend('folder', 'OC_Share_Backend_Folder', 'file');
 
+OCP\Util::addTranslations('files_sharing');
 OCP\Util::addScript('files_sharing', 'share');
 OCP\Util::addScript('files_sharing', 'external');
 
index fe428121a25e19c4029803e2a9365332e43457a0..7df52da6314f33e78ee167bd3dc63cd7c1d218e1 100644 (file)
@@ -1,6 +1,8 @@
 <?php
 $l = \OC::$server->getL10N('files_trashbin');
 
+OCP\Util::addTranslations('files_trashbin');
+
 OC::$CLASSPATH['OCA\Files_Trashbin\Exceptions\CopyRecursiveException'] = 'files_trashbin/lib/exceptions.php';
 
 // register hooks
index 8c517d4d0ff02dd83ed8a5b7f279563c50c72e28..78de1528f322f5360d7c8e146a173db19c6038f6 100644 (file)
@@ -5,6 +5,7 @@ OC::$CLASSPATH['OCA\Files_Versions\Storage'] = 'files_versions/lib/versions.php'
 OC::$CLASSPATH['OCA\Files_Versions\Hooks'] = 'files_versions/lib/hooks.php';
 OC::$CLASSPATH['OCA\Files_Versions\Capabilities'] = 'files_versions/lib/capabilities.php';
 
+OCP\Util::addTranslations('files_versions');
 OCP\Util::addscript('files_versions', 'versions');
 OCP\Util::addStyle('files_versions', 'versions');
 
index a26c7709d41096b34cc16c8ae26dd5e018ee9a7c..8f9fbc5129b05b5419bcb9bdc4e9398180c0eda1 100644 (file)
@@ -54,6 +54,7 @@ $entry = array(
        'href' => OCP\Util::linkTo( 'user_ldap', 'settings.php' ),
        'name' => 'LDAP'
 );
+OCP\Util::addTranslations('user_ldap');
 
 OCP\Backgroundjob::registerJob('OCA\user_ldap\lib\Jobs');
 if(OCP\App::isEnabled('user_webdavauth')) {
index 3cd227bddbefa4bbe7b1005f992d0ed54c64fd3e..125f5f406547df42fa636890c376f9589985d414 100644 (file)
@@ -28,6 +28,8 @@ OC_APP::registerAdmin('user_webdavauth', 'settings');
 OC_User::registerBackend("WEBDAVAUTH");
 OC_User::useBackend( "WEBDAVAUTH" );
 
+OCP\Util::addTranslations('user_webdavauth');
+
 // add settings page to navigation
 $entry = array(
        'id' => "user_webdavauth_settings",
index caff2b05252f5c18b0ccd12484b075744c5ffeea..e2da14028888d0712f7fe14d466f960477cfe8d1 100644 (file)
@@ -13,6 +13,7 @@
                "jquery.ocdialog.js",
                "oc-dialogs.js",
                "js.js",
+               "l10n.js",
                "share.js",
                "octemplate.js",
                "eventsource.js",
index 94b78a2e9a9c89d536b285d12f61091dc2cf6ad7..7f657f0e945c66fc0ac12fa862e46559a874f052 100644 (file)
@@ -37,121 +37,6 @@ if (
        }
 }
 
-function initL10N(app) {
-       if (!( t.cache[app] )) {
-               $.ajax(OC.filePath('core', 'ajax', 'translations.php'), {
-                       // TODO a proper solution for this without sync ajax calls
-                       async: false,
-                       data: {'app': app},
-                       type: 'POST',
-                       success: function (jsondata) {
-                               t.cache[app] = jsondata.data;
-                               t.plural_form = jsondata.plural_form;
-                       }
-               });
-
-               // Bad answer ...
-               if (!( t.cache[app] )) {
-                       t.cache[app] = [];
-               }
-       }
-       if (typeof t.plural_function[app] === 'undefined') {
-               t.plural_function[app] = function (n) {
-                       var p = (n !== 1) ? 1 : 0;
-                       return { 'nplural' : 2, 'plural' : p };
-               };
-
-               /**
-                * code below has been taken from jsgettext - which is LGPL licensed
-                * https://developer.berlios.de/projects/jsgettext/
-                * http://cvs.berlios.de/cgi-bin/viewcvs.cgi/jsgettext/jsgettext/lib/Gettext.js
-                */
-               var pf_re = new RegExp('^(\\s*nplurals\\s*=\\s*[0-9]+\\s*;\\s*plural\\s*=\\s*(?:\\s|[-\\?\\|&=!<>+*/%:;a-zA-Z0-9_\\(\\)])+)', 'm');
-               if (pf_re.test(t.plural_form)) {
-                       //ex english: "Plural-Forms: nplurals=2; plural=(n != 1);\n"
-                       //pf = "nplurals=2; plural=(n != 1);";
-                       //ex russian: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10< =4 && (n%100<10 or n%100>=20) ? 1 : 2)
-                       //pf = "nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2)";
-                       var pf = t.plural_form;
-                       if (! /;\s*$/.test(pf)) {
-                               pf = pf.concat(';');
-                       }
-                       /* We used to use eval, but it seems IE has issues with it.
-                        * We now use "new Function", though it carries a slightly
-                        * bigger performance hit.
-                       var code = 'function (n) { var plural; var nplurals; '+pf+' return { "nplural" : nplurals, "plural" : (plural === true ? 1 : plural ? plural : 0) }; };';
-                       Gettext._locale_data[domain].head.plural_func = eval("("+code+")");
-                        */
-                       var code = 'var plural; var nplurals; '+pf+' return { "nplural" : nplurals, "plural" : (plural === true ? 1 : plural ? plural : 0) };';
-                       t.plural_function[app] = new Function("n", code);
-               } else {
-                       console.log("Syntax error in language file. Plural-Forms header is invalid ["+t.plural_forms+"]");
-               }
-       }
-}
-/**
- * translate a string
- * @param {string} app the id of the app for which to translate the string
- * @param {string} text the string to translate
- * @param [vars] FIXME
- * @param {number} [count] number to replace %n with
- * @return {string}
- */
-function t(app, text, vars, count){
-       initL10N(app);
-       var _build = function (text, vars, count) {
-               return text.replace(/%n/g, count).replace(/{([^{}]*)}/g,
-                       function (a, b) {
-                               var r = vars[b];
-                               return typeof r === 'string' || typeof r === 'number' ? r : a;
-                       }
-               );
-       };
-       var translation = text;
-       if( typeof( t.cache[app][text] ) !== 'undefined' ){
-               translation = t.cache[app][text];
-       }
-
-       if(typeof vars === 'object' || count !== undefined ) {
-               return _build(translation, vars, count);
-       } else {
-               return translation;
-       }
-}
-t.cache = {};
-// different apps might or might not redefine the nplurals function correctly
-// this is to make sure that a "broken" app doesn't mess up with the
-// other app's plural function
-t.plural_function = {};
-
-/**
- * translate a string
- * @param {string} app the id of the app for which to translate the string
- * @param {string} text_singular the string to translate for exactly one object
- * @param {string} text_plural the string to translate for n objects
- * @param {number} count number to determine whether to use singular or plural
- * @param [vars] FIXME
- * @return {string} Translated string
- */
-function n(app, text_singular, text_plural, count, vars) {
-       initL10N(app);
-       var identifier = '_' + text_singular + '_::_' + text_plural + '_';
-       if( typeof( t.cache[app][identifier] ) !== 'undefined' ){
-               var translation = t.cache[app][identifier];
-               if ($.isArray(translation)) {
-                       var plural = t.plural_function[app](count);
-                       return t(app, translation[plural.plural], vars, count);
-               }
-       }
-
-       if(count === 1) {
-               return t(app, text_singular, vars, count);
-       }
-       else{
-               return t(app, text_plural, vars, count);
-       }
-}
-
 /**
 * Sanitizes a HTML string by replacing all potential dangerous characters with HTML entities
 * @param {string} s String to sanitize
@@ -584,11 +469,13 @@ OC.search.currentResult=-1;
 OC.search.lastQuery='';
 OC.search.lastResults={};
 //translations for result type ids, can be extended by apps
+// FIXME: move to later in the init process, after translations were loaded
+
 OC.search.resultTypes={
-       file: t('core','File'),
-       folder: t('core','Folder'),
-       image: t('core','Image'),
-       audio: t('core','Audio')
+       file: 'File', //t('core','File'),
+       folder: 'Folder', //t('core','Folder'),
+       image: 'Image', //t('core','Image'),
+       audio: 'Audio' //t('core','Audio')
 };
 OC.addStyle.loaded=[];
 OC.addScript.loaded=[];
diff --git a/core/js/l10n.js b/core/js/l10n.js
new file mode 100644 (file)
index 0000000..e375b7e
--- /dev/null
@@ -0,0 +1,178 @@
+/**
+ * Copyright (c) 2014 Vincent Petry <pvince81@owncloud.com>
+ *
+ * This file is licensed under the Affero General Public License version 3
+ * or later.
+ *
+ * See the COPYING-README file.
+ *
+ */
+
+/**
+ * L10N namespace with localization functions.
+ *
+ * @namespace
+ */
+OC.L10N = {
+       /**
+        * String bundles with app name as key.
+        * @type {Object.<String,String>}
+        */
+       _bundles: {},
+
+       /**
+        * Plural functions, key is app name and value is function.
+        * @type {Object.<String,Function>}
+        */
+       _pluralFunctions: {},
+
+       /**
+        * Register an app's translation bundle.
+        *
+        * @param {String} appName name of the app
+        * @param {Object<String,String>} strings bundle
+        * @param {{Function|String}} [pluralForm] optional plural function or plural string
+        */
+       register: function(appName, bundle, pluralForm) {
+               this._bundles[appName] = bundle || {};
+
+               if (_.isFunction(pluralForm)) {
+                       this._pluralFunctions[appName] = pluralForm;
+               } else {
+                       // generate plural function based on form
+                       this._pluralFunctions[appName] = this._generatePluralFunction(pluralForm);
+               }
+       },
+
+       /**
+        * Generates a plural function based on the given plural form.
+        * If an invalid form has been given, returns a default function.
+        *
+        * @param {String} pluralForm plural form
+        */
+       _generatePluralFunction: function(pluralForm) {
+               // default func
+               var func = function (n) {
+                       var p = (n !== 1) ? 1 : 0;
+                       return { 'nplural' : 2, 'plural' : p };
+               };
+
+               if (!pluralForm) {
+                       console.warn('Missing plural form in language file');
+                       return func;
+               }
+
+               /**
+                * code below has been taken from jsgettext - which is LGPL licensed
+                * https://developer.berlios.de/projects/jsgettext/
+                * http://cvs.berlios.de/cgi-bin/viewcvs.cgi/jsgettext/jsgettext/lib/Gettext.js
+                */
+               var pf_re = new RegExp('^(\\s*nplurals\\s*=\\s*[0-9]+\\s*;\\s*plural\\s*=\\s*(?:\\s|[-\\?\\|&=!<>+*/%:;a-zA-Z0-9_\\(\\)])+)', 'm');
+               if (pf_re.test(pluralForm)) {
+                       //ex english: "Plural-Forms: nplurals=2; plural=(n != 1);\n"
+                       //pf = "nplurals=2; plural=(n != 1);";
+                       //ex russian: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10< =4 && (n%100<10 or n%100>=20) ? 1 : 2)
+                       //pf = "nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2)";
+                       var pf = pluralForm;
+                       if (! /;\s*$/.test(pf)) {
+                               pf = pf.concat(';');
+                       }
+                       /* We used to use eval, but it seems IE has issues with it.
+                        * We now use "new Function", though it carries a slightly
+                        * bigger performance hit.
+                       var code = 'function (n) { var plural; var nplurals; '+pf+' return { "nplural" : nplurals, "plural" : (plural === true ? 1 : plural ? plural : 0) }; };';
+                       Gettext._locale_data[domain].head.plural_func = eval("("+code+")");
+                        */
+                       var code = 'var plural; var nplurals; '+pf+' return { "nplural" : nplurals, "plural" : (plural === true ? 1 : plural ? plural : 0) };';
+                       func = new Function("n", code);
+               } else {
+                       console.warn('Invalid plural form in language file: "' + pluralForm + '"');
+               }
+               return func;
+       },
+
+       /**
+        * Translate a string
+        * @param {string} app the id of the app for which to translate the string
+        * @param {string} text the string to translate
+        * @param [vars] map of placeholder key to value
+        * @param {number} [count] number to replace %n with
+        * @return {string}
+        */
+       translate: function(app, text, vars, count) {
+               // TODO: cache this function to avoid inline recreation
+               // of the same function over and over again in case
+               // translate() is used in a loop
+               var _build = function (text, vars, count) {
+                       return text.replace(/%n/g, count).replace(/{([^{}]*)}/g,
+                               function (a, b) {
+                                       var r = vars[b];
+                                       return typeof r === 'string' || typeof r === 'number' ? r : a;
+                               }
+                       );
+               };
+               var translation = text;
+               var bundle = this._bundles[app] || {};
+               var value = bundle[text];
+               if( typeof(value) !== 'undefined' ){
+                       translation = value;
+               }
+
+               if(typeof vars === 'object' || count !== undefined ) {
+                       return _build(translation, vars, count);
+               } else {
+                       return translation;
+               }
+       },
+
+       /**
+        * Translate a plural string
+        * @param {string} app the id of the app for which to translate the string
+        * @param {string} text_singular the string to translate for exactly one object
+        * @param {string} text_plural the string to translate for n objects
+        * @param {number} count number to determine whether to use singular or plural
+        * @param [vars] map of placeholder key to value
+        * @return {string} Translated string
+        */
+       translatePlural: function(app, textSingular, textPlural, count, vars) {
+               var identifier = '_' + textSingular + '_::_' + textPlural + '_';
+               var bundle = this._bundles[app] || {};
+               var value = bundle[identifier];
+               if( typeof(value) !== 'undefined' ){
+                       var translation = value;
+                       if ($.isArray(translation)) {
+                               var plural = this._pluralFunctions[app](count);
+                               return this.translate(app, translation[plural.plural], vars, count);
+                       }
+               }
+
+               if(count === 1) {
+                       return this.translate(app, textSingular, vars, count);
+               }
+               else{
+                       return this.translate(app, textPlural, vars, count);
+               }
+       }
+};
+
+/**
+ * translate a string
+ * @param {string} app the id of the app for which to translate the string
+ * @param {string} text the string to translate
+ * @param [vars] map of placeholder key to value
+ * @param {number} [count] number to replace %n with
+ * @return {string}
+ */
+window.t = _.bind(OC.L10N.translate, OC.L10N);
+
+/**
+ * translate a string
+ * @param {string} app the id of the app for which to translate the string
+ * @param {string} text_singular the string to translate for exactly one object
+ * @param {string} text_plural the string to translate for n objects
+ * @param {number} count number to determine whether to use singular or plural
+ * @param [vars] map of placeholder key to value
+ * @return {string} Translated string
+ */
+window.n = _.bind(OC.L10N.translatePlural, OC.L10N);
+
index b62a0efe40daab54fc99874e916f91f288e43e1a..4111b6763d985095824148fe26d04a0af8dcfff2 100644 (file)
@@ -113,15 +113,6 @@ window.isPhantom = /phantom/i.test(navigator.userAgent);
                // must use fake responses for expected calls
                fakeServer = sinon.fakeServer.create();
 
-               // return fake translations as they might be requested for many test runs
-               fakeServer.respondWith(/\/index.php\/core\/ajax\/translations.php$/, [
-                               200, {
-                                       "Content-Type": "application/json"
-                               },
-                               '{"data": [], "plural_form": "nplurals=2; plural=(n != 1);"}'
-                       ]
-               );
-
                // make it globally available, so that other tests can define
                // custom responses
                window.fakeServer = fakeServer;
diff --git a/core/js/tests/specs/l10nSpec.js b/core/js/tests/specs/l10nSpec.js
new file mode 100644 (file)
index 0000000..d5b0363
--- /dev/null
@@ -0,0 +1,101 @@
+/**
+ * Copyright (c) 2014 Vincent Petry <pvince81@owncloud.com>
+ *
+ * This file is licensed under the Affero General Public License version 3
+ * or later.
+ *
+ * See the COPYING-README file.
+ *
+ */
+
+describe('OC.L10N tests', function() {
+       var TEST_APP = 'jsunittestapp';
+
+       afterEach(function() {
+               delete OC.L10N._bundles[TEST_APP];
+       });
+
+       describe('text translation', function() {
+               beforeEach(function() {
+                       OC.L10N.register(TEST_APP, {
+                               'Hello world!': 'Hallo Welt!',
+                               'Hello {name}, the weather is {weather}': 'Hallo {name}, das Wetter ist {weather}',
+                               'sunny': 'sonnig'
+                       });
+               });
+               it('returns untranslated text when no bundle exists', function() {
+                       delete OC.L10N._bundles[TEST_APP];
+                       expect(t(TEST_APP, 'unknown text')).toEqual('unknown text');
+               });
+               it('returns untranslated text when no key exists', function() {
+                       expect(t(TEST_APP, 'unknown text')).toEqual('unknown text');
+               });
+               it('returns translated text when key exists', function() {
+                       expect(t(TEST_APP, 'Hello world!')).toEqual('Hallo Welt!');
+               });
+               it('returns translated text with placeholder', function() {
+                       expect(
+                               t(TEST_APP, 'Hello {name}, the weather is {weather}', {name: 'Steve', weather: t(TEST_APP, 'sunny')})
+                       ).toEqual('Hallo Steve, das Wetter ist sonnig');
+               });
+       });
+       describe('plurals', function() {
+               function checkPlurals() {
+                       expect(
+                               n(TEST_APP, 'download %n file', 'download %n files', 0)
+                       ).toEqual('0 Dateien herunterladen');
+                       expect(
+                               n(TEST_APP, 'download %n file', 'download %n files', 1)
+                       ).toEqual('1 Datei herunterladen');
+                       expect(
+                               n(TEST_APP, 'download %n file', 'download %n files', 2)
+                       ).toEqual('2 Dateien herunterladen');
+                       expect(
+                               n(TEST_APP, 'download %n file', 'download %n files', 1024)
+                       ).toEqual('1024 Dateien herunterladen');
+               }
+
+               it('generates plural for default text when translation does not exist', function() {
+                       OC.L10N.register(TEST_APP, {
+                       });
+                       expect(
+                               n(TEST_APP, 'download %n file', 'download %n files', 0)
+                       ).toEqual('download 0 files');
+                       expect(
+                               n(TEST_APP, 'download %n file', 'download %n files', 1)
+                       ).toEqual('download 1 file');
+                       expect(
+                               n(TEST_APP, 'download %n file', 'download %n files', 2)
+                       ).toEqual('download 2 files');
+                       expect(
+                               n(TEST_APP, 'download %n file', 'download %n files', 1024)
+                       ).toEqual('download 1024 files');
+               });
+               it('generates plural with default function when no forms specified', function() {
+                       OC.L10N.register(TEST_APP, {
+                               '_download %n file_::_download %n files_':
+                                       ['%n Datei herunterladen', '%n Dateien herunterladen']
+                       });
+                       checkPlurals();
+               });
+               it('generates plural with generated function when forms is specified', function() {
+                       OC.L10N.register(TEST_APP, {
+                               '_download %n file_::_download %n files_':
+                                       ['%n Datei herunterladen', '%n Dateien herunterladen']
+                       }, 'nplurals=2; plural=(n != 1);');
+                       checkPlurals();
+               });
+               it('generates plural with function when forms is specified as function', function() {
+                       OC.L10N.register(TEST_APP, {
+                               '_download %n file_::_download %n files_':
+                                       ['%n Datei herunterladen', '%n Dateien herunterladen']
+                       }, function(n) {
+                               return {
+                                       nplurals: 2,
+                                       plural: (n !== 1) ? 1 : 0
+                               };
+                       });
+                       checkPlurals();
+               });
+       });
+});
index 3d374f12f7d7d356c8934fadd3bb228f2659c2fd..3554911abb9752a66e61d5f7987f758b457a9bf6 100644 (file)
@@ -338,6 +338,7 @@ class OC {
                OC_Util::addScript("jquery.ocdialog");
                OC_Util::addScript("oc-dialogs");
                OC_Util::addScript("js");
+               OC_Util::addScript("l10n");
                OC_Util::addScript("octemplate");
                OC_Util::addScript("eventsource");
                OC_Util::addScript("config");
index cbe751e59b507a0c72ad730f13b2ac8a5b37a59d..8c94b7cf345bba08273206e77b95ad4eea6dc14d 100644 (file)
@@ -55,6 +55,22 @@ function style($app, $file) {
        }
 }
 
+/**
+ * Shortcut for adding translations to a page
+ * @param string $app the appname
+ * @param string|string[] $file the filename,
+ * if an array is given it will add all styles
+ */
+function translation($app, $file) {
+       if(is_array($file)) {
+               foreach($file as $f) {
+                       OC_Util::addStyle($app, $f);
+               }
+       } else {
+               OC_Util::addStyle($app, $file);
+       }
+}
+
 /**
  * Shortcut for HTML imports
  * @param string $app the appname
index 6cd982c222ee27b4f99bace11844ca9e10ddd3d7..5105bb2293117c825644b3da2b75a00a2cb509de 100644 (file)
@@ -333,7 +333,7 @@ class OC_Util {
        /**
         * add a javascript file
         *
-        * @param string $application
+        * @param string $application application id
         * @param string|null $file filename
         * @return void
         */
@@ -349,10 +349,28 @@ class OC_Util {
                }
        }
 
+       /**
+        * add a translation JS file
+        *
+        * @param string $application application id
+        * @param string $languageCode language code, defaults to the current language
+        */
+       public static function addTranslations($application, $languageCode = null) {
+               if (is_null($languageCode)) {
+                       $l = new \OC_L10N($application);
+                       $languageCode = $l->getLanguageCode($application);
+               }
+               if (!empty($application)) {
+                       self::$scripts[] = "$application/l10n/$languageCode";
+               } else {
+                       self::$scripts[] = "js/$languageCode";
+               }
+       }
+
        /**
         * add a css file
         *
-        * @param string $application
+        * @param string $application application id
         * @param string|null $file filename
         * @return void
         */
index 4c4a84af240968bcca87cdf224f74ba99d421b6a..22ded1d0fc5f9f592834fe212cd09240b7f935a2 100644 (file)
@@ -136,6 +136,15 @@ class Util {
                \OC_Util::addScript( $application, $file );
        }
 
+       /**
+        * Add a translation JS file
+        * @param string $application application id
+        * @param string $languageCode language code, defaults to the current locale
+        */
+       public static function addTranslations($application, $languageCode = null) {
+               \OC_Util::addTranslations($application, $languageCode);
+       }
+
        /**
         * Add a custom element to the header
         * @param string $tag tag name of the element