diff --git a/core/lib/Drupal/Core/Template/TwigExtension.php b/core/lib/Drupal/Core/Template/TwigExtension.php index 52291c3..e0cd126 100644 --- a/core/lib/Drupal/Core/Template/TwigExtension.php +++ b/core/lib/Drupal/Core/Template/TwigExtension.php @@ -541,14 +541,14 @@ public function renderVar($arg) { * This value is expected to be safe for output and user provided data * should never be used as a glue. * - * @return string - * The strings joined together. + * @return TwigMarkup + * The created imploded string, which is now markup. */ public function safeJoin(\Twig_Environment $env, $value, $glue = '') { - return implode($glue, array_map(function($item) use ($env) { + return new TwigMarkup(implode($glue, array_map(function($item) use ($env) { // If $item is not marked safe then it will be escaped. return $this->escapeFilter($env, $item, 'html', NULL, TRUE); - }, $value)); + }, $value)), $env->getCharset()); } } diff --git a/core/lib/Drupal/Core/Template/TwigMarkup.php b/core/lib/Drupal/Core/Template/TwigMarkup.php new file mode 100644 index 0000000..d642183 --- /dev/null +++ b/core/lib/Drupal/Core/Template/TwigMarkup.php @@ -0,0 +1,36 @@ +__toString(); + } + +} diff --git a/core/modules/system/system.admin.inc b/core/modules/system/system.admin.inc index efa1f5c..ba725bf 100644 --- a/core/modules/system/system.admin.inc +++ b/core/modules/system/system.admin.inc @@ -211,8 +211,7 @@ function template_preprocess_system_modules_details(&$variables) { $module['id'] = $id; $module['enable_id'] = $module['enable']['#id']; - // @todo Remove early rendering and use safe_join in the Twig template once - // https://www.drupal.org/node/2579091 is fixed. + // @todo Remove early rendering. $renderer = \Drupal::service('renderer'); $machine_name_render = [ '#prefix' => '', @@ -222,20 +221,10 @@ function template_preprocess_system_modules_details(&$variables) { $module['machine_name'] = $renderer->render($machine_name_render); if (!empty($module['#requires'])) { - $requires = [ - '#theme' => 'item_list', - '#items' => $module['#requires'], - '#context' => ['list_style' => 'comma-list'], - ]; - $module['requires'] = $renderer->render($requires); + $module['requires'] = $module['#requires']; } if (!empty($module['#required_by'])) { - $required_by = [ - '#theme' => 'item_list', - '#items' => $module['#required_by'], - '#context' => ['list_style' => 'comma-list'], - ]; - $module['required_by'] = $renderer->render($required_by); + $module['required_by'] = $module['#required_by']; } if (!empty($module['version'])) { diff --git a/core/modules/system/templates/system-modules-details.html.twig b/core/modules/system/templates/system-modules-details.html.twig index e431c8e..5ad7812 100644 --- a/core/modules/system/templates/system-modules-details.html.twig +++ b/core/modules/system/templates/system-modules-details.html.twig @@ -53,10 +53,10 @@
{{ 'Version: @module-version'|t({'@module-version': module.version }) }}
{% endif %} {% if module.requires %} -
{{ 'Requires: @module-list'|t({'@module-list': module.requires }) }}
+
{{ 'Requires: @module-list'|t({'@module-list': module.requires|safe_join(', ') }) }}
{% endif %} {% if module.required_by %} -
{{ 'Required by: @module-list'|t({'@module-list': module.required_by }) }}
+
{{ 'Required by: @module-list'|t({'@module-list': module.required_by|safe_join(', ') }) }}
{% endif %} {% if module.links %} diff --git a/core/tests/Drupal/Tests/Core/Template/TwigExtensionTest.php b/core/tests/Drupal/Tests/Core/Template/TwigExtensionTest.php index 6b9525e..f20607d 100644 --- a/core/tests/Drupal/Tests/Core/Template/TwigExtensionTest.php +++ b/core/tests/Drupal/Tests/Core/Template/TwigExtensionTest.php @@ -7,6 +7,7 @@ namespace Drupal\Tests\Core\Template; +use Drupal\Component\Render\FormattableMarkup; use Drupal\Core\Render\RenderableInterface; use Drupal\Core\Render\RendererInterface; use Drupal\Core\StringTranslation\TranslatableMarkup; @@ -200,6 +201,11 @@ public function testSafeJoin() { ]; $result = $twig_extension->safeJoin($twig_environment, $items, '
'); $this->assertEquals('<em>will be escaped</em>
will be markup
will be rendered', $result); + + // Ensure that result of safe join can be used in t() and string formatting + // without double escaping. + $result = new FormattableMarkup('Kittens @text', ['@text' => $result]); + $this->assertEquals('Kittens <em>will be escaped</em>
will be markup
will be rendered', $result); } /**