drupal/core/themes/engines/twig/twig.engine

158 lines
4.2 KiB
Plaintext

<?php
/**
* @file
* Handles integration of Twig templates with the Drupal theme system.
*/
use Drupal\Core\Template\TwigReference;
/**
* Implements hook_theme().
*/
function twig_theme($existing, $type, $theme, $path) {
$templates = drupal_find_theme_functions($existing, array($theme));
$templates += drupal_find_theme_templates($existing, '.html.twig', $path);
return $templates;
}
/**
* Implements hook_extension().
*/
function twig_extension() {
return '.html.twig';
}
/**
* Implements hook_init().
*/
function twig_init($template) {
$file = dirname($template->filename) . '/' . $template->name . '.theme';
if (file_exists($file)) {
include_once DRUPAL_ROOT . '/' . $file;
}
}
/**
* Renders a Twig template.
*
* If the Twig debug setting is enabled, HTML comments including theme() call
* and template file name suggestions will surround the template markup.
*
* @param $template_file
* The file name of the template to render.
* @param $variables
* A keyed array of variables that will appear in the output.
*
* @return
* The output generated by the template, plus any debug information.
*/
function twig_render_template($template_file, $variables) {
$variables['_references'] = array();
$output = array(
'debug_prefix' => '',
'debug_info' => '',
'rendered_markup' => \Drupal::service('twig')->loadTemplate($template_file)->render($variables),
'debug_suffix' => '',
);
if (settings()->get('twig_debug', FALSE)) {
$output['debug_prefix'] .= "\n\n<!-- THEME DEBUG -->";
$output['debug_prefix'] .= "\n<!-- CALL: theme('{$variables['theme_hook_original']}') -->";
if (!empty($variables['theme_hook_suggestions'])) {
$extension = twig_extension();
$current_template = basename($template_file);
$suggestions = $variables['theme_hook_suggestions'];
$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 " . implode("\n ", $suggestions) . "\n-->";
}
$output['debug_info'] .= "\n<!-- BEGIN OUTPUT from '{$template_file}' -->\n";
$output['debug_suffix'] .= "\n<!-- END OUTPUT from '{$template_file}' -->\n\n";
}
return implode('', $output);
}
/**
* Wrapper around render() for twig printed output.
*
* If an object is passed that has no __toString method an exception is thrown;
* other objects are casted to string. However in the case that the object is an
* instance of a Twig_Markup object it is returned directly to support auto
* escaping.
*
* If an array is passed it is rendered via render() and scalar values are
* returned directly.
*
* @param mixed $arg
* String, Object or Render Array
*
* @return
* The rendered output or an Twig_Markup object.
*
* @see render
* @see TwigNodeVisitor
*/
function twig_render_var($arg) {
if ($arg instanceof TwigReference) {
$arg = &$arg->getReference();
}
// Check for numeric zero.
if ($arg === 0) {
return 0;
}
// == is true also for empty arrays
if ($arg == NULL) {
return NULL;
}
// Keep Twig_Markup objects intact to prepare for later autoescaping support
if ($arg instanceOf Twig_Markup) {
return $arg;
}
if (is_scalar($arg)) {
return $arg;
}
if (is_object($arg)) {
if (method_exists($arg, '__toString')) {
return (string) $arg;
}
throw new Exception(t('Object of type "@class" cannot be printed.', array('@class' => get_class($arg))));
}
// This is a normal render array.
return render($arg);
}
/**
* Wrapper around hide() that does not return the content.
*
* @see hide
*/
function twig_hide($element) {
if ($element instanceof TwigReference) {
$element = &$element->getReference();
hide($element);
}
// @todo Add warning in else case
}
/**
* Wrapper around show() that does not return the content.
*
* @see show
*/
function twig_show($element) {
if ($element instanceof TwigReference) {
$element = &$element->getReference();
show($element);
}
// @todo Add warning in else case
}