Twig doğrudan bunu yapmaya izin vermiyor. Twig'e basit bir işlev ekleyebilir veya kapağın işlevini kullanabilmeniz için kapağınızı bir sınıfa sarın ya da Twig'in öznitelik işlevini doğrudan kullanabileceğinden, doğrudan attribute(_context, 'myclosure', args)
'u bir Önemli Hata tetikleyecektir. _context
bir dizidir, çünkü verilen argümanları yok sayın).
Bu amaca ulaşan basit bir Twig uzantısı Symfony 2.8+ için buna benzer. sadece aramak zorunda şablonlarınızda, Sonra
// 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';
}
}
(Symfony'de 4 için new documentation bakınız) yürütün:
{{ execute(closure, [argument1, argument2]) }}
Twig uzanan olmadan, tek yönlü bu sorunu aşmanın Kapanışınız için bir sarıcı görevi gören bir sınıf kullanmak ve bir nesnenin yöntemini çağırmak için kullanılabileceği için Twig'in attribute
işlevini kullanmaktır.
// 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());
}
}
Sonra, sadece yerine kapağın kendisinin render yaparken şablona bir ClosureWrapper örneğini vermek gerekir: Şablonunuzdaki,
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]);
}
...
Sonunda, kapatma çalıştırmak için attribute
kullanmak gerekir Eğer denetleyici tanımlanan:
// Displays 12
{{ attribute(closure, 'execute', [4, 6]) }}
Ancak bu, gibi biraz gereksiz Twig'in 10 işlevi, verilen argümanları da açar. Yukarıdaki kodu kullanarak, her bir çağrı için, argümanlar art arda paketlenip paketlenip tekrar açılır.
Teşekkürler! Fakat mantık değişkeni – Carles
olduğu için bu çözüm benim için çalışmaz "Mantık değişkendir" ile ne demek istiyorsun? – Terenoth
Farklı koşullara sahip birçok farklı koşullu işlev olabilir. Şablon oluşturmada performansı azaltacağından, farklı koşullara göre fazla sayıda uzantı koymanın etkili olmadığını düşünüyorum. – Carles