diff options
author | ArthurHoaro <arthur@hoa.ro> | 2018-03-26 20:26:10 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-03-26 20:26:10 +0200 |
commit | 9b2bd66fb60ffd5a833480bf329062c7d57bc8c4 (patch) | |
tree | d0a99bd7b366a9bdd6c92ab9e95db6dce4de1d3c | |
parent | 838ef8a6ec140bd21124258e584be220be55048f (diff) | |
parent | 68c6afc56f3758154cfb96cba6fd48a6b5535590 (diff) | |
download | Shaarli-9b2bd66fb60ffd5a833480bf329062c7d57bc8c4.tar.gz Shaarli-9b2bd66fb60ffd5a833480bf329062c7d57bc8c4.tar.zst Shaarli-9b2bd66fb60ffd5a833480bf329062c7d57bc8c4.zip |
Merge pull request #1093 from ArthurHoaro/feature/theme-translation
Load theme translations files automatically
-rw-r--r-- | application/Languages.php | 20 | ||||
-rw-r--r-- | doc/md/Translations.md | 12 | ||||
-rw-r--r-- | tests/LanguagesTest.php | 26 | ||||
-rw-r--r-- | tests/languages/fr/LanguagesFrTest.php | 26 | ||||
-rw-r--r-- | tests/utils/customtpl/dummy/language/fr/LC_MESSAGES/dummy.mo | bin | 0 -> 431 bytes | |||
-rw-r--r-- | tests/utils/customtpl/dummy/language/fr/LC_MESSAGES/dummy.po | 16 |
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 | ||
77 | Save when you're done, then you can submit a pull request containing the new `shaarli.po`. | 77 | Save when you're done, then you can submit a pull request containing the new `shaarli.po`. |
78 | 78 | ||
79 | ### Theme translations | ||
80 | |||
81 | Theme translation extensions are loaded automatically if they're present. | ||
82 | |||
83 | As 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 | |||
88 | Where `<lang>` is the ISO 3166-1 alpha-2 language code. | ||
89 | Read 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 | ||
81 | If you're writing a custom theme, or a non official plugin, you might want to use the translation system, | 93 | If 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 @@ | |||
1 | msgid "" | ||
2 | msgstr "" | ||
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 | |||
15 | msgid "rooster" | ||
16 | msgstr "coq" | ||