RenderView in Symfony Command usage

后端 未结 3 2218
迷失自我
迷失自我 2021-02-20 08:52

How can I use $this->renderView inside a symfony Command (not inside a controller)? I new about the function \"renderView\" but what do I have to setup to use it wihtin a comman

相关标签:
3条回答
  • 2021-02-20 09:17

    In Symfony 4 I could not get $this->getContainer()->get('templating')->render($view, $parameters); to work.

    I set the namespace use for Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand and extended ContainerAwareCommand class EmailCommand extends ContainerAwareCommand

    I get an exception thrown

    [Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException]
          You have requested a non-existent service "templating".
    

    For Symfony 4, this is the solution I came up with.

    First I installed Twig.

    composer require twig
    

    Then created my own twig service.

    <?php
    
    # src/Service/Twig.php
    
    namespace App\Service;
    
    use Symfony\Component\HttpKernel\KernelInterface;
    
    class Twig extends \Twig_Environment {
    
        public function __construct(KernelInterface $kernel) {
            $loader = new \Twig_Loader_Filesystem($kernel->getProjectDir());
    
            parent::__construct($loader);
        }
    }
    

    Now my email command looks like this.

    <?php
    
    # src/Command/EmailCommand.php
    
    namespace App\Command;
    
    use Symfony\Component\Console\Command\Command,
        Symfony\Component\Console\Input\InputInterface,
        Symfony\Component\Console\Output\OutputInterface,
        App\Service\Twig;
    
    class EmailCommand extends Command {
    
        protected static $defaultName = 'mybot:email';
    
        private $mailer,
                $twig;
    
        public function __construct(\Swift_Mailer $mailer, Twig $twig) {
            $this->mailer = $mailer;
            $this->twig = $twig;
    
            parent::__construct();
        }
    
        protected function configure() {
            $this->setDescription('Email bot.');
        }
    
        protected function execute(InputInterface $input, OutputInterface $output) {
    
            $template = $this->twig->load('templates/email.html.twig');
    
            $message = (new \Swift_Message('Hello Email'))
                ->setFrom('emailbot@domain.com')
                ->setTo('someone@somewhere.com')
                ->setBody(
                    $template->render(['name' => 'Fabien']),
                    'text/html'
                );
    
            $this->mailer->send($message);
        }
    }
    
    0 讨论(0)
  • 2021-02-20 09:29

    Yet another one: rely on dependency injection, i.e. inject ContainerInterface

    namespace AppBundle\Command;
    
    use Symfony\Component\Console\Command\Command;
    use Symfony\Component\Console\Input\InputInterface;
    use Symfony\Component\Console\Output\OutputInterface;
    use Psr\Container\ContainerInterface;
    
    class SampleCommand extends Command
    {
        public function __construct(ContainerInterface $container)
        {
            $this->templating = $container->get('templating');
            parent::__construct();
        }
    
        protected function configure()
        {
            $this->setName('app:my-command')
                 ->setDescription('Do my command using render');
        }
    
        protected function execute(InputInterface $input, OutputInterface $output)
        {
            $data = retrieveSomeData();
            $csv = $this->templating->render('path/to/sample.csv.twig',
                                             array('data' => $data));
            $output->write($csv);
        }
    
        private $templating;
    }
    

    This relies on Symfony to inject the container, which in turn is used to retrieve either templating or twig or whatever you need for your custom command.

    0 讨论(0)
  • 2021-02-20 09:30

    Your command class must extends the ContainerAwareCommand abstract class and then you can do:

    $this->getContainer()->get('templating')->render($view, $parameters);
    

    When it comes to commands that extend ContainerAwareCommand the proper way to obtain the container is by getContainer() unlike in controller shortcut.

    0 讨论(0)
提交回复
热议问题