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

Storing a views content

hey Guys,

I'm hitting a little logic bump here. I want to store the contents of a view without outputting anything. I've managed to do it but i'm afraid of hitting bumps later on when someone uses this component outside of the normal context.

 if(!is_null($viewName)) {

            if(!$this->view) {
                throw new Exception('No view engine registered!');
            }

            $mailView = clone $this->view;

            $mailView->reset();
            $mailView->setRenderLevel(View::LEVEL_NO_RENDER);

            $mailView->setVar('bla', 'BLALALA');
            $mailView->partial($viewName);

            // get the contents from the outputBuffer when parsing the view
            $this->_viewContent = ob_get_contents();
            ob_end_clean();
        }

This code works, but i don't feel comfortable with this solution. Does anybody have a better idea?

See the docs: https://docs.phalcon.io/en/latest/reference/views.html#stand-alone-component

<?php

$view = new \Phalcon\Mvc\View();

//A trailing directory separator is required
$view->setViewsDir("../app/views/");

// Passing variables to the views, these will be created as local variables
$view->setVar("someProducts", $products);
$view->setVar("someFeatureEnabled", true);

//Start the output buffering
$view->start();

//Render all the view hierarchy related to the view products/list.phtml
$view->render("products", "list");

//Finish the output buffering
$view->finish();

echo $view->getContent();


8.1k

@philippgerard I read the docs very thoroughly. I might not have been specific enough in what i want to achieve. I don't want to use the view component standalone, i want to use the view system configured in the bootstrap to load views into email bodies to be used as templates. I've tested all of the solutions offered in the docs and nothing achieved what i am trying to accomplish.

Ah, I see! And may I ask why you don't just instantiate a new view object for that purpose? Why use the one from bootstrap which has various events attached to it etc? That'll only end up in confusion once your project matures. If you need it in the bootstrap, add a "mailView" component or something, which contains the required settings but remains independent from the core view dependency.



8.1k

Well the idea is that it's integrated with the application but now that i think of it, i might as well add it to the bootstrap with a custom view configuration. Probably the wisest thing to do, need to work it out a bit more. thanks though :)

Philipp is right :) and for email than add full View component, use SimpleView component https://docs.phalcon.io/en/latest/api/Phalcon_Mvc_View_Simple.html



8.1k

@doit76 i was looking at this component, but i don't know if this component also has the ability to load partials into views. Which is nessesary if you want to send a mail with a layout and a template inside.

Yes you can use everything which offer View component. Difference is that this component haven't got hierarchical levels. Just point&view ;)



2.9k

If I want to use the Phalcon\Mvc\View\Simple, The following code Is it error?

$view = new \Phalcon\Mvc\View\Simple(); $view->setViewsDir('/someDir'); $view->registerEngines([".volt" => "Phalcon\Mvc\View\Engine\Volt",]); // Render /someDir/a/b/c/mailBody.volt $mailBody = $view->render('a/b/c/mailBody', array());

I got Phalcon\Mvc\View\Exception: A dependency injector container is required to obtain the application services.

thank you.



98.9k

@shuogawa It seems the view you're rendering is needing access a service in the services container thus you need to pass it to make available to the views:

$view = new \Phalcon\Mvc\View\Simple();
$view->setDI($di);
//...


2.9k

thank you @Phalcon.

my index.php is simple. <?php $view = new \Phalcon\Mvc\View\Simple(); $view->setViewsDir('/someDIr'); $di = new \Phalcon\DI\FactoryDefault(); $view->setDI($di); $view->registerEngines([".volt" => new \Phalcon\Mvc\View\Engine\Volt($di)]); $result = $view->render('a/b/c/mailBody', array());

and template is simple 'this is mail body'

I got Fatal error: Phalcon\Mvc\View\Engine\Volt::render(): Call to undefined method setcontent() on class Phalcon\DI\FactoryDefault Is there something wrong?

In addition, to assign the result of the view like the fetch method of smarty is, What should I do?



98.9k

The first parameter of Phalcon\Mvc\View\Engine\Volt is the view component:

$view = new \Phalcon\Mvc\View\Simple();
$view->setViewsDir('./views/');

$di = new \Phalcon\DI\FactoryDefault();
$view->setDI($di);

$view->registerEngines([".volt" => function($view, $di) {
    return new \Phalcon\Mvc\View\Engine\Volt($view, $di);
}]);

echo $view->render('templates/mailBody', array());


2.9k

Thank you. Was a careless mistake. I can get the results of the View correctly.

@thecodeassassin I think Phalcon\Mvc\View\Simple is a good way.

<?php

namespace Library;

use Phalcon\Mvc\User\Component;
use Phalcon\Mvc\View\Simple as View;

class Elements extends Component
{
    protected $simpleView;

    public function __construct()
    {
        $this->simpleView =  new View();
        $this->simpleView->setDI($this->getDI());
    }

    public function getMenu()
    {
        $this->simpleView->setViewsDir($this->view->getViewsDir());

        return $this->simpleView->render('templates/topMenu', ['Foo' => 'Bar']);
    }
}