Unverified Commit 0ac4b763 authored by Lauri Timmanee's avatar Lauri Timmanee
Browse files

Issue #3343198 by andy-blum, murilohp, smustgrave, safetypin: Improve...

Issue #3343198 by andy-blum, murilohp, smustgrave, safetypin: Improve documentation of hook_theme_suggestions_HOOK_alter()
parent 22a39eb4
Loading
Loading
Loading
Loading
+19 −1
Original line number Diff line number Diff line
@@ -645,6 +645,8 @@ function hook_theme_suggestions_HOOK(array $variables) {
 * hook_theme_suggestions_HOOK_alter(). So, for each module or theme, the more
 * general hooks are called first followed by the more specific.
 *
 * New suggestions must begin with the value of HOOK, followed by two underscores to be discoverable.
 *
 * In the following example, we provide an alternative template suggestion to
 * node and taxonomy term templates based on the user being logged in.
 * @code
@@ -690,11 +692,27 @@ function hook_theme_suggestions_alter(array &$suggestions, array $variables, $ho
 * hook called (in this case 'node__article') is available in
 * $variables['theme_hook_original'].
 *
 * New suggestions must begin with the value of HOOK, followed by two underscores to be discoverable.
 * For example, consider the below suggestions from hook_theme_suggestions_node_alter:
 *   - node__article is valid
 *   - node__article__custom_template is valid
 *   - node--article is invalid
 *   - article__custom_template is invalid
 *
 * Implementations of this hook must be placed in *.module or *.theme files, or
 * must otherwise make sure that the hook implementation is available at
 * any given time.
 *
 * @todo Add @code sample.
 * In the following example, we provide an alternative template suggestion to
 * node templates based on the user being logged in.
 * @code
 * function MYMODULE_theme_suggestions_node_alter(array &$suggestions, array $variables) {
 *   if (\Drupal::currentUser()->isAuthenticated()) {
 *     $suggestions[] = 'node__logged_in';
 *   }
 * }
 *
 * @endcode
 *
 * @param array $suggestions
 *   An array of theme suggestions.
+1 −0
Original line number Diff line number Diff line
@@ -55,6 +55,7 @@ public function testTwigDebugMarkup() {
    $this->assertStringContainsString("THEME HOOK: 'node'", $output, 'Theme call information found.');
    $this->assertStringContainsString('* node--1--full' . $extension . PHP_EOL . '   x node--1' . $extension . PHP_EOL . '   * node--page--full' . $extension . PHP_EOL . '   * node--page' . $extension . PHP_EOL . '   * node--full' . $extension . PHP_EOL . '   * node' . $extension, $output, 'Suggested template files found in order and node ID specific template shown as current template.');
    $this->assertStringContainsString(Html::escape('node--<script type="text/javascript">alert(\'yo\');</script>'), (string) $output);
    $this->assertStringContainsString('<!-- INVALID FILE NAME SUGGESTIONS:' . PHP_EOL . '   See https://api.drupal.org/api/drupal/core!lib!Drupal!Core!Render!theme.api.php/function/hook_theme_suggestions_alter' . PHP_EOL . '   invalid_theme_suggestions' . PHP_EOL . '-->', $output, 'Twig debug markup found invalid suggestions.');
    $template_filename = $templates['node__1']['path'] . '/' . $templates['node__1']['template'] . $extension;
    $this->assertStringContainsString("BEGIN OUTPUT from '$template_filename'", $output, 'Full path to current template file found.');

+9 −0
Original line number Diff line number Diff line
@@ -68,6 +68,15 @@ function test_theme_theme_suggestions_theme_test_suggestions_alter(array &$sugge
  array_unshift($suggestions, 'theme_test_suggestions__' . 'theme_override');
}

/**
 * Implements hook_theme_suggestions_HOOK_alter().
 */
function test_theme_theme_suggestions_node_alter(array &$suggestions, array $variables) {
  // Add an invalid suggestion to be tested.
  $suggestions[] = 'invalid_theme_suggestions';
  \Drupal::messenger()->addStatus(__FUNCTION__ . '() executed.');
}

/**
 * Implements hook_theme_registry_alter().
 */
+16 −1
Original line number Diff line number Diff line
@@ -93,12 +93,27 @@ function twig_render_template($template_file, array $variables) {
      if (strpos($variables['theme_hook_original'], '__') === FALSE) {
        $suggestions[] = $variables['theme_hook_original'];
      }
      foreach ($suggestions as &$suggestion) {
      $invalid_suggestions = [];
      $base_hook = $base_hook ?? $variables['theme_hook_original'];
      foreach ($suggestions as $key => &$suggestion) {
        // Valid suggestions are $base_hook, $base_hook__*, and contain no hyphens.
        if (($suggestion !== $base_hook && !str_starts_with($suggestion, $base_hook . '__')) || str_contains($suggestion, '-')) {
          $invalid_suggestions[] = $suggestion;
          unset($suggestions[$key]);
          continue;
        }
        $template = strtr($suggestion, '_', '-') . $extension;
        $prefix = ($template == $current_template) ? 'x' : '*';
        $suggestion = $prefix . ' ' . $template;
      }
      $output['debug_info'] .= "\n<!-- FILE NAME SUGGESTIONS:\n   " . Html::escape(implode("\n   ", $suggestions)) . "\n-->";

      if (!empty($invalid_suggestions)) {
        $output['debug_info'] .= "\n<!-- INVALID FILE NAME SUGGESTIONS:";
        $output['debug_info'] .= "\n   See https://api.drupal.org/api/drupal/core!lib!Drupal!Core!Render!theme.api.php/function/hook_theme_suggestions_alter";
        $output['debug_info'] .= "\n   " . Html::escape(implode("\n   ", $invalid_suggestions));
        $output['debug_info'] .= "\n-->";
      }
    }
    $output['debug_info']   .= "\n<!-- BEGIN OUTPUT from '" . Html::escape($template_file) . "' -->\n";
    $output['debug_suffix'] .= "\n<!-- END OUTPUT from '" . Html::escape($template_file) . "' -->\n\n";