Yii2 Mailer layout change

Hi all,

how can i set layout in mail??

i have been using:

Yii::$app->mailer->compose(‘viewName’, [‘variable’ => $variable]);

this renders the view using the default html layout in layouts/html

how can i change the layout ?

thanks for the help in addvance

This is written in yii2\mail\BaseMailer.php




    /**

     * @var string|boolean HTML layout view name. This is the layout used to render HTML mail body.

     * The property can take the following values:

     *

     * - a relative view name: a view file relative to [[viewPath]], e.g., 'layouts/html'.

     * - a path alias: an absolute view file path specified as a path alias, e.g., '@app/mail/html'.

     * - a boolean false: the layout is disabled.

     */

    public $htmlLayout = 'layouts/html';




yes i have checked this file too but i didnt understand how to set the layout.

i am giving a view name:

Yii::$app->mailer->compose(‘viewName’, [‘variable’ => $variable]);

how can i set the layout ?

Yii::$app->mailer->compose(‘viewName’,‘htmlLayout’?? [‘variable’ => $variable]);

You will be having a folder \app\mail\layouts\

In that you will find html.php which is the default view file.

You can add another view file, say html2.php




Yii::$app->mailer->compose('layouts/html2', ['variable' => $variable]);



so its not possible to pass a layout and a view ?

As per my understanding, in the layout, you can make ready the view file for the required purpose with all html and css, and pass on only the required variables, like the name of the recipient, or whatever.

The template with html and CSS you can have in the ‘layout’ directory, and only variables are enough. We will be using only one page at a time for one email.

In case of a web application, there will be number of pages with different setting. There the layout, view file and variable will make sense.

i have made small change in BaseMailer.php and created an option to set layout. If a layout is set then its use that one else default. I know this is not the best solution to solve this one… by next update it will get updated/deleated.

Made this suggestion in Github too …




public function compose($view = null, array $params = [])

    {

        $message = $this->createMessage();

        if ($view === null) {

            return $message;

        }


        if (!array_key_exists('message', $params)) {

            $params['message'] = $message;

        }


        $this->_message = $message;

      

        if (is_array($view)) {

            if (isset($view['html'])) {

                if(isset($view['layout'])){

                  $this->htmlLayout = $view['layout'];

                }

                $html = $this->render($view['html'], $params, $this->htmlLayout);

            }

            if (isset($view['text'])) {

                if(isset($view['layout'])){

                  $this->textLayout = $view['layout'];

                }

                $text = $this->render($view['text'], $params, $this->textLayout);

            }

        } else {

            $html = $this->render($view, $params, $this->htmlLayout);

        }

    ...

}



Following from the documetation, it is possible and preferable (compared to changing the core framework) to do this




\Yii::$app->mailer->htmlLayout = "layouts/custom_html";

\Yii::$app->mailer->compose("view");



Or to set it in application component, if that is gonna be the default one.

3 Likes