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

\Phalcon\Mvc\View's setContent() not working in action

I have a question about how the \Phalcon\Mvc\View works. This class has a setContent() method, yet the content set with it won't be part of the output of $this->getContent() - neither in views/example/overview.phtml nor views/index.phtml. Shouldn't foobar show up in one of those views?

Use-Case: I have different HTML codes for some contents, saved in a database. Those codes should be setable as the content for overviewAction (and some other actions in different controllers) and I don't want to create view files for all those actions, yet the content should be included in/be part of the main layout. That's why simply returning the content won't work.

ExampleController.php

class ExampleController extends \Phalcon\Mvc\Controller {
    public function overviewAction () {
        //This doesn't work, too:
        //$this->view->disableLevel([\Phalcon\Mvc\View::LEVEL_ACTION_VIEW => true]);
        $this->view->setContent('foobar');
    }
}

index.php:

$di->setShared('view', function() use ($events_manager, $di) {
    $view = new \Phalcon\Mvc\View();

    //Disable layout-level
    $view->disableLevel([\Phalcon\Mvc\View::LEVEL_LAYOUT => true]);

    //Bind the EventsManager to the view component
    $view->setEventsManager($events_manager);

    $view->setVar('f', $di->get('filter'));

    return $view;
});

Hi @fabsn182 to render any view file what you want you have to use pick() method from the view to select them.

Tip: don't need set filter service in view because is already injected in DI and the view too. Then you can use filter in the view files.

// view.phtml
<h1>Hello <?=$this->filter->sanitize($userName, 'string')?></h1>

Good luck

edited Jan '18

I don't want to render any view for those actions. I want to set the content without having to create and/or pick a specific view file.

That's what the setContent() method is for, isn't it? Because returning anything from an action results in only that content being shown - without being wrapped with the layout file

//I am not setting the filter service, I am setting a shortcut ($f) for all views

Well you have to use response service for that


class SomeController extends \Phalcon\Mvc\Controller {
    public function indexAction() {
        return $this->response->setContent('hello world!')->send();     
    }
}

Please read what I wrote:

returning anything from an action results in only that content being shown - without being wrapped with the layout file

And that is an unwanted behaviour



77.7k
Accepted
answer
edited Jan '18

I dont know what view->setContent() actually does, but this is working for me:

class ExampleController extends \Phalcon\Mvc\Controller {
    public function overviewAction () {
        echo 'foobar';
    }
}
<p>
<h1>Some content page</h1>
{{ content() }}
</p>

Result is

Some content page

foobar

so RTFM

Please read what I wrote:

returning anything from an action results in only that content being shown - without being wrapped with the layout file

And that is an unwanted behaviour

edited Jan '18

so RTFM

Oh boi, calm your tits. There's nothing in the "manual" about that. Lajos Bencz's answer works but feels wrong. Echoing in a controller? Meh.

I use echo $html in my controller and it work. I have one main views with code

    <div class="container">
        <?php echo $this->getContent();?>
    </div>

And now if i look code-page in browser i see what my $html located in <div class="container">