Mercurial > hg > isophonics-drupal-site
comparison core/lib/Drupal/Core/Template/TwigNodeTrans.php @ 0:4c8ae668cc8c
Initial import (non-working)
author | Chris Cannam |
---|---|
date | Wed, 29 Nov 2017 16:09:58 +0000 |
parents | |
children | 1fec387a4317 |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:4c8ae668cc8c |
---|---|
1 <?php | |
2 | |
3 namespace Drupal\Core\Template; | |
4 | |
5 /** | |
6 * A class that defines the Twig 'trans' tag for Drupal. | |
7 * | |
8 * This Twig extension was originally based on Twig i18n extension. It has been | |
9 * severely modified to work properly with the complexities of the Drupal | |
10 * translation system. | |
11 * | |
12 * @see http://twig.sensiolabs.org/doc/extensions/i18n.html | |
13 * @see https://github.com/fabpot/Twig-extensions | |
14 */ | |
15 class TwigNodeTrans extends \Twig_Node { | |
16 | |
17 /** | |
18 * {@inheritdoc} | |
19 */ | |
20 public function __construct(\Twig_Node $body, \Twig_Node $plural = NULL, \Twig_Node_Expression $count = NULL, \Twig_Node_Expression $options = NULL, $lineno, $tag = NULL) { | |
21 parent::__construct([ | |
22 'count' => $count, | |
23 'body' => $body, | |
24 'plural' => $plural, | |
25 'options' => $options, | |
26 ], [], $lineno, $tag); | |
27 } | |
28 | |
29 /** | |
30 * {@inheritdoc} | |
31 */ | |
32 public function compile(\Twig_Compiler $compiler) { | |
33 $compiler->addDebugInfo($this); | |
34 | |
35 $options = $this->getNode('options'); | |
36 | |
37 list($singular, $tokens) = $this->compileString($this->getNode('body')); | |
38 $plural = NULL; | |
39 | |
40 if (NULL !== $this->getNode('plural')) { | |
41 list($plural, $pluralTokens) = $this->compileString($this->getNode('plural')); | |
42 $tokens = array_merge($tokens, $pluralTokens); | |
43 } | |
44 | |
45 // Start writing with the function to be called. | |
46 $compiler->write('echo ' . (empty($plural) ? 't' : '\Drupal::translation()->formatPlural') . '('); | |
47 | |
48 // Move the count to the beginning of the parameters list. | |
49 if (!empty($plural)) { | |
50 $compiler->raw('abs(')->subcompile($this->getNode('count'))->raw('), '); | |
51 } | |
52 | |
53 // Write the singular text parameter. | |
54 $compiler->subcompile($singular); | |
55 | |
56 // Write the plural text parameter, if necessary. | |
57 if (!empty($plural)) { | |
58 $compiler->raw(', ')->subcompile($plural); | |
59 } | |
60 | |
61 // Write any tokens found as an associative array parameter, otherwise just | |
62 // leave as an empty array. | |
63 $compiler->raw(', array('); | |
64 foreach ($tokens as $token) { | |
65 $compiler->string($token->getAttribute('placeholder'))->raw(' => ')->subcompile($token)->raw(', '); | |
66 } | |
67 $compiler->raw(')'); | |
68 | |
69 // Write any options passed. | |
70 if (!empty($options)) { | |
71 $compiler->raw(', ')->subcompile($options); | |
72 } | |
73 | |
74 // Write function closure. | |
75 $compiler->raw(')'); | |
76 | |
77 // @todo Add debug output, see https://www.drupal.org/node/2512672 | |
78 | |
79 // End writing. | |
80 $compiler->raw(";\n"); | |
81 } | |
82 | |
83 /** | |
84 * Extracts the text and tokens for the "trans" tag. | |
85 * | |
86 * @param \Twig_Node $body | |
87 * The node to compile. | |
88 * | |
89 * @return array | |
90 * Returns an array containing the two following parameters: | |
91 * - string $text | |
92 * The extracted text. | |
93 * - array $tokens | |
94 * The extracted tokens as new \Twig_Node_Expression_Name instances. | |
95 */ | |
96 protected function compileString(\Twig_Node $body) { | |
97 if ($body instanceof \Twig_Node_Expression_Name || $body instanceof \Twig_Node_Expression_Constant || $body instanceof \Twig_Node_Expression_TempName) { | |
98 return [$body, []]; | |
99 } | |
100 | |
101 $tokens = []; | |
102 if (count($body)) { | |
103 $text = ''; | |
104 | |
105 foreach ($body as $node) { | |
106 if (get_class($node) === 'Twig_Node' && $node->getNode(0) instanceof \Twig_Node_SetTemp) { | |
107 $node = $node->getNode(1); | |
108 } | |
109 | |
110 if ($node instanceof \Twig_Node_Print) { | |
111 $n = $node->getNode('expr'); | |
112 while ($n instanceof \Twig_Node_Expression_Filter) { | |
113 $n = $n->getNode('node'); | |
114 } | |
115 | |
116 $args = $n; | |
117 | |
118 // Support TwigExtension->renderVar() function in chain. | |
119 if ($args instanceof \Twig_Node_Expression_Function) { | |
120 $args = $n->getNode('arguments')->getNode(0); | |
121 } | |
122 | |
123 // Detect if a token implements one of the filters reserved for | |
124 // modifying the prefix of a token. The default prefix used for | |
125 // translations is "@". This escapes the printed token and makes them | |
126 // safe for templates. | |
127 // @see TwigExtension::getFilters() | |
128 $argPrefix = '@'; | |
129 while ($args instanceof \Twig_Node_Expression_Filter) { | |
130 switch ($args->getNode('filter')->getAttribute('value')) { | |
131 case 'placeholder': | |
132 $argPrefix = '%'; | |
133 break; | |
134 } | |
135 $args = $args->getNode('node'); | |
136 } | |
137 if ($args instanceof \Twig_Node_Expression_GetAttr) { | |
138 $argName = []; | |
139 // Reuse the incoming expression. | |
140 $expr = $args; | |
141 // Assemble a valid argument name by walking through the expression. | |
142 $argName[] = $args->getNode('attribute')->getAttribute('value'); | |
143 while ($args->hasNode('node')) { | |
144 $args = $args->getNode('node'); | |
145 if ($args instanceof \Twig_Node_Expression_Name) { | |
146 $argName[] = $args->getAttribute('name'); | |
147 } | |
148 else { | |
149 $argName[] = $args->getNode('attribute')->getAttribute('value'); | |
150 } | |
151 } | |
152 $argName = array_reverse($argName); | |
153 $argName = implode('.', $argName); | |
154 } | |
155 else { | |
156 $argName = $n->getAttribute('name'); | |
157 if (!is_null($args)) { | |
158 $argName = $args->getAttribute('name'); | |
159 } | |
160 $expr = new \Twig_Node_Expression_Name($argName, $n->getLine()); | |
161 } | |
162 $placeholder = sprintf('%s%s', $argPrefix, $argName); | |
163 $text .= $placeholder; | |
164 $expr->setAttribute('placeholder', $placeholder); | |
165 $tokens[] = $expr; | |
166 } | |
167 else { | |
168 $text .= $node->getAttribute('data'); | |
169 } | |
170 } | |
171 } | |
172 elseif (!$body->hasAttribute('data')) { | |
173 throw new \Twig_Error_Syntax('{% trans %} tag cannot be empty'); | |
174 } | |
175 else { | |
176 $text = $body->getAttribute('data'); | |
177 } | |
178 | |
179 return [new \Twig_Node([new \Twig_Node_Expression_Constant(trim($text), $body->getLine())]), $tokens]; | |
180 } | |
181 | |
182 } |