Rendering view to variable disables primary view

Hi everyone, I'm trying to send out an email with html and plain text versions generated by templates. The email is getting created correctly, and sent out as intended, but the view in which I'd like to display the email sending results is blank.

My controller does something like:

function submitAction($vars_and_stuff){
  $post = Models\Post::findFirst(23);

  // do some stuff with post, save/update/etc

  // send mail
  $mail_result = $this->mail->sendMail($to, $from, $post);
}

My mail class is modeled after the Vokuro sample app Mail class. In the class I have:

private function _getTemplate(&$post, $template_name){
  return $this->view->getRender('templates', $template_name, array('post'=>$post), function($view){
    $view->setRenderLevel(View::LEVEL_LAYOUT);
  });

  return $view->getContent();
}

function sendMail($to, $from, &$post){
 ... 
  $html = $this->_getTemplate($post, 'emailHtml');
  $plain = $this->_getTemplate($post, 'emailPlain');
  ...
}

So at the end of all of this, in my view, submit.volt, nothing shows up. Just a blank page. Can someone point out what I'm doing wrong? I'm guessing it has do do with view render levels or similar, but I keep ending up with the same blank page no matter what.

Thanks! -Seth



11.9k

you have two "return" in "_getTemplate"?

Yeah -- I'm not sure why both returns are there -- the 2nd return should not ever happen, but I copied it from here:

https://github.com/phalcon/vokuro/blob/master/app/library/Mail/Mail.php#L59

thinking that it might do something else ...



11.9k
edited Jan '15

I just did a brief research and seem like there is no way to have multiple "return"; I'm not very knowledgable, however allow me to assume it is a mistake in the vokuro (there are also plenty of mistakes in the other Phalcon project INVO) and what it meant is "echo" instead of "return". Have you try "echo"?

I agree, I'm pretty sure that's an error in the Vokuro app Mail class. My emails are getting sent out correctly, the view renders my templates just fine (even with the 2 returns).

The problem I have is one level above that -- I want to return success messages when an email is sent correctly, or an error message if the email is invalid/server bounces back/transport problems/etc. But I just keep getting a blank view. If i disable the email sending, the view works as expected.



11.9k

"blank view" you mean like when a website is unavailable? I encounter that very often at the beginning, you may have to look at your error log; when I got "exit signal Illegal instruction (4)" kind of error message, it is because I'm trying to something that's designed for Phalcon 2. I guess you should post your error log here so there maybe some expert can figure it out easier.

In addition, at this moment I really don't think the second return is doing anything; have you comment out the second return and see how it change (I mean for the situation that you can see the view page)?



18.6k

chiWahWong is right: there is no way of multiple returns (unless they are in different clossures, in which one of them will execute). You will execute the first return, and then the function will end. I'm sure it is a code mistake of the tutorial.

For your other problem, see if the server writes an error.log, or do manual breakpoints (echo "<pre>"; var_dump(..); die(), for example). I didn't that tutorial so...

No errors -- just a blank page. I am using volt, so maybe that view is not getting compiled somehow. Http code is 200, so everything is working correctly; I've removed the 2nd return, no change. Now trying to create a separate view in the _getTemplate() function, but so far the same result.



11.9k

Right, the error.log file (server side error records), I do have a feeling that there is something valuable that indicate the termination of your code.

edited Jan '15

Found the solution here: http://stackoverflow.com/questions/25758424/using-volt-tempalte-with-view-simple-inside-user-component

Had to create another volt engine used only for rendering the emails. Code would have worked initially if i had just been using regular php templates (.phtml) rather than trying to use volt.

So now in Module.php:

$di->set('volt', function($view, $di){
            $volt = new \Phalcon\Mvc\View\Engine\Volt($view, $di);
            $volt->setOptions(array(
                'compiledPath' => '../cache/volt/',
                'compileAlways'   => TRUE
            ));

            $compiler = $volt->getCompiler();
            $compiler->addFunction('is_a', 'is_a');

            return $volt;
        }, TRUE);

        $di->set('email_volt', function($view, $di){
            $volt = new \Phalcon\Mvc\View\Engine\Volt($view, $di);
            $volt->setOptions(array(
                'compiledPath' => '../cache/volt/',
                'compileAlways'   => TRUE
            ));

            $compiler = $volt->getCompiler();
            $compiler->addFunction('is_a', 'is_a');

            return $volt;
        }, TRUE);

and my new template function:

private function _getTemplate(&$post, $template_name){
        $view = new View();
        $view->setViewsDir($this->config->application->viewsDir);
        $view->setDI($this->getDI());
        $view->registerEngines(array('.volt' => 'email_volt'));
        $view->setVar("post", $post);
        $view->start();
        $view->render("templates", $template_name);
        $view->finish();
        return $view->getContent();
    }

Not sure if it's the best way to do this, but it works as I have intended now.



11.9k

glad that you found the answer.



18.6k

If you only needed to use a phtml file, why don't you do as I do in my app? Then you request in your function the template.

Just wondering, I don't know if it will even short your work.

{% extends 'templates/yourEmailTemplate.volt' %}

{% block body %}
{{ super() }}
{% endblock %}


2.9k

Many thanks Its work for me too