Использовать Twig Extension в контроллере
У меня есть метод slugify в расширении Twig, который я хотел бы использовать в некоторых случаях в контроллере, т.е. с перенаправлением.
Есть ли простой способ для этого?
Как я могу получить доступ к функциям из Twig Extensions в контроллере?
Или мне нужно сделать метод slugify некогда помощником, чтобы использовать его в коде и в twig?
Ответы
Ответ 1
Я бы посоветовал создать общий сервис и ввести его в расширение Twig. Расширение будет действовать как оболочка для службы.
namespace Acme\Bundle\DemoBundle\...;
class MyService
{
public function myFunc($foo, $bar)
{
// some code...
}
// additional methods...
}
EDIT - как упоминалось Squasic, первый аргумент должен реализовать Twig_ExtensionInterface
. Неэлегантным решением было бы добавить методы к MyTwigExtension
, которые в свою очередь вызывают соответствующие методы в службе.
namespace Acme\Bundle\DemoBundle\Twig\Extension;
class MyTwigExtension extends \Twig_Extension
{
protected $service;
public function __construct(MyService $service)
{
$this->service = $service;
}
public function getFunctions()
{
return array(
'myTwigFunction' => new \Twig_Function_Method($this, 'myFunc'),
'mySecondFunc' => new \Twig_Function_Method($this, 'mySecondFunc'),
);
}
public function myFunc($foo, $bar)
{
return $this->service->myFunc($foo, $bar);
}
// etc...
}
Ответ 2
Функция доступа/логика от веточки и контроллера
Я думаю, что для этого есть два решения, оба должны использовать класс Twig_Function_Method
.
1
Первое уже принятое решение gilden
- это инкапсулировать логику в службу и сделать оболочку для расширения Twig.
2
Другим решением является использование только расширения Twig. Twig Extensino уже является сервисом, вы должны определить его как услугу со специальным <tag name="twig.extension" />
.
Но это также сервис, который вы можете захватить контейнером сервиса. А также можно вводить другие услуги:
Итак, у вас есть расширение/сервис Twig:
class MyTwigExtension extends \Twig_Extension
{
private $anotherService;
public function __construct(SecurityService $anotherService= null)
{
$this->anotherService = $anotherService;
}
public function foo($param)
{
// do something
$this->anotherService->bar($param);
}
public function getFunctions()
{
// function names in twig => function name in this calss
return array(
'foo' => new \Twig_Function_Method($this, 'foo'),
);
}
/**
* Returns the name of the extension.
*
* @return string The extension name
*/
public function getName()
{
return 'my_extension';
}
}
Образ services.xml выглядит следующим образом
<service id="acme.my_extension" class="Acme\CoreBundle\Twig\Extension\MyTwigExtension">
<tag name="twig.extension" />
<argument type="service" id="another.service"></argument>
</service>
Чтобы перейти к сервису с вашего контроллера, вам нужно использовать это:
$this->container->get('acme.my_extension')
Примечание Единственное отличие от обычной службы заключается в том, что расширение ветки не загружается без лжи (http://symfony.com/doc/current/cookbook/templating/twig_extension.html#register-an-extension-as-a-service)