From 099bf1dc3bbc7e1bf2deff47356fb22131fd525d Mon Sep 17 00:00:00 2001 From: Mark Carver Date: Tue, 16 Jul 2013 20:47:07 -0500 Subject: Issue #1927584 by Mark Carver, drupalninja99, penyaskito, Cottser, jenlampton, John Bickar, geoffreyr, ezeedub: Add support for the Twig {% trans %} tag extension --- .../Drupal/system/Tests/Theme/TwigTransTest.php | 264 +++++++++++++++++++++ .../twig_theme_test/TwigThemeTestController.php | 9 + .../templates/twig_theme_test.trans.html.twig | 53 +++++ .../modules/twig_theme_test/twig_theme_test.module | 4 + .../twig_theme_test/twig_theme_test.routing.yml | 6 + 5 files changed, 336 insertions(+) create mode 100644 core/modules/system/lib/Drupal/system/Tests/Theme/TwigTransTest.php create mode 100644 core/modules/system/tests/modules/twig_theme_test/templates/twig_theme_test.trans.html.twig diff --git a/core/modules/system/lib/Drupal/system/Tests/Theme/TwigTransTest.php b/core/modules/system/lib/Drupal/system/Tests/Theme/TwigTransTest.php new file mode 100644 index 0000000..f8c0a19 --- /dev/null +++ b/core/modules/system/lib/Drupal/system/Tests/Theme/TwigTransTest.php @@ -0,0 +1,264 @@ + 'Twig Translation', + 'description' => 'Test Twig "trans" tags.', + 'group' => 'Theme', + ); + } + + /** + * {@inheritdoc} + */ + protected function setUp() { + parent::setUp(); + + // Setup test_theme. + theme_enable(array('test_theme')); + \Drupal::config('system.theme')->set('default', 'test_theme')->save(); + + // Create and log in as admin. + $this->admin_user = $this->drupalCreateUser(array( + 'administer languages', + 'access administration pages', + 'administer site configuration', + 'translate interface' + )); + $this->drupalLogin($this->admin_user); + + // Add test language for translation testing. + $edit = array( + 'predefined_langcode' => 'custom', + 'langcode' => $this->langcode, + 'name' => $this->name, + 'direction' => '0', + ); + + // Install the lolspeak language. + $this->drupalPost('admin/config/regional/language/add', $edit, t('Add custom language')); + $this->assertRaw('"edit-languages-' . $this->langcode . '-weight"', 'Language code found.'); + + // Import a custom .po file for the lolspeak language. + $this->importPoFile($this->examplePoFile(), array( + 'langcode' => $this->langcode, + 'customized' => TRUE, + )); + + // Assign lolspeak to be the default language. + $edit = array('site_default_language' => $this->langcode); + $this->drupalPost('admin/config/regional/settings', $edit, t('Save configuration')); + + // Reset the static cache of the language list. + drupal_static_reset('language_list'); + + // Check that lolspeak is the default language for the site. + $this->assertEqual(language_default()->id, $this->langcode, $this->name . ' is the default language'); + } + + /** + * Test Twig "trans" tags. + */ + public function testTwigTransTags() { + $this->drupalGet('twig-theme-test/trans', array('language' => language_load('xx'))); + + $this->assertText( + 'OH HAI SUNZ', + '{% trans "Hello sun." %} was successfully translated.' + ); + + $this->assertText( + 'OH HAI TEH MUUN', + '{% trans %}Hello moon.{% endtrans %} was successfully translated.' + ); + + $this->assertText( + 'O HAI STARRRRR', + '{% trans %} with {% plural count = 1 %} was successfully translated.' + ); + + $this->assertText( + 'O HAI 2 STARZZZZ', + '{% trans %} with {% plural count = 2 %} was successfully translated.' + ); + + $this->assertRaw( + 'ESCAPEE: &"<>', + '{{ token }} was successfully translated and prefixed with "@".' + ); + + $this->assertRaw( + 'PAS-THRU: &"<>', + '{{ token|passthrough }} was successfully translated and prefixed with "!".' + ); + + $this->assertRaw( + 'PLAYSHOLDR: &"<>', + '{{ token|placeholder }} was successfully translated and prefixed with "%".' + ); + + $this->assertRaw( + 'DIS complex token HAZ LENGTH OV: 3. IT CONTAYNZ: 12345 AN &"<>. LETS PAS TEH BAD TEXT THRU: &"<>.', + '{{ complex.tokens }} were successfully translated with appropriate prefixes.' + ); + + // Ensure debug output does not print. + $this->checkForDebugMarkup(FALSE); + } + + /** + * Test Twig "trans" debug markup. + */ + public function testTwigTransDebug() { + // Enable twig debug and write to the test settings.php file. + $this->settingsSet('twig_debug', TRUE); + $settings['settings']['twig_debug'] = (object) array( + 'value' => TRUE, + 'required' => TRUE, + ); + $this->writeSettings($settings); + + // Get page for assertion testing. + $this->drupalGet('twig-theme-test/trans', array('language' => language_load('xx'))); + + // Ensure debug output is printed. + $this->checkForDebugMarkup(TRUE); + } + + /** + * Helper function: test twig debug translation markup. + * + * @param bool $visible + * Toggle determining which assertion to use for test. + */ + protected function checkForDebugMarkup($visible) { + $tests = array( + '{% trans %} with {% plural %}' => '', + '{{ token }}' => '', + '{{ token|passthrough }}' => '', + '{{ token|placeholder }}' => '', + '{{ complex.tokens }}' => '', + ); + foreach ($tests as $test => $markup) { + if ($visible) { + $this->assertRaw($markup, "Twig debug translation markup exists in source for: $test"); + } + else { + $this->assertNoRaw($markup, "Twig debug translation markup does not exist in source for: $test"); + } + } + } + + /** + * Helper function: import a standalone .po file in a given language. + * + * Borrowed from \Drupal\locale\Tests\LocaleImportFunctionalTest. + * + * @param string $contents + * Contents of the .po file to import. + * @param array $options + * Additional options to pass to the translation import form. + */ + protected function importPoFile($contents, array $options = array()) { + $name = tempnam('temporary://', "po_") . '.po'; + file_put_contents($name, $contents); + $options['files[file]'] = $name; + $this->drupalPost('admin/config/regional/translate/import', $options, t('Import')); + drupal_unlink($name); + } + + /** + * An example .po file. + * + * @return string + * The .po contents used for this test. + */ + protected function examplePoFile() { + return <<< EOF +msgid "" +msgstr "" +"Project-Id-Version: Drupal 8\\n" +"MIME-Version: 1.0\\n" +"Content-Type: text/plain; charset=UTF-8\\n" +"Content-Transfer-Encoding: 8bit\\n" +"Plural-Forms: nplurals=2; plural=(n > 1);\\n" + +msgid "Hello sun." +msgstr "OH HAI SUNZ" + +msgid "Hello moon." +msgstr "OH HAI TEH MUUN" + +msgid "Hello star." +msgid_plural "Hello @count stars." +msgstr[0] "O HAI STARRRRR" +msgstr[1] "O HAI @count STARZZZZ" + +msgid "Escaped: @string" +msgstr "ESCAPEE: @string" + +msgid "Pass-through: !string" +msgstr "PAS-THRU: !string" + +msgid "Placeholder: %string" +msgstr "PLAYSHOLDR: %string" + +msgid "This @name has a length of: @count. It contains: %numbers and @bad_text. Lets pass the bad text through: !bad_text." +msgstr "DIS @name HAZ LENGTH OV: @count. IT CONTAYNZ: %numbers AN @bad_text. LETS PAS TEH BAD TEXT THRU: !bad_text." +EOF; + } + +} diff --git a/core/modules/system/tests/modules/twig_theme_test/lib/Drupal/twig_theme_test/TwigThemeTestController.php b/core/modules/system/tests/modules/twig_theme_test/lib/Drupal/twig_theme_test/TwigThemeTestController.php index ef5fb70..6eb318a 100644 --- a/core/modules/system/tests/modules/twig_theme_test/lib/Drupal/twig_theme_test/TwigThemeTestController.php +++ b/core/modules/system/tests/modules/twig_theme_test/lib/Drupal/twig_theme_test/TwigThemeTestController.php @@ -29,4 +29,13 @@ public function phpVariablesRender() { return theme('twig_theme_test_php_variables'); } + /** + * Menu callback for testing translation blocks in a Twig template. + */ + public function transBlockRender() { + return array( + '#theme' => 'twig_theme_test_trans', + ); + } + } diff --git a/core/modules/system/tests/modules/twig_theme_test/templates/twig_theme_test.trans.html.twig b/core/modules/system/tests/modules/twig_theme_test/templates/twig_theme_test.trans.html.twig new file mode 100644 index 0000000..bf2200b --- /dev/null +++ b/core/modules/system/tests/modules/twig_theme_test/templates/twig_theme_test.trans.html.twig @@ -0,0 +1,53 @@ +{# Output for the Twig trans block test. #} +
+ {% trans "Hello sun." %} +
+ +
+ {% trans %} + Hello moon. + {% endtrans %} +
+ +
+ {% set count = 1 %} + {% trans %} + Hello star. + {% plural count %} + Hello {{ count }} stars. + {% endtrans %} +
+ +
+ {% set count = 2 %} + {% trans %} + Hello star. + {% plural count %} + Hello {{ count }} stars. + {% endtrans %} +
+ +{% set string = '&"<>' %} +
+ {% trans %} + Escaped: {{ string }} + {% endtrans %} +
+
+ {% trans %} + Pass-through: {{ string|passthrough }} + {% endtrans %} +
+
+ {% trans %} + Placeholder: {{ string|placeholder }} + {% endtrans %} +
+ +{% set token = {'name': 'complex token', 'numbers': '12345', 'bad_text': '&"<>' } %} +{% set count = token|length %} +
+ {% trans %} + This {{ token.name }} has a length of: {{ count }}. It contains: {{ token.numbers|placeholder }} and {{ token.bad_text }}. Lets pass the bad text through: {{ token.bad_text|passthrough }}. + {% endtrans %} +
diff --git a/core/modules/system/tests/modules/twig_theme_test/twig_theme_test.module b/core/modules/system/tests/modules/twig_theme_test/twig_theme_test.module index 2ca2cd0..934d1b0 100644 --- a/core/modules/system/tests/modules/twig_theme_test/twig_theme_test.module +++ b/core/modules/system/tests/modules/twig_theme_test/twig_theme_test.module @@ -7,6 +7,10 @@ function twig_theme_test_theme($existing, $type, $theme, $path) { $items['twig_theme_test_php_variables'] = array( 'template' => 'twig_theme_test.php_variables', ); + $items['twig_theme_test_trans'] = array( + 'variables' => array(), + 'template' => 'twig_theme_test.trans', + ); return $items; } diff --git a/core/modules/system/tests/modules/twig_theme_test/twig_theme_test.routing.yml b/core/modules/system/tests/modules/twig_theme_test/twig_theme_test.routing.yml index cdc0ac1..17ac5b0 100644 --- a/core/modules/system/tests/modules/twig_theme_test/twig_theme_test.routing.yml +++ b/core/modules/system/tests/modules/twig_theme_test/twig_theme_test.routing.yml @@ -4,3 +4,9 @@ twig_theme_test_php_variables: _content: '\Drupal\twig_theme_test\TwigThemeTestController::phpVariablesRender' requirements: _permission: 'access content' +twig_theme_test_trans: + pattern: '/twig-theme-test/trans' + defaults: + _content: '\Drupal\twig_theme_test\TwigThemeTestController::transBlockRender' + requirements: + _permission: 'access content' -- 1.8.2