3
votes

I'm having problem with my Phalcon PHP project. I'm building single module app with multiple MVC directories inside.

Every each module has it's own "views" directory, which contains action templates. (index.volt, show.volt etc.). Layouts are loaded from modules/layout/ and then set with

$this->view->setLayout('index');

in main controller initialize().

That's how it looks like:

    .
    ├── application
    │   └── modules
    │       ├── index
    │       │   ├── ControllerBase.php
    │       │   ├── IndexController.php
    │       │   └── views
    │       │       └── index.volt
    │       ├── layout
    │       │   ├── index.volt
    │       │   └── admin.volt
    │       ├── page
    │       │   ├── Page.php
    │       │   ├── PageAdminController.php
    │       │   ├── PageController.php
    │       │   ├── admin_views
    │       │   │   ├── edit.volt
    │       │   │   └── index.volt
    │       │   └── views
    │       │       └── show.volt
    

This is my view service:

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

    $view = new View();

    $view->setLayoutsDir(APPLICATION_PATH . "/modules/layout/");

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

            $volt = new VoltEngine($view, $di);

            $volt->setOptions(array(
                'compiledPath' => $mainConfig->application->cacheDir,
                'compiledSeparator' => '_'
            ));

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

    return $view;
}, true);

I want to set views directory right in the main controller (ControllerBase.php), beacuse it depends on current controllers name.

For example:

myapp.com => /modules/index/views/index.volt
myapp.com/page/show/2 => /modules/page/views/show.volt

So my question is: How can i set views directory and searching pattern to match my structure?

2
won't that be a lot easier to keep all views in one separate directory tree, as its being created with devtools? - yergo
of course it will. But i'd rather to keep my module files separetely. It mainly depends on my modules policy - jpawlowski

2 Answers

4
votes

Nailed it!

ControllerBase.php

$moduleName = $this->dispatcher->getControllerName();
$actionName = $this->dispatcher->getActionName();

// set view for current Controller and Action
$this->view->setMainView('layout/index');
$this->view->pick($moduleName."/views/".$actionName);

Services.php

$view->setViewsDir(APPLICATION_PATH . "/modules/");

I'm simply picking current view by myself, using View::pick()

1
votes

Not a 100% score answer, because you will have to take your time on this anyway, but your cold start should be something like this:

class ControllerBase extends \Phalcon\Mvc\Controller 
{
    // initialization for all controllers in module
    protected function initialize() {

        $this->view->setViewsDir(
            sprintf('../application/modules/%s/views/', $this->router->getModuleName())
        );
    }

this should make your phalcon seraching for views in modules directory, still its working struture will be something like:

.
├── application
│   └── modules
│       ├── index
│       │   ├── ControllerBase.php
│       │   ├── IndexController.php
│       │   └── views
│       │       └── Index
│       │           └──default.volt

not sure if there is more "global" way, but I kinda feel like there should one exist, most-possibly through exotic View definition in DI().