Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to Render a custom view with plugins in Zend Framework 2

I'm working on an app that needs to send an email after a process is complete. Since the email needs to be HTML I had the bright idea of rendering a view as the email message body so that I can implement a "Click here to see this on your browser" functionality. This is all taking part inside a controller that implements AbstractRestfulController so the view itself resides in my front end module so that it can be accessed from a URL through a browser. However I am getting an

No RouteStackInterface instance provided

error when I try to render the view.

This is my code:

use Zend\View\HelperPluginManager;
use Zend\View\Resolver;
use Zend\View\Renderer\PhpRenderer;

//Instantiate the renderer
$renderer = new PhpRenderer();
$resolver = new Resolver\TemplateMapResolver(array(
            'layout' => realpath(__DIR__ . '/../../../../Application/view/layout/email.layout.phtml'),
            'email/view' => realpath(__DIR__ . '/../../../../Application/view/application/email/view.phtml')
        )
    );
$renderer->setResolver($resolver);
$renderer->url()->setRouter($this->getEvent()->getRouter());

I saw on the API documentation that you can set the router to the URL plugin by giving it a RouteStackInterface, hence the last line. However, that didn't seem to work either.

I would like to use the same view to send an HTML email message that has links in the message body & to display on the browser through a URL.

Any ideas/suggestions as to how to accomplish this?

EDIT/SOLUTION:

As per dotwired's answer below, getting the instance of the renderer from the service manager causes the plugins to be instantiated correctly. So this is the code that worked:

module.config.php:

array('view_manager' => array(
            'template_map' => array(
                    'layout/email'            => __DIR__ . '/../../Application/view/layout/email.layout.phtml',
                    'email/share'             => __DIR__ . '/../../Application/view/application/email/share.phtml',
                    'email/view'              => __DIR__ . '/../../Application/view/application/email/view.phtml',
            ),
    ),
);

REST controller:

use Zend\View\Model\ViewModel;

//get the renderer
    $renderer = $this->getServiceLocator()->get('Zend\View\Renderer\RendererInterface');

    //Create the views
    $shareView = new ViewModel(array('data' => $data));
    $shareView->setTemplate('email/view');
    $emailLayout = new ViewModel(array('subject' => $this->_subject, 'content' => $renderer->render($shareView)));
    $emailLayout->setTemplate('layout/email');

    //Render the message
    $markup = $renderer->render($emailLayout);

Using the renderer from the service manager the $this->url() view helper work without issue.

like image 668
Adrian Avatar asked Feb 25 '13 18:02

Adrian


1 Answers

Just use the module.config.php of your module to specify your email template, like:

'view_manager' => array(
    'template_path_stack' => array(
        'user' => __DIR__ . '/../view'
    ),
    'template_map' => array(
        'email/view' => __DIR__ . '/../view/application/email/view.phtml'
    )
),

After which you can go on with this part of the documentation. You can then pass your view template from the renderer to the MimePart which will be used by the MimeMessage like

$viewModel = new \Zend\View\Model\ViewModel();
$viewModel->setTemplate('email/view');

$renderer = $this->serviceLocator->get('Zend\View\Renderer\RendererInterface');
$htmlPart = new \Zend\Mime\Part($renderer->render($viewModel));
like image 138
Maxim Zubarev Avatar answered Oct 04 '22 01:10

Maxim Zubarev