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.

Views: Stop hierarchical propagation from the view file

Hi,

I've read the docs about the hierarchical rendering levels, and how to disable certain levels from the controller or the DI setup: https://docs.phalconphp.com/en/3.3/views#disabling-render-levels

I would like to do that from the view file that belongs to the action. So not from the controller, but from the /views/controllername/actionname.phtml . Is it possible? I use the \MyPhalcon\View\PhpEngine.

In case you wonder why I want to do this: Some of my forms needs to respond with just a partial HTML. So not the entire webpage. And I want to put that logic into the viwe file, not the controller. I consider Controller to be business loginc, I dont want to write things there that is doing things for the view. The controller (or rather, the person who writes the controllers) should not need t know about what will happen in the view. So I dont want to disable rendering levels in the controller files, but instead I want to do it in the view phtml files.

Thanks



60.5k
Accepted
answer

We could argue about your approach and MVC here...

But the tech says that the views are executed last.

Phalcon automatically passes the execution to the view component as soon as a particular controller has completed its cycle.

Note here the part: controller has completed its cycle

Have you tried to use partials for the task?

https://github.com/phalcon/docs/blob/3.4/en/views.md/#using-partials

edited Jun '18

Thank you. So I keep that 1 line in the controller :) $this->view->->setRenderLevel( \Phalcon\Mvc\View::LEVEL_ACTION_VIEW );

We could argue about your approach and MVC here...

Actually, that could be interesting and useful to me (and perhaps for others who happen to read it). So I know it could go off topic, but if you don't mind the effort, please do say your argument.

My idea: There 2 developers: one frontend, and one backend. And some info needs to be collected from the user, via a web form...

Backend person knows what info he needs from a form, so he creates the form, he passes it to the view, and he tells the frontent person to display it and send it back to a given URL with a POST request. So he writes the following in the controller (simplified):

<?php
// the form
$form = new MyForm();
$this->view->form = $form;

// the form was submitted
if($this->request->isPost())  {

    // valid or not
    $is_valid = $form->isValid( $this->request->getPos() );

    // tell the view that is was submitted, valid or not
    $this->view->form_submitted = true;
    $this->view->form_isvalid = $is_valid

    if($is_valid) {
       // save data, send email, etc
    }
}

Frontend person works with the view files, so he displays the form. When the form was submitted, he needs a simple JSON response from the server. So at /app/view/controllername/actionname.phtml file he could write this:

// form response
if($this->form_submitted) {
    if($form_isvalid) echo '{success:true};
    else echo '{success:false'};
    // and stop here, do not display the /app/view/layout/controllername.phtml, nor the /app/view/index.html

// display the form and the entire webpage
} else {
   // display $form here, submitting with AJAX.
   // let the hierarchy go on, so the full page will be displayed
}

And when the frontend person changes the way the form behaves on the frontend, he can implement it by himself. Such as the form will no longer submit with AJAX, but submit "normally" so he does need the full page displayed again when the form was submitted (so he wants all the levels of the hierarchy). Or submit to an <iframe> that will respond with some javascript code and partial HTML.

So idea is that the frontend person doesn't need to write things into the controller. He can just deal with the view, in the view files. And the backend person doesn't need to know anything about the view files. So code for the Controller and View are separated.

(sorry for the double post). Edited my above post to give an example of how I thought it could work.