Verified Commit 6425af26 authored by Alex Pott's avatar Alex Pott
Browse files

Issue #3306864 by lauriii, mherchel, alexpott: Integrate Twig with Symfony...

Issue #3306864 by lauriii, mherchel, alexpott: Integrate Twig with Symfony VarDumper for improved debugging experience

(cherry picked from commit 07994b06)
parent bd29f2e0
Loading
Loading
Loading
Loading
+9 −3
Original line number Diff line number Diff line
@@ -1668,12 +1668,18 @@ services:
    arguments: ['@renderer', '@url_generator', '@theme.manager', '@date.formatter', '@file_url_generator']
    tags:
      - { name: twig.extension, priority: 100 }
  # @todo Figure out what to do about debugging functions.
  # @see https://www.drupal.org/node/1804998
  twig.extension.debug:
    class: Twig\Extension\DebugExtension
    tags:
      - { name: twig.extension }
      - { name: twig.extension, priority: 50 }
  twig.extension.varDumper:
    class: Drupal\Core\Template\DebugExtension
    tags:
      # This extension is loaded after the Twig Debug Extension because for Twig
      # Extensions, last extension loaded takes precedent. This allows this
      # extension to override the default Twig Debug Extension conditionally
      # when Symfony VarDumper is available.
      - { name: twig.extension, priority: 25 }
  twig.loader:
    class: Twig\Loader\ChainLoader
    public: false
+68 −0
Original line number Diff line number Diff line
<?php

namespace Drupal\Core\Template;

use Twig\Environment;
use Twig\Extension\AbstractExtension;
use Twig\TwigFunction;

/**
 * A class providing Drupal Twig Debug extension.
 */
final class DebugExtension extends AbstractExtension {

  /**
   * The Symfony VarDumper class.
   *
   * Defined as a string because the Symfony VarDumper does not always exist.
   *
   * @type string
   */
  private const SYMFONY_VAR_DUMPER_CLASS = '\Symfony\Component\VarDumper\VarDumper';

  /**
   * {@inheritdoc}
   */
  public function getFunctions(): array {
    // Override Twig built in debugger when Symfony VarDumper is available to
    // improve developer experience.
    // @see \Twig\Extension\DebugExtension
    // @see \Symfony\Component\VarDumper\VarDumper
    if (class_exists(self::SYMFONY_VAR_DUMPER_CLASS)) {
      return [
        new TwigFunction('dump', [self::class, 'dump'], ['needs_context' => TRUE, 'needs_environment' => TRUE, 'is_variadic' => TRUE]),
      ];
    }

    return [];
  }

  /**
   * Dumps information about variables using Symfony VarDumper.
   *
   * @param \Twig\Environment $env
   *   The Twig environment.
   * @param array $context
   *   Variables from the Twig template.
   * @param array $variables
   *   (optional) Variable(s) to dump.
   */
  public static function dump(Environment $env, array $context, ...$variables): void {
    if (!$env->isDebug()) {
      return;
    }

    if (class_exists(self::SYMFONY_VAR_DUMPER_CLASS)) {
      if (func_num_args() === 2) {
        call_user_func(self::SYMFONY_VAR_DUMPER_CLASS . '::dump', $context);
      }
      else {
        array_walk($variables, self::SYMFONY_VAR_DUMPER_CLASS . '::dump');
      }
    }
    else {
      throw new \LogicException('Could not dump the variable because symfony/var-dumper component is not installed.');
    }
  }

}
+7 −0
Original line number Diff line number Diff line
@@ -111,4 +111,11 @@ public function embedTagRender() {
    return ['#theme' => 'twig_theme_test_embed_tag'];
  }

  /**
   * Renders for testing drupal_dump function.
   */
  public function dump() {
    return ['#theme' => 'twig_theme_test_dump'];
  }

}
+6 −0
Original line number Diff line number Diff line
{% set foo = '💩' %}
{% set bar = '🐣' %}
{% set baz = '☄️' %}
{{ dump(foo) }}
{{ dump() }}
{{ dump(foo, baz) }}
+4 −0
Original line number Diff line number Diff line
@@ -77,6 +77,10 @@ function twig_theme_test_theme($existing, $type, $theme, $path) {
    'variables' => [],
    'template' => 'twig_theme_test.embed_tag',
  ];
  $items['twig_theme_test_dump'] = [
    'variables' => [],
    'template' => 'twig_theme_test.dump',
  ];
  return $items;
}

Loading