Solved thread

This post is marked as solved. If you think the information contained on this thread must be part of the official documentation, please contribute submitting a pull request to its repository.

Volt - foreach loop && render

Hello,

I am experiencing a strange behavior. I have the following code:

    public function sendEventReportAction()
    {
        $events = Event::find([
            "status = :status:",
            "bind" => [
                "status" => Event::STATUS_SETTLED
            ],
            "order" => "end_time ASC"
        ]);

        if ($events->count() > 0) {
            foreach ($events as $o_event) {
                $template = $this->renderEventTemplate($o_event);
                ld($template);
            }
        }
    }

    private function renderEventTemplate(Event $o_event)
    {
        $this->view->pick('event/partial/status_content');
        $this->view->setVar('o_event', $o_event);

        $template = $this->view->getRender('event', 'status', null, function($view) {
            $view->setRenderLevel(Phalcon\Mvc\View::LEVEL_ACTION_VIEW);
        });

        return $template;
    }

This code it's a task that renders a template and sends it via email as html format. The problem that I have is that the view is rendering only the first event.

The rest of them are not rendered. So if i have 3 events, the $template var for event 1 returns the expected result, but for events 2 and 3 returns an empty string.

Anyone had similar problems ? Thanks.

Phalcon 1.3.4 / PHP 5.6 / Ubuntu 14.04



46.7k
edited Dec '14

A Volt service seems to get confused and so I define it as a closure that can then be reused easily. Also I use a Simple View for my emails and lets the voltService die after each render as opposed to the typical Controller View setup tha reuses it.

$voltService = function($view, $di) {
    // ...
    return $volt;
};


$di->set('voltService', $voltService);



$di->set('viewSimple', function() use ($di, $voltService) {
    $config = $di->get('config');

    $view = new ViewSimple();
    $view->setDI($di);

    $view->registerEngines([
        '.volt' => $voltService
    ]);

    $view->setViewsDir($config->path->viewsSimpleDir);

    return $view;
});


46.7k
Accepted
answer

Try using a simple view first as I believe that the solution that I provided is for when you are using simple views and normal views from a Controller dispatcher cycle. Simple views are better suited to rendering a stand-alone template.



34.0k

Thanks @dschissler , but I need inheritance and the simple view does not support it.



46.7k

You can get nearly this same effect with partial includes.

On Thu, Dec 11, 2014 at 11:47 AM, Calin Rada <[email protected]> wrote:



46.7k
edited Dec '14

Also you can pass in prerendered template strings into a main ~~string~~ template.



34.0k

Finally, you were right using simple view. It works:

    public function sendEventReportAction()
    {
        $events = Event::find([
            "status = :status:",
            "bind" => [
                "status" => Event::STATUS_SETTLED
            ],
            "order" => "end_time ASC"
        ]);

        if ($events->count() > 0) {
            foreach ($events as $o_event) {
                $template  = $this->view->render('event/partial/status_content', ['o_event' => $o_event]);
                ld($template);
            }
        }
    }

The view service declared as simple:

        $di['view'] = function () {

            $view = new \Phalcon\Mvc\View\Simple();
            $view->setViewsDir(__DIR__ . '/../Views/');
            $view->registerEngines(array(
                ".volt" => 'voltService'
            ));

            return $view;
        };


34.0k

For someone who has a similar problem: please check my final answer to view the code for a functional example

Try using a simple view first as I believe that the solution that I provided is for when you are using simple views and normal views from a Controller dispatcher cycle. Simple views are better suited to rendering a stand-alone template.