Currently I place my function in a class and pass an instance of this class into template and call my required function as a class method.
{{ unneededclass.blah() }}
I need to do like below
{{ blah() }}
Is it possible?
Commenters point out that I'm mostly wrong. If you really need a function, and not a filter or macro, you can do it as suggested in the Twig docs:
$twig = new Twig_Environment($loader);
$function = new Twig_SimpleFunction('blah', function () {
// ...
});
$twig->addFunction($function);
And use like
{{ blah() }}
In short, no, this is not possible.
However, hope is not lost!
If this function blah()
of yours is meant to modify an existing variable, then it is a filter.
An example:
//in your PHP
function format_date($date_string,$format_string) {
return date($format_string,strtotime($date_string));
}
$twig_env->addFilter('format_date',new Twig_Filter_Function('format_date'));
{# in your template #}
{{ some_date|format_date('n/j/Y') }}
(The first argument is the variable you are filtering, the second is supplied by normal means)
If, as you have indicated above, your function simply outputs HTML, then it is a good candidate for a macro.
An example:
{# in your template #}
{% macro say_hello() %}
<p>Oh! Hello, world!</p>
{% endmacro %}
{# ... later on ... #}
{{ _self.say_hello() }}
Or with parameters:
{% macro input(name,value,type) %}
<input type="{{ type|default('text') }}" name="{{ name }}" value="{{ value }}">
{% endmacro %}
{{ _self.input('phone_number','867-5309') }}
{{ _self.input('subscribe','yes','checkbox') }}
The thing to remember is that Twig templates represent a view, in terms of MVC. This means they are isolated in terms of their environment, and can only represent the context you pass them via the data array you pass in the $template->render()
method.
This is a good thing, as it decouples your presentation from your logic and data. If you can arbitrarily call functions, then you suddenly increase that coupling, which is a bad thing.
The other reason for this is the way PHP handles callbacks. Think about how you would have to pass that function into your template... Probably something like this:
function blah() {
return "<p>Oh! Hello, world!</p>";
}
$template = $twig_env->loadTemplate('template.html');
echo $template->render(array('blah'=>'blah'));
In your template, the context variable blah
is now just a string containing 'blah'
.
In vanilla PHP, when you use variable functions like this (try to use a string variable like a function), it (more or less) performs a lookup for that function, then calls it. You are not passing the function, just it's name.
The thing is, you cannot possibly pass a function into a template, because PHP's only mechanism for doing this is by name-string, and once inside a template, that name is no longer a function name and just a string.
A little bit long winded, but I hope that helps!
If you want more documentation, the official docs are here.