* 0.9.9
+Backward incompatibilities:
+ * the self special variable has been renamed to _self
+
+ * added the special _context variable to reference the current context
+ * renamed self to _self (to avoid conflict)
* fixed Twig_Template::getAttribute() for protected properties
* 0.9.8 (2010-06-28)
> [twig]
> foo[bar]
+Twig always references two special variables (mostly useful for macros):
+
+ * `_self`: references the current template;
+ * `_context`: references the current context.
+
Filters
-------
But as PHP functions, macros don't have access to the current template
variables.
+>**TIP**
+>You can pass the whole context as an argument by using the special `_context`
+>variable.
+
Macros can be defined in any template, and need to be "imported" before being
used (see the Import section for more information):
<p>{{ forms.input('password', none, 'password') }}</p>
If the macros are defined and used in the same template, you can use the
-special `self` variable, without importing them:
+special `_self` variable, without importing them:
[twig]
- <p>{{ self.input('username') }}</p>
+ <p>{{ _self.input('username') }}</p>
-When you want to use a macro in another one from the same file, use the `self`
+When you want to use a macro in another one from the same file, use the `_self`
variable:
[twig]
{% macro wrapped_input(name, value, type, size) %}
<div class="field">
- {{ self.input(name, value, type, size) }}
+ {{ _self.input(name, value, type, size) }}
</div>
{% endmacro %}
<p>{{ forms.textarea('comment') }}</p>
Importing is not needed if the macros and the template are defined in the file;
-use the special `self` variable instead:
+use the special `_self` variable instead:
[twig]
{# index.html template #}
<textarea name="{{ name }}" rows="{{ rows|default(10) }}" cols="{{ cols|default(40) }}">{{ value|e }}</textarea>
{% endmacro %}
- <p>{{ self.textarea('comment') }}</p>
+ <p>{{ _self.textarea('comment') }}</p>
-But you can still create an alias by importing from the `self` variable:
+But you can still create an alias by importing from the `_self` variable:
[twig]
{# index.html template #}
<textarea name="{{ name }}" rows="{{ rows|default(10) }}" cols="{{ cols|default(40) }}">{{ value|e }}</textarea>
{% endmacro %}
- {% import self as forms %}
+ {% import _self as forms %}
<p>{{ forms.textarea('comment') }}</p>
public function compile($compiler)
{
- if ('self' === $this['name']) {
+ if ('_self' === $this['name']) {
$compiler->raw('$this');
+ } elseif ('_context' === $this['name']) {
+ $compiler->raw('$context');
} elseif ($compiler->getEnvironment()->isStrictVariables()) {
$compiler->raw(sprintf('$this->getContext($context, \'%s\')', $this['name'], $this['name']));
} else {
->raw(' = ')
;
- if ($this->expr instanceof Twig_Node_Expression_Name && 'self' === $this->expr['name']) {
+ if ($this->expr instanceof Twig_Node_Expression_Name && '_self' === $this->expr['name']) {
$compiler->raw("\$this");
} else {
$compiler
if (!isset($this->cache[$class])) {
$r = new ReflectionClass($class);
$this->cache[$class] = array();
- foreach ($r->getMethods(ReflectionMethod::IS_PUBLIC | ReflectionMethod::IS_FINAL) as $method) {
+ foreach ($r->getMethods(ReflectionMethod::IS_PUBLIC) as $method) {
$this->cache[$class]['methods'][strtolower($method->getName())] = true;
}
--TEST--
"macro" tag
--TEMPLATE--
-{{ self.input('username') }}
-{{ self.input('password', null, 'password', 1) }}
+{{ _self.input('username') }}
+{{ _self.input('password', null, 'password', 1) }}
{% macro input(name, value, type, size) %}
<input type="{{ type|default("text") }}" name="{{ name }}" value="{{ value|e|default('') }}" size="{{ size|default(20) }}">
--TEST--
"macro" tag
--TEMPLATE--
-{% import self as forms %}
+{% import _self as forms %}
{{ forms.input('username') }}
{{ forms.input('password', null, 'password', 1) }}
public function getTests()
{
$node = new Twig_Node_Expression_Name('foo', 0);
+ $self = new Twig_Node_Expression_Name('_self', 0);
+ $context = new Twig_Node_Expression_Name('_context', 0);
$env = new Twig_Environment(null, array('strict_variables' => true));
return array(
array($node, '$this->getContext($context, \'foo\')', $env),
array($node, '(isset($context[\'foo\']) ? $context[\'foo\'] : null)'),
+ array($self, '$this'),
+ array($context, '$context'),
);
}
}
$output = trim($template->render(eval($match[1].';')), "\n ");
$expected = trim($match[2], "\n ");
- $this->assertEquals($expected, $output, $message.' (in '.$file.')');
- if ($output != $expected) {
+ if ($expected != $output) {
echo 'Compiled template that failed:';
foreach (array_keys($templates) as $name) {
+ echo "Template: $name\n";
$source = $loader->getSource($name);
echo $twig->compile($twig->parse($twig->tokenize($source, $name)));
}
}
+ $this->assertEquals($expected, $output, $message.' (in '.$file.')');
}
}
}