123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152 |
- <?php
- /**
- * @file
- * Handles integration of Twig templates with the Drupal theme system.
- */
- use Drupal\Component\Utility\Html;
- use Drupal\Core\Render\Markup;
- use Drupal\Core\Extension\Extension;
- /**
- * Implements hook_theme().
- */
- function twig_theme($existing, $type, $theme, $path) {
- $templates = drupal_find_theme_functions($existing, [$theme]);
- $templates += drupal_find_theme_templates($existing, '.html.twig', $path);
- return $templates;
- }
- /**
- * Implements hook_extension().
- */
- function twig_extension() {
- return '.html.twig';
- }
- /**
- * Includes .theme file from themes.
- *
- * @param \Drupal\Core\Extension\Extension $theme
- * The theme extension object.
- */
- function twig_init(Extension $theme) {
- $theme->load();
- }
- /**
- * Implements hook_render_template().
- *
- * Renders a Twig template.
- *
- * If the Twig debug setting is enabled, HTML comments including the theme hook
- * and template file name suggestions will surround the template markup.
- *
- * @param string $template_file
- * The file name of the template to render.
- * @param array $variables
- * A keyed array of variables that will appear in the output.
- *
- * @return string|\Drupal\Component\Render\MarkupInterface
- * The output generated by the template, plus any debug information.
- */
- function twig_render_template($template_file, array $variables) {
- /** @var \Twig_Environment $twig_service */
- $twig_service = \Drupal::service('twig');
- $output = [
- 'debug_prefix' => '',
- 'debug_info' => '',
- 'rendered_markup' => '',
- 'debug_suffix' => '',
- ];
- try {
- $output['rendered_markup'] = $twig_service->loadTemplate($template_file)->render($variables);
- }
- catch (\Twig_Error_Runtime $e) {
- // In case there is a previous exception, re-throw the previous exception,
- // so that the original exception is shown, rather than
- // \Twig_Template::displayWithErrorHandling()'s exception.
- $previous_exception = $e->getPrevious();
- if ($previous_exception) {
- throw $previous_exception;
- }
- throw $e;
- }
- if ($twig_service->isDebug()) {
- $output['debug_prefix'] .= "\n\n<!-- THEME DEBUG -->";
- $output['debug_prefix'] .= "\n<!-- THEME HOOK: '" . Html::escape($variables['theme_hook_original']) . "' -->";
- // 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'.
- 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) 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;
- }
- if (!empty($variables['theme_hook_suggestions'])) {
- $extension = twig_extension();
- $current_template = basename($template_file);
- $suggestions = $variables['theme_hook_suggestions'];
- // 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 &$suggestion) {
- $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-->";
- }
- $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";
- }
- // This output has already been rendered and is therefore considered safe.
- return Markup::create(implode('', $output));
- }
- /**
- * Removes child elements from a copy of the original array.
- *
- * Creates a copy of the renderable array and removes child elements by key
- * specified through filter's arguments. The copy can be printed without these
- * elements. The original renderable array is still available and can be used
- * to print child elements in their entirety in the twig template.
- *
- * @param array|object $element
- * The parent renderable array to exclude the child items.
- * @param string[] ...
- * The string keys of $element to prevent printing.
- *
- * @return array
- * The filtered renderable array.
- */
- function twig_without($element) {
- if ($element instanceof ArrayAccess) {
- $filtered_element = clone $element;
- }
- else {
- $filtered_element = $element;
- }
- $args = func_get_args();
- unset($args[0]);
- foreach ($args as $arg) {
- if (isset($filtered_element[$arg])) {
- unset($filtered_element[$arg]);
- }
- }
- return $filtered_element;
- }
|