2012-11-03 17:36:10 +00:00
|
|
|
<?php
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @file
|
|
|
|
* Handles integration of Twig templates with the Drupal theme system.
|
|
|
|
*/
|
|
|
|
|
2015-08-17 07:34:08 +00:00
|
|
|
use Drupal\Component\Utility\Html;
|
2015-10-01 23:25:03 +00:00
|
|
|
use Drupal\Core\Render\Markup;
|
Issue #3041076 by alexpott, shaal, Gábor Hojtsy, lauriii, Wim Leers, catch, Cottser, jibran, andypost, znerol, xim, joelpittet, effulgentsia: Update Drupal 9 to Twig 2
2019-10-31 12:39:18 +00:00
|
|
|
use Twig\Error\RuntimeError;
|
2014-03-11 17:19:24 +00:00
|
|
|
|
2012-11-03 17:36:10 +00:00
|
|
|
/**
|
|
|
|
* Implements hook_theme().
|
|
|
|
*/
|
|
|
|
function twig_theme($existing, $type, $theme, $path) {
|
2022-02-07 09:44:22 +00:00
|
|
|
return drupal_find_theme_templates($existing, '.html.twig', $path);
|
2012-11-03 17:36:10 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Implements hook_extension().
|
|
|
|
*/
|
|
|
|
function twig_extension() {
|
2013-01-30 03:11:25 +00:00
|
|
|
return '.html.twig';
|
2012-11-03 17:36:10 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2014-10-04 13:15:51 +00:00
|
|
|
* Implements hook_render_template().
|
2012-11-03 17:36:10 +00:00
|
|
|
*/
|
2015-02-05 09:24:24 +00:00
|
|
|
function twig_render_template($template_file, array $variables) {
|
Issue #3041076 by alexpott, shaal, Gábor Hojtsy, lauriii, Wim Leers, catch, Cottser, jibran, andypost, znerol, xim, joelpittet, effulgentsia: Update Drupal 9 to Twig 2
2019-10-31 12:39:18 +00:00
|
|
|
/** @var \Twig\Environment $twig_service */
|
2014-03-27 05:31:37 +00:00
|
|
|
$twig_service = \Drupal::service('twig');
|
2015-03-01 13:02:11 +00:00
|
|
|
$output = [
|
|
|
|
'debug_prefix' => '',
|
|
|
|
'debug_info' => '',
|
|
|
|
'rendered_markup' => '',
|
|
|
|
'debug_suffix' => '',
|
|
|
|
];
|
Issue #2226207 by lauriii, mgbellaire, Cottser, m1r1k, Mark Carver, LinL, rachel_norfolk, rteijeiro, skwashd, davidhernandez, euphoric_mv: Make 'template' the default output option for hook_theme().
2014-10-08 11:06:17 +00:00
|
|
|
try {
|
Issue #3094493 by longwave, Gábor Hojtsy, alexpott, naveen433, Chi, catch, andypost, Krzysztof Domański, shaal, xjm, fgm, Luke.Leber, daffie, Berdir, Fabianx, effulgentsia: Upgrade to Twig 3
2022-01-05 11:17:42 +00:00
|
|
|
$output['rendered_markup'] = $twig_service->load($template_file)->render($variables);
|
Issue #2226207 by lauriii, mgbellaire, Cottser, m1r1k, Mark Carver, LinL, rachel_norfolk, rteijeiro, skwashd, davidhernandez, euphoric_mv: Make 'template' the default output option for hook_theme().
2014-10-08 11:06:17 +00:00
|
|
|
}
|
Issue #3041076 by alexpott, shaal, Gábor Hojtsy, lauriii, Wim Leers, catch, Cottser, jibran, andypost, znerol, xim, joelpittet, effulgentsia: Update Drupal 9 to Twig 2
2019-10-31 12:39:18 +00:00
|
|
|
catch (RuntimeError $e) {
|
2015-06-23 16:24:29 +00:00
|
|
|
// In case there is a previous exception, re-throw the previous exception,
|
|
|
|
// so that the original exception is shown, rather than
|
Issue #3041076 by alexpott, shaal, Gábor Hojtsy, lauriii, Wim Leers, catch, Cottser, jibran, andypost, znerol, xim, joelpittet, effulgentsia: Update Drupal 9 to Twig 2
2019-10-31 12:39:18 +00:00
|
|
|
// \Twig\Template::displayWithErrorHandling()'s exception.
|
2015-06-23 16:24:29 +00:00
|
|
|
$previous_exception = $e->getPrevious();
|
|
|
|
if ($previous_exception) {
|
|
|
|
throw $previous_exception;
|
|
|
|
}
|
|
|
|
throw $e;
|
|
|
|
}
|
2014-03-27 05:31:37 +00:00
|
|
|
if ($twig_service->isDebug()) {
|
2013-02-19 08:59:05 +00:00
|
|
|
$output['debug_prefix'] .= "\n\n<!-- THEME DEBUG -->";
|
2015-08-17 07:34:08 +00:00
|
|
|
$output['debug_prefix'] .= "\n<!-- THEME HOOK: '" . Html::escape($variables['theme_hook_original']) . "' -->";
|
2014-03-04 21:04:23 +00:00
|
|
|
// 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 like
|
|
|
|
// '#theme' => 'comment__node__article'.
|
2023-03-18 11:30:09 +00:00
|
|
|
if (str_contains($variables['theme_hook_original'], '__')) {
|
2014-03-04 21:04:23 +00:00
|
|
|
$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) and append it
|
|
|
|
// to the end of all 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;
|
|
|
|
}
|
2013-02-19 08:59:05 +00:00
|
|
|
if (!empty($variables['theme_hook_suggestions'])) {
|
|
|
|
$extension = twig_extension();
|
|
|
|
$current_template = basename($template_file);
|
|
|
|
$suggestions = $variables['theme_hook_suggestions'];
|
2014-03-04 21:04:23 +00:00
|
|
|
// Only add the original theme hook if it wasn't a directly called
|
|
|
|
// suggestion.
|
2023-03-18 11:30:09 +00:00
|
|
|
if (!str_contains($variables['theme_hook_original'], '__')) {
|
2014-03-04 21:04:23 +00:00
|
|
|
$suggestions[] = $variables['theme_hook_original'];
|
|
|
|
}
|
2023-03-03 08:20:46 +00:00
|
|
|
$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;
|
|
|
|
}
|
2013-02-19 08:59:05 +00:00
|
|
|
$template = strtr($suggestion, '_', '-') . $extension;
|
2024-02-29 20:25:10 +00:00
|
|
|
$prefix = ($template == $current_template) ? '✅' : '▪️';
|
2013-02-19 08:59:05 +00:00
|
|
|
$suggestion = $prefix . ' ' . $template;
|
|
|
|
}
|
2015-08-17 07:34:08 +00:00
|
|
|
$output['debug_info'] .= "\n<!-- FILE NAME SUGGESTIONS:\n " . Html::escape(implode("\n ", $suggestions)) . "\n-->";
|
2023-03-03 08:20:46 +00:00
|
|
|
|
|
|
|
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-->";
|
|
|
|
}
|
2013-02-19 08:59:05 +00:00
|
|
|
}
|
2024-02-29 20:25:10 +00:00
|
|
|
// Check if the template_file belongs to a custom theme
|
|
|
|
$template_override_status_output = "BEGIN OUTPUT";
|
|
|
|
$template_override_suffix_output = "END OUTPUT";
|
|
|
|
if (str_starts_with($template_file, $variables['directory'])) {
|
|
|
|
$template_override_status_output = "💡 BEGIN CUSTOM TEMPLATE OUTPUT";
|
|
|
|
$template_override_suffix_output = "END CUSTOM TEMPLATE OUTPUT";
|
|
|
|
}
|
|
|
|
$output['debug_info'] .= "\n<!-- " . $template_override_status_output . " from '" . Html::escape($template_file) . "' -->\n";
|
|
|
|
$output['debug_suffix'] .= "\n<!-- " . $template_override_suffix_output . " from '" . Html::escape($template_file) . "' -->\n\n";
|
2013-02-19 08:59:05 +00:00
|
|
|
}
|
2015-08-13 11:33:54 +00:00
|
|
|
// This output has already been rendered and is therefore considered safe.
|
2015-10-01 23:25:03 +00:00
|
|
|
return Markup::create(implode('', $output));
|
2012-11-03 17:36:10 +00:00
|
|
|
}
|