Call action of controller in volt

hi all, how to call an action in Volt

Generally, Controller actions are only called when a new request is made by the user.

Views, which is where you use Volt, should only be concerned with displaying information to the user.

Have a read through this documentation page for clarity http://docs.phalconphp.com/en/latest/reference/mvc.html

If you post details of what you're trying to achieve, I may be able to give you more help.

Call controller method in view - is wrong. I don't know what you need exactly but i think you need look at helpers (http://docs.phalconphp.com/en/latest/reference/tags.html#view-helpers). Just create one with your logic and call from view.

edited Apr '14

Im in a similar situation.

I have the ControllerBase where I have a function that tells me wether I'm logged in or not, and I'm changing the header in index.volt depending on that condition, so I'm calling from the volt the controller function like this:

<!-- index.volt -->
... some html code in the <header> section
<?php 
if(ControllerBase::_isLoggedIn()){ 
?>
    THE HTML IF IM LOGGED IN
<?php
}else{
?>
    THE HTML IF IM NOT LOGGED IN
<?php
}
?>
... some other html code in the <header> section

So, if it's wrong to call ControllerBase from the view, how else can I achieve that?



1.2k

On the services.php, I use this one:

$di->set('view', function () use ($config) {

    $view = new View();

    $view->setViewsDir($config->application->viewsDir);

    $view->registerEngines(array(
        '.volt'  => function ($view, $di) use ($config) {

                $volt = new VoltEngine($view, $di);
                $volt->setOptions(array(
                    'compiledPath'      => $config->application->cacheDir,
                    'compiledSeparator' => '_'
                ));

                $compiler = $volt->getCompiler();

                $compiler->addFunction('logged_in', function ($resolvedArgs, $expArgs) {
                    return '!empty($this->session->auth)';
                });

                $compiler->addFunction('username', function ($resolvedArgs, $expArgs) {
                   return '$this->session->auth["name"]';
                });

                return $volt;
            },
        '.phtml' => 'Phalcon\Mvc\View\Engine\Php'
    ));

    return $view;
}, true);

On views, I can use:

{% if logged_in() %}
    Hello {{ username() }}
{% else %}  
    Something else
{% endif %}

@iman38 I just tried that and It worked like a charm! Thanks a lot! But, yesterday I was taking a look at the INVO example in the phalcon documentation, and there it says the "correct" way to do it is by using Elements.

Take a look at here: http://docs.phalconphp.com/en/latest/reference/tutorial-invo.html#user-components

It says:

"All the UI elements and visual style of the application has been achieved mostly through Bootstrap. Some elements, such as the navigation bar changes according to the state of the application. For example, in the upper right corner, the link “Log in / Sign Up” changes to “Log out” if an user is logged into the application. This part of the application is implemented in the component “Elements” (app/library/Elements.php)."

So, I'm wondering if the way you suggest is the recommended or right way to achieve it.

Thanks a lot again for the answer.



1.2k

Generally, I would extend volt engine to suit my needs. In many cases, I work directly with designer guys who are not so happy with cluttering php statements accross the view files (It's just personal taste, but I love those clean volt templates rather than mixing php statements on views--as long as I can avoid them).

On my previous example, I showed you that I need to access some values held by some services (in that case, the session) injected on the DI. So, I simply add functions to the volt compiler for those trivial functionalities.

On other cases, I have some dynamic (html) elements / block of elements. And yes, I extended the Component class and create my own Tag class (extending the \Phalcon\Tag) to suit my needs (and again, create volt functions to make my views cleaner).

I'm not sure that this would be the most recommended way on phalcon. However, I don't see it break any MVC concepts. -cmiiw

Btw, sorry to the OP if my comments being way out of topic.

Cheers,



1.5k
edited Feb '15

I am not sure I agree about calling controller in view :

What if you have some dynamic content you want to reuse at several place ?

For me I have a form that I have rendered in a given place which requires a controller to bind model data to the form. But now I also want to render it elsewhere.

What I tried to is put in my view :

{{ view.render('mycontroller', 'myaction') }}

but it only render the view, it does not go through the controller action so my view variables are not set !

Does someone know how I can render this nice controller ?

edit : Maybe something can be done thanks to controller forwarding ?

Thanks