TwigNodeVisitor.php 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. <?php
  2. namespace Drupal\Core\Template;
  3. /**
  4. * Provides a Twig_NodeVisitor to change the generated parse-tree.
  5. *
  6. * This is used to ensure that everything printed is wrapped via the
  7. * TwigExtension->renderVar() function in order to just write {{ content }}
  8. * in templates instead of having to write {{ render_var(content) }}.
  9. *
  10. * @see twig_render
  11. */
  12. class TwigNodeVisitor extends \Twig_BaseNodeVisitor {
  13. /**
  14. * {@inheritdoc}
  15. */
  16. protected function doEnterNode(\Twig_Node $node, \Twig_Environment $env) {
  17. return $node;
  18. }
  19. /**
  20. * {@inheritdoc}
  21. */
  22. protected function doLeaveNode(\Twig_Node $node, \Twig_Environment $env) {
  23. // We use this to inject a call to render_var -> TwigExtension->renderVar()
  24. // before anything is printed.
  25. if ($node instanceof \Twig_Node_Print) {
  26. if (!empty($this->skipRenderVarFunction)) {
  27. // No need to add the callback, we have escape active already.
  28. unset($this->skipRenderVarFunction);
  29. return $node;
  30. }
  31. $class = get_class($node);
  32. $line = $node->getTemplateLine();
  33. return new $class(
  34. new \Twig_Node_Expression_Function('render_var', new \Twig_Node([$node->getNode('expr')]), $line),
  35. $line
  36. );
  37. }
  38. // Change the 'escape' filter to our own 'drupal_escape' filter.
  39. elseif ($node instanceof \Twig_Node_Expression_Filter) {
  40. $name = $node->getNode('filter')->getAttribute('value');
  41. if ('escape' == $name || 'e' == $name) {
  42. // Use our own escape filter that is MarkupInterface aware.
  43. $node->getNode('filter')->setAttribute('value', 'drupal_escape');
  44. // Store that we have a filter active already that knows
  45. // how to deal with render arrays.
  46. $this->skipRenderVarFunction = TRUE;
  47. }
  48. }
  49. return $node;
  50. }
  51. /**
  52. * {@inheritdoc}
  53. */
  54. public function getPriority() {
  55. // Just above the Optimizer, which is the normal last one.
  56. return 256;
  57. }
  58. }