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.

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();
                    ".volt" => 'Phalcon\Mvc\View\Engine\Volt'
                $view->setViewsDir(__DIR__ . '/views/');

                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?


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

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


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.

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: