aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorArthurHoaro <arthur@hoa.ro>2018-02-26 22:53:00 +0100
committerArthurHoaro <arthur@hoa.ro>2018-03-26 19:20:25 +0200
commit68c6afc56f3758154cfb96cba6fd48a6b5535590 (patch)
treebabc499a94679e8897f70d3024d7b2c359f387e4
parentddd3c19f4336495bbc8927fd552db0c4d9fe6662 (diff)
downloadShaarli-68c6afc56f3758154cfb96cba6fd48a6b5535590.tar.gz
Shaarli-68c6afc56f3758154cfb96cba6fd48a6b5535590.tar.zst
Shaarli-68c6afc56f3758154cfb96cba6fd48a6b5535590.zip
Load theme translations files automatically
Fixes #1077 Take a look at the docs update to see how it works
-rw-r--r--application/Languages.php20
-rw-r--r--doc/md/Translations.md12
-rw-r--r--tests/LanguagesTest.php26
-rw-r--r--tests/languages/fr/LanguagesFrTest.php26
-rw-r--r--tests/utils/customtpl/dummy/language/fr/LC_MESSAGES/dummy.mobin0 -> 431 bytes
-rw-r--r--tests/utils/customtpl/dummy/language/fr/LC_MESSAGES/dummy.po16
6 files changed, 98 insertions, 2 deletions
diff --git a/application/Languages.php b/application/Languages.php
index 3eb3388f..db4b84ae 100644
--- a/application/Languages.php
+++ b/application/Languages.php
@@ -98,6 +98,12 @@ class Languages
98 $this->translator->setLanguage($this->language); 98 $this->translator->setLanguage($this->language);
99 $this->translator->loadDomain(self::DEFAULT_DOMAIN, 'inc/languages'); 99 $this->translator->loadDomain(self::DEFAULT_DOMAIN, 'inc/languages');
100 100
101 // Default extension translation from the current theme
102 $themeTransFolder = rtrim($this->conf->get('raintpl_tpl'), '/') .'/'. $this->conf->get('theme') .'/language';
103 if (is_dir($themeTransFolder)) {
104 $this->translator->loadDomain($this->conf->get('theme'), $themeTransFolder, false);
105 }
106
101 foreach ($this->conf->get('translation.extensions', []) as $domain => $translationPath) { 107 foreach ($this->conf->get('translation.extensions', []) as $domain => $translationPath) {
102 if ($domain !== self::DEFAULT_DOMAIN) { 108 if ($domain !== self::DEFAULT_DOMAIN) {
103 $this->translator->loadDomain($domain, $translationPath, false); 109 $this->translator->loadDomain($domain, $translationPath, false);
@@ -116,12 +122,23 @@ class Languages
116 $translations = new Translations(); 122 $translations = new Translations();
117 // Core translations 123 // Core translations
118 try { 124 try {
119 /** @var Translations $translations */
120 $translations = $translations->addFromPoFile('inc/languages/'. $this->language .'/LC_MESSAGES/shaarli.po'); 125 $translations = $translations->addFromPoFile('inc/languages/'. $this->language .'/LC_MESSAGES/shaarli.po');
121 $translations->setDomain('shaarli'); 126 $translations->setDomain('shaarli');
122 $this->translator->loadTranslations($translations); 127 $this->translator->loadTranslations($translations);
123 } catch (\InvalidArgumentException $e) {} 128 } catch (\InvalidArgumentException $e) {}
124 129
130 // Default extension translation from the current theme
131 $theme = $this->conf->get('theme');
132 $themeTransFolder = rtrim($this->conf->get('raintpl_tpl'), '/') .'/'. $theme .'/language';
133 if (is_dir($themeTransFolder)) {
134 try {
135 $translations = Translations::fromPoFile(
136 $themeTransFolder .'/'. $this->language .'/LC_MESSAGES/'. $theme .'.po'
137 );
138 $translations->setDomain($theme);
139 $this->translator->loadTranslations($translations);
140 } catch (\InvalidArgumentException $e) {}
141 }
125 142
126 // Extension translations (plugins, themes, etc.). 143 // Extension translations (plugins, themes, etc.).
127 foreach ($this->conf->get('translation.extensions', []) as $domain => $translationPath) { 144 foreach ($this->conf->get('translation.extensions', []) as $domain => $translationPath) {
@@ -130,7 +147,6 @@ class Languages
130 } 147 }
131 148
132 try { 149 try {
133 /** @var Translations $extension */
134 $extension = Translations::fromPoFile($translationPath . $this->language .'/LC_MESSAGES/'. $domain .'.po'); 150 $extension = Translations::fromPoFile($translationPath . $this->language .'/LC_MESSAGES/'. $domain .'.po');
135 $extension->setDomain($domain); 151 $extension->setDomain($domain);
136 $this->translator->loadTranslations($extension); 152 $this->translator->loadTranslations($extension);
diff --git a/doc/md/Translations.md b/doc/md/Translations.md
index 54a36655..c7d33855 100644
--- a/doc/md/Translations.md
+++ b/doc/md/Translations.md
@@ -76,6 +76,18 @@ Then click on the "Update" button, and you can start to translate every availabl
76 76
77Save when you're done, then you can submit a pull request containing the new `shaarli.po`. 77Save when you're done, then you can submit a pull request containing the new `shaarli.po`.
78 78
79### Theme translations
80
81Theme translation extensions are loaded automatically if they're present.
82
83As a theme developer, all you have to do is to add the `.po` and `.mo` compiled file like this:
84
85 tpl/<theme name>/language/<lang>/LC_MESSAGES/<theme name>.po
86 tpl/<theme name>/language/<lang>/LC_MESSAGES/<theme name>.mo
87
88Where `<lang>` is the ISO 3166-1 alpha-2 language code.
89Read the following section "Extend Shaarli's translation" to learn how to generate those files.
90
79### Extend Shaarli's translation 91### Extend Shaarli's translation
80 92
81If you're writing a custom theme, or a non official plugin, you might want to use the translation system, 93If you're writing a custom theme, or a non official plugin, you might want to use the translation system,
diff --git a/tests/LanguagesTest.php b/tests/LanguagesTest.php
index 864ce630..4951e09a 100644
--- a/tests/LanguagesTest.php
+++ b/tests/LanguagesTest.php
@@ -176,6 +176,32 @@ class LanguagesTest extends \PHPUnit_Framework_TestCase
176 } 176 }
177 177
178 /** 178 /**
179 * Test t() with an extension language file coming from the theme in gettext mode
180 */
181 public function testTranslationThemeExtensionGettext()
182 {
183 $this->conf->set('translation.mode', 'gettext');
184 $this->conf->set('raintpl_tpl', 'tests/utils/customtpl/');
185 $this->conf->set('theme', 'dummy');
186 new Languages('en', $this->conf);
187 $txt = 'rooster'; // ignore me poedit
188 $this->assertEquals('rooster', t($txt, $txt, 1, 'dummy'));
189 }
190
191 /**
192 * Test t() with an extension language file coming from the theme in PHP mode
193 */
194 public function testTranslationThemeExtensionPhp()
195 {
196 $this->conf->set('translation.mode', 'php');
197 $this->conf->set('raintpl_tpl', 'tests/utils/customtpl/');
198 $this->conf->set('theme', 'dummy');
199 new Languages('en', $this->conf);
200 $txt = 'rooster'; // ignore me poedit
201 $this->assertEquals('rooster', t($txt, $txt, 1, 'dummy'));
202 }
203
204 /**
179 * Test t() with an extension language file in gettext mode 205 * Test t() with an extension language file in gettext mode
180 */ 206 */
181 public function testTranslationExtensionGettext() 207 public function testTranslationExtensionGettext()
diff --git a/tests/languages/fr/LanguagesFrTest.php b/tests/languages/fr/LanguagesFrTest.php
index 79d05172..0cf74891 100644
--- a/tests/languages/fr/LanguagesFrTest.php
+++ b/tests/languages/fr/LanguagesFrTest.php
@@ -172,4 +172,30 @@ class LanguagesFrTest extends \PHPUnit_Framework_TestCase
172 $this->assertEquals('voiture', t($txt, $txt, 1, 'test')); 172 $this->assertEquals('voiture', t($txt, $txt, 1, 'test'));
173 $this->assertEquals('Fouille', t('Search', 'Search', 1, 'test')); 173 $this->assertEquals('Fouille', t('Search', 'Search', 1, 'test'));
174 } 174 }
175
176 /**
177 * Test t() with an extension language file coming from the theme in gettext mode
178 */
179 public function testTranslationThemeExtensionGettext()
180 {
181 $this->conf->set('translation.mode', 'gettext');
182 $this->conf->set('raintpl_tpl', 'tests/utils/customtpl/');
183 $this->conf->set('theme', 'dummy');
184 new Languages('en', $this->conf);
185 $txt = 'rooster'; // ignore me poedit
186 $this->assertEquals('coq', t($txt, $txt, 1, 'dummy'));
187 }
188
189 /**
190 * Test t() with an extension language file coming from the theme in PHP mode
191 */
192 public function testTranslationThemeExtensionPhp()
193 {
194 $this->conf->set('translation.mode', 'php');
195 $this->conf->set('raintpl_tpl', 'tests/utils/customtpl/');
196 $this->conf->set('theme', 'dummy');
197 new Languages('en', $this->conf);
198 $txt = 'rooster'; // ignore me poedit
199 $this->assertEquals('coq', t($txt, $txt, 1, 'dummy'));
200 }
175} 201}
diff --git a/tests/utils/customtpl/dummy/language/fr/LC_MESSAGES/dummy.mo b/tests/utils/customtpl/dummy/language/fr/LC_MESSAGES/dummy.mo
new file mode 100644
index 00000000..8daae0c9
--- /dev/null
+++ b/tests/utils/customtpl/dummy/language/fr/LC_MESSAGES/dummy.mo
Binary files differ
diff --git a/tests/utils/customtpl/dummy/language/fr/LC_MESSAGES/dummy.po b/tests/utils/customtpl/dummy/language/fr/LC_MESSAGES/dummy.po
new file mode 100644
index 00000000..90d1abb0
--- /dev/null
+++ b/tests/utils/customtpl/dummy/language/fr/LC_MESSAGES/dummy.po
@@ -0,0 +1,16 @@
1msgid ""
2msgstr ""
3"Project-Id-Version: Theme extension test\n"
4"POT-Creation-Date: 2017-05-20 13:54+0200\n"
5"PO-Revision-Date: 2018-03-26 19:09+0200\n"
6"Last-Translator: \n"
7"Language-Team: Shaarli\n"
8"Language: fr_FR\n"
9"MIME-Version: 1.0\n"
10"Content-Type: text/plain; charset=UTF-8\n"
11"Content-Transfer-Encoding: 8bit\n"
12"Plural-Forms: nplurals=2; plural=(n > 1);\n"
13"X-Generator: Poedit 2.0.6\n"
14
15msgid "rooster"
16msgstr "coq"