We have moved our forum to GitHub Discussions. For questions about Phalcon v3/v4/v5 you can visit here and for Phalcon v6 here.

How to load email templates which are stored in common view directory for multi module setup.

I have multi module setup with following directory structure.

-project --apps ----backend ----frontend ----webservice ----config ----common ------views ------models ----library --public --vendor

So far all works good as expected.

I now need to send emails from some actions of diffrent modules. I am using Swift Mailer plugin. It works fine for controller in frontend module, probabaly because it is default module but it wont work if i use it from controller of webservice module.

I have downlaoded the Swift mailer library and store it in vendor directory. Then crearted a file Mail.php in library directory taht has following code:

class Mail extends Component {

protected $_transport;

/**
 * Applies a template to be used in the e-mail
 *
 * @param string $name
 * @param array $params
 */
public function getTemplate($name, $params)
{

    $parameters = array_merge(array(
        'publicUrl' => $this->config->application->publicUrl,
    ), $params);

    return $this->view->getRender('emailTemplates', $name, $parameters, function($view){
        $view->setRenderLevel(View::LEVEL_LAYOUT);
    });

    return $view->getContent();
}

/**
 * Sends e-mails via gmail based on predefined templates
 *
 * @param array $to
 * @param string $subject
 * @param string $name
 * @param array $params
 */
public function send($to, $subject, $name, $params)
{

    //Settings
    $mailSettings = $this->config->mail;

    echo $template = $this->getTemplate($name, $params);

    //some code to send email

I have set Mail class in di aand use following code to send email :

$this->getDI()->getMail()->send( $admin_email, 'Beta list subscription', 'betajoin', array( 'email' => $email) );

When i call it from controller of webservice module it does not print template content but it works when i call it in frontend module.

What i guess is that getTemplate function does not load the view inside in webservice module.

Can I create a view in common/view/emailTemplates and render it inside the getTemplate function so I can keep all email template on common place?

You can user View helper to solve just, just use example from doc:

<?php

class PostsController extends \Phalcon\Mvc\Controller
{

    public function indexAction()
    {
        //Render 'views-dir/index.phtml'
        echo $this->view->render('index');

        //Render 'views-dir/posts/show.phtml'
        echo $this->view->render('posts/show');

        //Render 'views-dir/index.phtml' passing variables
        echo $this->view->render('index', array('posts' => Posts::find()));

        //Render 'views-dir/posts/show.phtml' passing variables
        echo $this->view->render('posts/show', array('posts' => Posts::find()));
    }

}

You can easily do similar in any library you want. Just $this->view change to $this->di->get('view') in Component.

The above line of code always looks view iin my default module "frontend". The problem might get solved if I able to set the new view dir in library, i tried registerDir here but it did not work.



5.4k
Accepted
answer

I got it work by creating a new object for \Phalcon\Mvc\View\Simple in my library file and then set new vide dir and engine.

public function getTemplate($name, $params) {

    $parameters = array_merge(array(
        'publicUrl' => $this->config->application->publicUrl,
    ), $params);

     $view = $this->getDI()->get('\Phalcon\Mvc\View\Simple');
    $view->setViewsDir(__DIR__.'/../common/views/');
    $view->registerEngines(array(
        ".volt" => 'Phalcon\Mvc\View\Engine\Volt'
    ));

    $content = $view->render('emails/verification', $parameters);

    return  $content;
}