枝條不允許直接做到這一點。你可以爲Twig添加一個簡單的函數來處理閉包的執行,或者將閉包封裝在類中以便能夠使用Twig的屬性函數(因爲直接調用attribute(_context, 'myclosure', args)
會觸發致命錯誤,因爲Twig將直接返回閉包並且忽略給定的參數,因爲_context
是一個數組)。
一個簡單的樹枝的擴展,實現這個目的應該是這樣的Symfony的2.8+。 (爲symfony1.2 4,看new documentation)
// src/AppBundle/Twig/Extension/CoreExtensions.php
namespace AppBundle\Twig\Extension;
class CoreExtensions extends \Twig_Extension
{
public function getFunctions()
{
return [
new \Twig_SimpleFunction('execute', [$this, 'executeClosure'])
];
}
public function executeClosure(\Closure $closure, $arguments)
{
return $closure(...$arguments);
}
public function getName()
{
return 'core_extensions_twig_extension';
}
}
然後,在你的模板,你只需要調用execute:
{{ execute(closure, [argument1, argument2]) }}
沒有延伸的樹枝,一個辦法來解決這個問題是使用一個類作爲封閉的包裝,並使用Twig的attribute
函數,因爲它可用於調用對象的方法。
// src/AppBundle/Twig/ClosureWrapper.php
namespace AppBundle\Twig;
/**
* Wrapper to get around the issue of not being able to use closures in Twig
* Since it is possible to call a method of a given object in Twig via "attribute",
* the only purpose of this class is to store the closure and give a method to execute it
*/
class ClosureWrapper
{
private $closure;
public function __construct($closure)
{
$this->closure = $closure;
}
public function execute()
{
return ($this->closure)(...func_get_args());
}
}
然後,你只需要渲染的,而不是封閉自己的時候給一個ClosureWrapper實例模板:
use AppBundle\Twig\ClosureWrapper;
class MyController extends Controller
{
public function myAction()
{
$localValue = 2;
$closure = new ClosureWrapper(function($param1, $param2) use ($localValue) {
return $localValue + $param1 + $param2;
});
return $this->render('mytemplate.html.twig', ['closure' => $closure]);
}
...
最終,在你的模板,你需要使用attribute
執行關閉你在控制器中定義:
// Displays 12
{{ attribute(closure, 'execute', [4, 6]) }}
然而,這是一個有點多餘的,internally,該Twig的10個函數也解包給定的參數。通過使用上面的代碼,對於每次調用,參數都會連續解壓縮,打包和解壓縮。
謝謝!但是這個解決方案對我來說不起作用,因爲邏輯是可變的 – Carles
你的意思是「邏輯是可變的」? – Terenoth
它可能是許多不同的條件函數,具有不同的條件。我認爲將不同條件的分枝擴展放在一起效率不高,因爲它會導致模板呈現性能下降。 – Carles