3 namespace Drupal\Tests\system\Functional\Theme;
5 use Drupal\Core\Language\LanguageInterface;
6 use Drupal\Tests\BrowserTestBase;
9 * Tests Twig "trans" tags.
13 class TwigTransTest extends BrowserTestBase {
20 public static $modules = [
28 * An administrative user for testing.
30 * @var \Drupal\user\Entity\User
39 protected $languages = [
47 protected function setUp() {
51 \Drupal::service('theme_handler')->install(['test_theme']);
52 $this->config('system.theme')->set('default', 'test_theme')->save();
54 // Create and log in as admin.
55 $this->adminUser = $this->drupalCreateUser([
56 'administer languages',
57 'access administration pages',
58 'administer site configuration',
59 'translate interface',
61 $this->drupalLogin($this->adminUser);
64 $this->installLanguages();
66 // Assign Lolspeak (xx) to be the default language.
67 $this->config('system.site')->set('default_langcode', 'xx')->save();
68 $this->rebuildContainer();
70 // Check that lolspeak is the default language for the site.
71 $this->assertEqual(\Drupal::languageManager()->getDefaultLanguage()->getId(), 'xx', 'Lolspeak is the default language');
75 * Test Twig "trans" tags.
77 public function testTwigTransTags() {
78 // Run this once without and once with Twig debug because trans can work
79 // differently depending on that setting.
80 $this->drupalGet('twig-theme-test/trans', ['language' => \Drupal::languageManager()->getLanguage('xx')]);
81 $this->assertTwigTransTags();
83 // Enable debug, rebuild the service container, and clear all caches.
84 $parameters = $this->container->getParameter('twig.config');
85 $parameters['debug'] = TRUE;
86 $this->setContainerParameter('twig.config', $parameters);
87 $this->rebuildContainer();
90 $this->drupalGet('twig-theme-test/trans', ['language' => \Drupal::languageManager()->getLanguage('xx')]);
91 $this->assertTwigTransTags();
95 * Test empty Twig "trans" tags.
97 public function testEmptyTwigTransTags() {
99 '#type' => 'inline_template',
100 '#template' => '{% trans %}{% endtrans %}',
102 /** @var \Drupal\Core\Render\RendererInterface $renderer */
103 $renderer = \Drupal::service('renderer');
106 $renderer->renderPlain($elements);
108 $this->fail('{% trans %}{% endtrans %} did not throw an exception.');
110 catch (\Twig_Error_Syntax $e) {
111 $this->assertTrue(strstr($e->getMessage(), '{% trans %} tag cannot be empty'), '{% trans %}{% endtrans %} threw the expected exception.');
113 catch (\Exception $e) {
114 $this->fail('{% trans %}{% endtrans %} threw an unexpected exception.');
119 * Asserts Twig trans tags.
121 protected function assertTwigTransTags() {
124 '{% trans "Hello sun." %} was successfully translated.'
129 '{% trans "Hello sun." with {"context": "Lolspeak"} %} was successfully translated.'
134 '{{ "Hello Earth."|trans }} was successfully translated.'
139 '{% trans %}Hello moon.{% endtrans %} was successfully translated.'
144 '{% trans %} with {% plural count = 1 %} was successfully translated.'
149 '{% trans %} with {% plural count = 2 %} was successfully translated.'
153 'ESCAPEE: &"<>',
154 '{{ token }} was successfully translated and prefixed with "@".'
158 'PLAYSHOLDR: <em class="placeholder">&"<></em>',
159 '{{ token|placeholder }} was successfully translated and prefixed with "%".'
163 'DIS complex token HAZ LENGTH OV: 3. IT CONTAYNZ: <em class="placeholder">12345</em> AN &"<>.',
164 '{{ complex.tokens }} were successfully translated with appropriate prefixes.'
169 '{% trans %} with a context only msgid was excluded from translation.'
174 '{% trans with {"context": "Lolspeak"} %} was successfully translated with context.'
179 '{% trans with {"langcode": "zz"} %} was successfully translated in specified language.'
184 '{% trans with {"context": "Lolspeak", "langcode": "zz"} %} was successfully translated with context in specified language.'
186 // Makes sure https://www.drupal.org/node/2489024 doesn't happen without
188 $this->assertNoText(pi(), 'Running php code inside a Twig trans is not possible.');
192 * Helper function: install languages.
194 protected function installLanguages() {
195 foreach ($this->languages as $langcode => $name) {
196 // Generate custom .po contents for the language.
197 $contents = $this->poFileContents($langcode);
199 // Add test language for translation testing.
201 'predefined_langcode' => 'custom',
202 'langcode' => $langcode,
204 'direction' => LanguageInterface::DIRECTION_LTR,
207 // Install the language in Drupal.
208 $this->drupalPostForm('admin/config/regional/language/add', $edit, t('Add custom language'));
209 $this->assertRaw('"edit-languages-' . $langcode . '-weight"', 'Language code found.');
211 // Import the custom .po contents for the language.
212 $filename = \Drupal::service('file_system')->tempnam('temporary://', "po_") . '.po';
213 file_put_contents($filename, $contents);
215 'files[file]' => $filename,
216 'langcode' => $langcode,
217 'customized' => TRUE,
219 $this->drupalPostForm('admin/config/regional/translate/import', $options, t('Import'));
220 drupal_unlink($filename);
223 $this->container->get('language_manager')->reset();
227 * Generate a custom .po file for a specific test language.
229 * @param string $langcode
230 * The langcode of the specified language.
232 * @return string|false
233 * The .po contents for the specified language or FALSE if none exists.
235 protected function poFileContents($langcode) {
236 if ($langcode === 'xx') {
240 "Project-Id-Version: Drupal 8\\n"
241 "MIME-Version: 1.0\\n"
242 "Content-Type: text/plain; charset=UTF-8\\n"
243 "Content-Transfer-Encoding: 8bit\\n"
244 "Plural-Forms: nplurals=2; plural=(n > 1);\\n"
251 msgstr "O HAI SUNZZZZZZZ"
254 msgstr "O HERRO ERRRF."
257 msgstr "OH HAI TEH MUUN"
260 msgid_plural "Hello @count stars."
261 msgstr[0] "O HAI STARRRRR"
262 msgstr[1] "O HAI @count STARZZZZ"
264 msgid "Escaped: @string"
265 msgstr "ESCAPEE: @string"
267 msgid "Placeholder: %string"
268 msgstr "PLAYSHOLDR: %string"
270 msgid "This @token.name has a length of: @count. It contains: %token.numbers and @token.bad_text."
271 msgstr "DIS @token.name HAZ LENGTH OV: @count. IT CONTAYNZ: %token.numbers AN @token.bad_text."
274 msgid "I have context."
275 msgstr "I HAZ KONTEX."
278 elseif ($langcode === 'zz') {
282 "Project-Id-Version: Drupal 8\\n"
283 "MIME-Version: 1.0\\n"
284 "Content-Type: text/plain; charset=UTF-8\\n"
285 "Content-Transfer-Encoding: 8bit\\n"
286 "Plural-Forms: nplurals=2; plural=(n > 1);\\n"
288 msgid "Hello new text."
289 msgstr "O HAI NU TXT."
292 msgid "Hello new text."
293 msgstr "O HAI NU TXTZZZZ."