问题
When sending out e-mails in Zend Framework 2, I want to use view script templates such that I can leverage a layout for my various e-mail templates. The idea is that I have a layout which has the shared markup and echoes out content somewhere. Exactly how layouts work in general. To accomplish this, I am trying to add a child view model to my layout view model and render it with the PhpRenderer
.
public function someMethod() {
$child = new ViewModel();
$child->setTemplate('test-template');
$layout = new ViewModel();
$layout->setTemplate('email-layout');
$layout->addChild($child, 'content');
$phpRenderer = new \Zend\View\Renderer\PhpRenderer();
$phpRenderer->setCanRenderTrees(true);
$resolver = new \Zend\View\Resolver\TemplateMapResolver();
$resolver->setMap($this->serviceLocator->get('ViewTemplateMapResolver'));
$phpRenderer->setResolver($resolver);
$output = $phpRenderer->render($layout);
}
Layout view script:
Hello from the e-mail layout script!
<?php echo $this->content; ?>
What happens is that only the layout's content is stored in $output
and $this->content
within the layout view script is NULL
.
What I am trying to do is to store the HTML in a string such that I can send it in an e-mail. I instantiate a child view model, which represents the view script that I would like to render within the layout. Then I instantiate the layout view model and add the child view model. Then I create a PhpRenderer and add a TemplateMapResolver
to it such that it will resolve templates by using the template map. Lastly, I call the render
method on the PhpRenderer
which takes a ViewModel
as its first parameter. I have added both templates to my template_map
configuration and the template map is set correctly with the correct names and correct paths.
The thing is that I do not see any handling of child views in its render method. This makes me think if I am using the PhpRenderer
class incorrectly and perhaps that is why it doesn't work. I have checked the documentation for nesting view models, and I am doing the same thing, except not returning the view model from a controller action. If I return $layout
from a controller action, it works.
If I look at Zend\View\View
's render method, I can see that it renders child views. It would seem as if I cannot use the PhpRenderer
like I want to. But can I use the Zend\View\View
for this? The render
method does not return anything, but triggers some events. I am not too familiar with the event manager yet, so I am not sure how/if I can capture the output if using this method. Would it be sensible to listen to the response event? I would have to check which view was rendered I guess (or detach my listener after doing my work). I don't know if that's any good.
Any ideas are more than welcome. Thank you!
回答1:
$this->content
is null because PhpRenderer just render self level not including children view models.
Actually the ZF2 MVC rendering are using Zend\View\View->render() but not Zend\View\Renderer\PhpRenderer->render(), so you need to render tree templates exactly like what Zend\View\View does:
foreach ($layout as $child) {
if ($child->terminate()) {
continue;
}
$child->setOption('has_parent', true);
$result = $view->render($child);
$child->setOption('has_parent', null);
$capture = $child->captureTo();
if (!empty($capture)) {
if ($child->isAppend()) {
$oldResult=$model->{$capture};
$layout->setVariable($capture, $oldResult . $result);
} else {
$layout->setVariable($capture, $result);
}
}
}
$output = $view->render($layout);
See ZF2 source code to know more:
https://github.com/zendframework/zf2/blob/master/library/Zend/View/View.php#L222
来源:https://stackoverflow.com/questions/15188614/using-phprenderer-directly-with-child-views-in-zf2