How to render a mail template with layout in ZF2?

2020-02-26 08:07发布

问题:

In the ZF1 I used the following code to render a mail body:

// View erstellen
$view = new Zend_View();
// Layout erstellen
$layout = new Zend_Layout();

// HelperPath muss hier nochmals übergeben werden da es ein neues View Objekt ist.
$view->addHelperPath('Own/View/Helper', "Own_View_Helper_");

// ViewScript
$view->setScriptPath(APPLICATION_PATH . '/views/scripts/emails/');

// LayoutPath
$layout->setLayoutPath(APPLICATION_PATH . '/layouts/scripts/');

$layout->setLayout('layoutMail');
$layout->setView($view);

foreach ($assigns as $key => $value) {
    $view->assign($key,$value);
}

$layout->content = $view->render($templateName);
return $layout->render();

I tried a lot but I cannot realise this function in ZF2. My actual code is this. But it uses the standard layout and I cannot get it in a string.

public function mailAction()
{
    $viewModel = new ViewModel();
    $viewModel->setTemplate("zhorty/test");
    $viewModel->setVariable('test', 'some value');
    return $viewModel;
}

回答1:

Thank you! Your answer helped me!

I extended the code. So I can use a layout template as well.

$view = new \Zend\View\Renderer\PhpRenderer();
$resolver = new \Zend\View\Resolver\TemplateMapResolver();
$resolver->setMap(array(
            'mailLayout' => __DIR__ . '/../../../../Application/view/layout/layout-mail.phtml',
            'mailTemplate' => __DIR__ . '/../../../view/zhorty/test.phtml'
    ));
$view->setResolver($resolver);

$viewModel = new \Zend\View\Model\ViewModel();
$viewModel->setTemplate('mailTemplate')
    ->setVariables(array(
    'test' => 'AlloVince'
));     

$content = $view->render($viewModel);

$viewLayout = new \Zend\View\Model\ViewModel();
$viewLayout->setTemplate('mailLayout')
     ->setVariables(array(
            'content' => $content
));

echo $view->render($viewLayout);


回答2:

My answer is based on user1986560's answer and How to Render a custom view with plugins in Zend Framework 2. I'm adding it as I think it makes things a little easier to implement.

I have an email layout and different content files. The layout can be reused and different content files added.

view/email/layout.phtml

<table>
    <tr><td><img src="header.png" /></td></tr>
    <tr><td><?= $this->content; ?></td></tr>
    <tr><td><img src="footer.png" /></td></tr>
</table>

view/email/contact.phtml

<h1>Contact us email</h1>
</ br>
Name: <?= $this->name;?></ br>
Email: <?= $this->email;?></ br>
Message:<?= $this->message;?></ br>

In your modules conf, add the layout and different content files. By doing it this way, you can use view helpers.

module.config.php

'view_manager' => array(
    'template_map' => array(
        'email/layout'  => __DIR__ . '/../view/email/layout.phtml',
        'email/contact' => __DIR__ . '/../view/email/contact.phtml',
    ),

In your controller/action:

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

// Email content
$viewContent = new \Zend\View\Model\ViewModel(
    array(
        'name'    => $name,
        'email'   => $email,
        'message' => $message,
));
$viewContent->setTemplate('email/contact'); // set in module.config.php
$content = $renderer->render($viewContent);

// Email layout
$viewLayout = new \Zend\View\Model\ViewModel(array('content' => $content));
$viewLayout->setTemplate('email/layout'); // set in module.config.php

// Email
$html = new MimePart($renderer->render($viewLayout));
$html->type = 'text/html';
$body = new MimeMessage();
$body->setParts(array($html));
$message = new \Zend\Mail\Message();
$message->setBody($body);


回答3:

Hopefully one of my blog post will help you out, it is about how to use Zend\View as template in Zend\Mail and add attachments in ZF2

It is written by Chinese, but I think just read the code is clear enough. Also you could read it with help of Google translation



回答4:

For sendig Emails I recommend the following Module: https://github.com/WasabiLib/Mail

The Module is based on the ZF2 message and it is configured as a service. So you only need to call the servicemanager.

The body method is able to handle ZF2 viewModels. See the example below:

$mail = $this->getServiceLocator()->get("Mail");
$viewModel = new ViewModel(array('$yourVariable1' => 'yourContent1', $yourVariable2=>'yourContent2',...));
$viewModel->setTemplate("responsive");
$mail->setTo('recipient@domain.com');
$mail->setBody($viewModel);
$mail->send();

It is bundled with a responsive email template that you can customize. You only need to add the module to the application.config.php and you are ready to go.



回答5:

@user1986560 answer is not complete, cause you must need some basic helper like "url" with router and sometimes "basePath" also required.

Here is the complete code -

$myApp=Zend\Mvc\Application::init(require 'config/application.config.php');
$sm=$myApp->getServiceManager();

$view=new \Zend\View\Renderer\PhpRenderer();
$view->getHelperPluginManager()->setServiceLocator($sm);
$basePathX='/your-folder-from-where-you-want-to-run';
$request=$myApp->getRequest();
if($request instanceof \Zend\Http\PhpEnvironment\Request){
    #die($request->getBasePath());
    $basePathX=$request->getBasePath();
}
$basePath1=explode('/', $basePathX);
/* please fix this path as your requirement */
array_pop($basePath1);
$bsPath=implode('/', $basePath1).'/';
/* following line will fix your router path, it is important */
$myApp->getMvcEvent()->getRouter()->setBaseUrl($bsPath);
$basePath=new \Zend\View\Helper\BasePath();
$basePath->setBasePath($bsPath);
$view->getHelperPluginManager()->setService('basePath', $basePath);
$urlHlpr=new \Zend\View\Helper\Url();
$urlHlpr->setRouter($myApp->getMvcEvent()->getRouter());
$view->getHelperPluginManager()->setService('url', $urlHlpr);

$resolver=new \Zend\View\Resolver\TemplateMapResolver();
$resolver->setMap(array(
        'wmsLayout' => APP_ROOT_PATH . 'module'.DS.'YourModule'.DS.'view'.DS.'layout'.DS.'layout1.phtml',
        'layout/left-menu' => APP_ROOT_PATH . 'module'.DS.'YourModule'.DS.'view'.DS.'layout'.DS.'left-menu.phtml',
));
$view->setResolver($resolver);

$viewModel = new \Zend\View\Model\ViewModel();
$tmpltFileToLoad=__DIR__ . DS.'your-file-to-render.phtml';
$tmpltIdx='_'.md5($tmpltFileToLoad);
$resolver->add($tmpltIdx, $tmpltFileToLoad);
$viewModel->setTemplate($tmpltIdx)->setVariables(array(
        'test' => 'shahadat hossain khan'
));
$content=$view->render($viewModel);

$viewLayout = new \Zend\View\Model\ViewModel();
$viewLayout->setTemplate('wmsLayout')->setVariables(array(
        'content' => $content,
        'anyOtherVariableForLayout'=>'layout variable value',
    ));
echo $view->render($viewLayout);

Hope it my help someone.