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

setLayoutsDir don't support absolute path

I have found a bug, if I have not committed myself For example in my Module.php

            //This works OK
            $di['view'] = function() {
                $view = new \Phalcon\Mvc\View();
                $view->registerEngines(array(
                    ".volt" => 'Phalcon\Mvc\View\Engine\Volt'
                ));
                $view->setViewsDir(__DIR__ . '/views/');
                $view->setLayoutsDir('../../../layouts');
                $view->setTemplateAfter('main');

                return $view;
            };

//but if the path is absolute, doesn't work
//APPLICATION_PATH = /real/path/to/my/app
$view->setLayoutsDir(APPLICATION_PATH  . '/../../layouts');

Am I wrong? or this is a issue?



58.4k

If you path is absolute so you dont used relatively, for example above should look like

    $view->setLayoutsDir(APPLICATION_PATH  . 'youapp/views/layouts');


10.5k
Accepted
answer

According to the official documentation:

Sets the layouts sub-directory. Must be a directory under the views directory. Depending of your platform, always add a trailing slash or backslash

So always you shoud use a relative path based on your views directory.



1.1k
edited Jun '15

If you are using a symlink in the application and you need define method setViewsDir to the symlinks directory and the layout in another directory outside the symlink directory, you must use absolute path.

Here is my solution:

$di->set('view', function() {
    $view = new MyView();
    return $view;
});

class MyView extends \Phalcon\Mvc\View {

    protected function _engineRender($engines, $viewPath, $silence, $mustClean, \Phalcon\Cache\BackendInterface $cache = null) {        
        $dirname = dirname($viewPath);
        $path = realpath($dirname);

        if($path !== false && $dirname != '.' && $dirname != '..') {
            $repeat = (count(explode('/', $this->getActiveRenderPath()))-3);
            $viewPathArr = explode('/', $viewPath);
            $viewPathArrSlice = array_slice($viewPathArr, 1, -1);
            $viewPath = str_repeat('../', $repeat) . implode('/', $viewPathArrSlice) . '/' . basename($viewPath);
        }

        parent::_engineRender($engines, $viewPath, $silence, $mustClean, $cache = null);
    }

}

And then you can write absolute path to the method setLayoutsDir:

$view->setLayoutsDir('/var/www/web/app/views/layoutDir/');