How to Call Static Function In Symfony2 Twig Template
You cannot directly call PHP in a twig template. You'll need to create a filter or function to do what you're looking.
$twig = new Twig_Environment($loader, $params);
$twigFunction = new Twig_SimpleFunction('MyStaticClass', function($method) {
MyStaticClass::$method
});
$twig->addFunction($twigFunction);
Then in your twig template just do:
{{ MyStaticClass('getData') }}
Of course the above example assumes MyStaticClass
is within the scope of wherever you're twig.
Symfony Example
You must create a twig extentions. Example below:
namespace PurpleNeve\Web\PNWebBundle\Extensions;
use PurpleNeve\Web\PNWebBundle\DependencyInjection\CurrencyConverter;
class TwigCurrency extends \Twig_Extension
{
private $converter;
public function __construct(CurrencyConverter $converter)
{
$this->converter = $converter;
}
public function getName()
{
return 'currency';
}
public function getFilters()
{
return array(
'convertCurrency' => new \Twig_Filter_Method($this, 'getConversionBetween')
);
}
public function getConversionBetween($amount, $isoFrom, $isoTo="USD")
{
try {
$value = $this->converter->convertAmount($amount, $isoFrom, $isoTo);
return round($value,2);
} catch(\Exception $e) {
return "?";
}
}
}
This is an example of an extension I created to convert currency from one currency to another in twig.
To implement it, you need to create a service object for it in your services.yml
parameters:
currency_converter.class: PurpleNeve\Web\PNWebBundle\DependencyInjection\CurrencyConverter
services:
currency_converter:
class: "%currency_converter.class%"
arguments : [@doctrine.orm.entity_manager]
twig.extension.currency:
class: PurpleNeve\Web\PNWebBundle\Extensions\TwigCurrency
tags:
- { name: 'twig.extension' }
arguments : [ @currency_converter ]
Then as above, within twig I can call that class and function using {{ convertCurrency(55505, 'CAD', 'USD) }}
A generic approach is to register a Twig helper function named callstatic
to make the call.
$twig->addFunction(new \Twig_SimpleFunction('callstatic', function ($class, $method, ...$args) {
if (!class_exists($class)) {
throw new \Exception("Cannot call static method $method on Class $class: Invalid Class");
}
if (!method_exists($class, $method)) {
throw new \Exception("Cannot call static method $method on Class $class: Invalid method");
}
return forward_static_call_array([$class, $method], $args);
}));
The main advantage of this approach is that it will work with any class and method combination.
Usage:
{# This will call \Mynamespace\Mypackage\Myclass::getStuff(); #}
{% set result = callstatic('\\Mynamespace\\Mypackage\\Myclass', 'getStuff') %}
It also supports arguments:
{# This will call \Mynamespace\Mypackage\Myclass::getStuff('arg1', 'arg2'); #}
{% set result = callstatic('\\Mynamespace\\Mypackage\\Myclass', 'getStuff', 'arg1', 'arg2') %}
Instead of writing a Twig extension an easier / less bloated solution can sometimes be to simply pass a new instance of the class with the static methods to twig.
eg
// ...
$viewVars['MyStaticClass'] = new MyStaticClass();
// ...
$html = $twig->render('myTemplate.html.twig', $viewVars);
and in twig:
{{ MyStaticClass.getData() }}