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

Controllers, Views and Routing

Hello,

I am trying to extend the tutorial by adding new controllers and routes.

I am adding a rounter by using the Dependency Injection container like this:

$router = new Phalcon\Mvc\Router();

$router->add(
    '/',
    array(
        'controller' => 'Index',
        'action'     => 'index',
    )
);

$router->add(
    "/request",
    array(
        'controller' => 'Request',
        'action' => 'list',
        'year' => 1
    )
);

And then add it like this:

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

I have created all the required dependencies (IndexController.php and RequestController.php with indexAction and listAction functions respectively, /views/index/index.phtml and /views/request/list.phtml).

Now, the behavior I see is this:

Router added:

  • routes are used correctly, however I can only output from whithin controller action. Empty action = no output (no errors also), as if there were no views connected.

Router not added (comment out the set router line):

  • views are rendered to the browser normally

Is there something I'm doing wrong? Do I need to set the views folders elsewhere aside from the way set in the tutorial? Eg:

$di->set('view', function(){
    $view = new \Phalcon\Mvc\View();
    $view->setViewsDir('../app/views/');
    return $view;
});

Thanks!



11.2k

On the router config you should try to use the setDefaultAction like $router->setDefaultAction('index'); that way when no action is set, it tries to use the default action

Hi heptagono,

Thanks for taking the time to reviw my problem and make the suggestion. I've added the setDefaultAction('index') on the router and it does work when I try routers that I haven't specified in the router.

However, the issue remains for the routers that I have defined. For the "Request" controller, for example, if I use a path like /request/list then the controller fires the listAction and the 'list' view is rendered.

However, if I only use a path like /request, the controller still fires the listAction (even through I haven't sent an action through the path) but no view is rendered.

As mentioned before, if I completely remove the router and specify controller and action via URL, all is good. However, I do need the router as I plan to allow a finite set of operations on very specific URLs rather than allow access to any router and any action as long as the user knows the proper paths.

Thanks



11.2k
edited Sep '14
$router->add(
    "/request",
    array(
        'controller' => 'Request',
        'action' => 'list',
        'year' => 1
    )
);

This line means "if user tries to access /request, take him to RequestController::listAction(); and set the following variable $this->dispatcher->year = 1

The default router also does the following: If no route is found, get the url and try to access it as the folowing: /Controller/Action/Params. So, if /Request/list is not set at the router, it will try to execute RequestController::listAction();

If you want to disable this default route, when configuring the router, set the creation param to false like this:

$router = new Router(false);

This way it will only allow the user to access the routes defined at the router configuration. Hope this helps you

edited Sep '14

Hi heptagono,

I don't thing the issue I'm having is very clear.

I have no problem with the default routing. It works ok and that's great.

The problem is that when it does go with the route I configured, the associated view is not rendered. It's like using the router somehow disables the views.

in the case when the default route is active then the following paths should do the same

expected result:

/request => calls RequestController::listAction(); (and renders the 'list' view - as far as I understood from the docs)

/request/list => calls RequestController::listAction(); (and renders the 'list' view)

actual result:

/request => calls RequestController::listAction(); (but DOES NOT render the 'list' view)

/request/list => calls RequestController::listAction(); (and DOES render the 'list' view)

why in the first case it doesn't render the view and in the second (when I call the default route) it does?



11.2k

But it doesnt output any error message ? This is an unexpected behavior. As the View service gets from the Dispatcher the info on which template to render ( and the dispatcher gets that info from the Router ).

So, my simplest guess is the following: Your route IS NOT working. You probably hasn't included it properly in the DI.

To prove it, do the following : create a template for the indexAction of the RequestController and try to access /request if it shows you the template that you just created ( probably index.phtml ) it means that you didn't added the route the right way. So i would have to take a look at your DI and Routes file

Hi,

Indeed, it does seem that something isn't working related to that route. However, like I said, if I output something in the controller action it does show it. For example:

class RequestController extends \Phalcon\Mvc\Controller
{
    public function listAction()
    {
        echo "Test output";
    }
}

It outputs "Test output" when I use the /request route. So it finds the correct controller and the action (listAction) configured in the router and there are no errors. If I remove the echo, then there's no output at all.

As far as how the router is included, it's like this:

$di->set('router', $router);
$application = new \Phalcon\Mvc\Application($di);
echo $application->handle()->getContent();

So I'm not sure: is there something else I need to do when including the router in the DI ? Or is there something else to do when using the DI ?

Thanks!

Finally figured it out.

Controller name *must be* lower case!

Which is strange, mainly because even in uppercase it does fire up the action, just doesn't go further to the view.