diff --git a/core/modules/system/lib/Drupal/system/Tests/Theme/TwigDebugMarkupTest.php b/core/modules/system/lib/Drupal/system/Tests/Theme/TwigDebugMarkupTest.php index 34675f7..63ffca7 100644 --- a/core/modules/system/lib/Drupal/system/Tests/Theme/TwigDebugMarkupTest.php +++ b/core/modules/system/lib/Drupal/system/Tests/Theme/TwigDebugMarkupTest.php @@ -19,7 +19,7 @@ class TwigDebugMarkupTest extends WebTestBase { * * @var array */ - public static $modules = array('theme_test'); + public static $modules = array('theme_test', 'comment'); public static function getInfo() { return array( @@ -49,6 +49,7 @@ function testTwigDebugMarkup() { // Create array of Twig templates. $templates = drupal_find_theme_templates($cache, $extension, drupal_get_path('theme', 'test_theme')); $templates += drupal_find_theme_templates($cache, $extension, drupal_get_path('module', 'node')); + $templates += drupal_find_theme_templates($cache, $extension, drupal_get_path('module', 'comment')); // Create a node and test different features of the debug markup. $node = $this->drupalCreateNode(); @@ -67,6 +68,31 @@ function testTwigDebugMarkup() { $this->assertTrue(strpos($output, '* node--2' . $extension) !== FALSE, 'Node ID specific template suggestion found.'); $this->assertTrue(strpos($output, 'x node' . $extension) !== FALSE, 'Base template file shown as current template.'); + // Create another node, call a theme suggestion directly, and make sure the + // template suggestions shown in the debug markup are correct. + $node3 = $this->drupalCreateNode(); + // Create a comment on the node. + $comment = entity_create('comment', array( + 'cid' => NULL, + 'nid' => $node3->id(), + 'node_type' => $node3->type, + 'pid' => 0, + 'uid' => 0, + 'status' => COMMENT_PUBLISHED, + 'subject' => $this->randomName(), + 'hostname' => '127.0.0.1', + 'langcode' => 'und', + 'comment_body' => array('und' => array($this->randomName())), + )); + $comment->save(); + $output = theme('comment__node__article', comment_view($comment)); + $this->assertTrue(strpos($output, "CALL: theme('comment__node__article')") !== FALSE, 'Theme call information found.'); + $this->assertTrue(strpos($output, 'x comment' . $extension) !== FALSE, 'Comment template file shown as current template.'); + $this->assertTrue(strpos($output, '* comment--node' . $extension) !== FALSE, 'Suggested template file found.'); + $this->assertTrue(strpos($output, '* comment--node--article' . $extension) !== FALSE, 'Suggested template file found.'); + $template_filename = $templates['comment']['path'] . '/' . $templates['comment']['template'] . $extension; + $this->assertTrue(strpos($output, "BEGIN OUTPUT from '$template_filename'") !== FALSE, 'Full path to current template file found.'); + // Disable debug, rebuild the service container, and clear all caches. $this->settingsSet('twig_debug', FALSE); $this->rebuildContainer(); diff --git a/core/themes/engines/twig/twig.engine b/core/themes/engines/twig/twig.engine index b541cdc..71da266 100644 --- a/core/themes/engines/twig/twig.engine +++ b/core/themes/engines/twig/twig.engine @@ -57,11 +57,33 @@ function twig_render_template($template_file, $variables) { if (settings()->get('twig_debug', FALSE)) { $output['debug_prefix'] .= "\n\n"; $output['debug_prefix'] .= "\n"; + // If there are theme suggestions, reverse the array so more specific + // suggestions are shown first. + if (!empty($variables['theme_hook_suggestions'])) { + $variables['theme_hook_suggestions'] = array_reverse($variables['theme_hook_suggestions']); + } + // Add debug output for directly called suggestions. + if (strpos($variables['theme_hook_original'], '__') !== FALSE) { + $derived_suggestions[] = $hook = $variables['theme_hook_original']; + while ($pos = strrpos($hook, '__')) { + $hook = substr($hook, 0, $pos); + $derived_suggestions[] = $hook; + } + // Get the value of the base hook (last derived suggestion) to be appended + // to the end of the theme suggestions. + $base_hook = array_pop($derived_suggestions); + $variables['theme_hook_suggestions'] = array_merge($derived_suggestions, $variables['theme_hook_suggestions']); + $variables['theme_hook_suggestions'][] = $base_hook; + } if (!empty($variables['theme_hook_suggestions'])) { $extension = twig_extension(); $current_template = basename($template_file); $suggestions = $variables['theme_hook_suggestions']; - $suggestions[] = $variables['theme_hook_original']; + // Only add the original theme hook if it wasn't a directly called + // suggestion. + if (strpos($variables['theme_hook_original'], '__') === FALSE) { + $suggestions[] = $variables['theme_hook_original']; + } foreach ($suggestions as $key => &$suggestion) { $template = strtr($suggestion, '_', '-') . $extension; $prefix = ($template == $current_template) ? 'x' : '*';