Phalcon backup view path

南楼画角 提交于 2019-12-10 11:34:52

问题


Is there any way to pass through a secondary path to the views dir in phalcon?

in zend framework I think the syntax is

$this->view->addScriptPath('/backup/path');
$this->view->addScriptPath('/preferred/path');

so if there is a file in the preferred path it will use it, if not it will fallback through the chain.

I use this, for example, for mobile versions when most of the pages are the same, but some have to be significantly different and I don't want to have to duplicate all the views just for 2 or 3 variants

In phalcon I have tried sending an array to the view, but that just results in neither working

$di->set('view', function() use ($config) {
    $view = new \Phalcon\Mvc\View();
    $view->setViewsDir( array('/preferred/path/', '/backup/path/') );
    return $view;
});

回答1:


I've got this working by extending the Phalcon\Mvc\View\Engine\Volt

In the render($template_path, $params, $must_clean = null) method I set the alternative path, check if file is available and if so I switch the $template_path given with the alternative path. Then it's just a case of calling:

return parent::render($template_path, $params, $must_clean);

where $template_path contains the new (alternative) path.

If your alternative path might change on a per project basis and you need to set it in bootstrap, then rather than doing it when getting a "view" from di you would do it when getting volt.

Just remember that all views are rendered with that method so you will have to account for layout and partial views as well - depending on your implementation.

Example: (this has not been tested, it's based on a similar set up I have in my own code)

<?php

class Volt extends Phalcon\Mvc\View\Engine\Volt
{
    private $skin_path;

    public function render($template_path, $params, $must_clean = null)
    {

        $skin_template = str_replace(
            $this->di->getView()->getViewsDir(),
            $this->getSkinPath(),
            $template_path
        );

        if (is_readable($skin_template)) {
            $template_path = $skin_template;
        }

        return parent::render($template_path, $params, $must_clean);
    }

    public function setSkinPath($data)
    {
        $this->skin_path = $data;
    }

    public function getSkinPath()
    {
        return $this->skin_path;
    }
}

In your bootstrap:

$di->setShared('volt', function($view, $di) {

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

    $volt->setSkinPath('my/alternative/dir/');

    return $volt;
});

Many thanks to nickolasgregory@github who pointed me in the right direction.




回答2:


Method proposed by @strayobject helps me also, but I've found that using extend or other statements inside volt templates dosn't work.

Here's refined solution that works with extend and include:

use Phalcon\Mvc\View\Engine\Volt;

class VoltExtension extends Volt
{
    // Override default Volt getCompiler method
    public function getCompiler()
    {
        if (!$this->_compiler) {
            $this->_compiler = new VoltCompilerExtension($this->getView());
            $this->_compiler->setOptions($this->getOptions());
            $this->_compiler->setDI($this->getDI());
        }
        return $this->_compiler;
    }
}

And

use Phalcon\Mvc\View\Engine\Volt;

class VoltCompilerExtension extends Volt\Compiler
{
    public function compileFile($path, $compiledPath, $extendsMode = null)
    {
        $skinPath = $this->getOption('skinPath');
        if ($skinPath) {
            $skinTemplate = str_replace(
                $this->getDI()->getView()->getViewsDir(),
                $skinPath,
                $path
            );

            if (is_readable($skinTemplate)) {
                $path = $skinTemplate;
            }
        }

        return parent::compileFile($path, $compiledPath, $extendsMode);
    }

}

Usage:

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



回答3:


Please take a look at this phalcon framework update. It provides support for multiple view packages per website (you can have multiple websites). Users of the magento framework will find it easy to use:

https://github.com/alanbarber111/cloud-phalcon-skeleton



来源:https://stackoverflow.com/questions/17087693/phalcon-backup-view-path

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!