Can I have multiple view directories, searching for a script name?
Edit:
... and where do we use the _activeRenderPath
?
https://github.com/phalcon/cphalcon/blob/master/ext/mvc/view.c#L997
Edit2: ... and I found an issue.
|
Dec '17 |
7 |
2235 |
0 |
Can I have multiple view directories, searching for a script name?
Edit:
... and where do we use the _activeRenderPath
?
https://github.com/phalcon/cphalcon/blob/master/ext/mvc/view.c#L997
Edit2: ... and I found an issue.
I needed pretty much the same thing. I find the view is pretty restrictive as it forces relative views. I just added a view override in the engineRender: https://github.com/Mech7/Phapp/blob/master/src/Mvc/View.php#L20
Overriding _engineRender
, Phalcon will search for scripts inside the same directory, right?
I need something like this:
$view->setViewsPath('./module/Admin/view');
$view->addVendorViewsPath('./vendor/Auth/view');
... with this structure:
project
|-- module
| |-- Admin
| | |-- view
| | | |-- index.phtml
+-- vendor
| |-- Auth
| | |-- view
| | | |-- users
| | | | |-- index.phtml
Why? Same Admin/view/index.phtml
for all "Admin" resources. Auth namespace registers controllers
$di->set('Admin\Controller\Users', 'Auth\Controller\Users');
... with view action scripts inside vendor Auth namespace.
Am I crazy? XD
Yes this is possible.. in your Module.php do something like:
public function registerServices($di) {
//Registering the view component
if ($di->get('view')) {
$view = $di->get('view');
} else {
$view = new \Phalcon\Mvc\View();
}
$view->setViewsDir(realpath(__DIR__.'/..//view/'));
}
Overriding renderEngine template will look wherever you change it to look for. For me it looks in a template path.
It depends where are your overrides.. my structure is a little different i have something like:
vendor/cept/blog/view
vendor/cept/blog/src/Module.php
So this is my main dir which is set in Module.php by: $view->setViewsDir(realpath(DIR.'/..//view/')); Then my overrides are here:
theme/default/{modulename}/{controllername}/{action}
The override location is set by: $view->setThemePath(getcwd().'/theme/default/');
But you can do the same with an override for your paths :) Still is a shame this is not really possible with some event in the view class
Damn! After one thousand years I understood!
I forgot the "renderLevel"... Let me try! =D
ps: my vim was in case sensitive search --' https://github.com/phalcon/cphalcon/blob/1.3.2/ext/mvc/view.c#L1298
ps2: ... and if we create an event? :)
Analyzing code, we can't use the view:beforeRenderView
event to change the path, 'cause it'll be only triggered if file exists. So, we can't use that in this case.
So, if I override the _engineRender
, arguments can't be defined to keep the structure, following the method definition. So...
<?php
namespace System\Mvc\View;
use Phalcon\Mvc\View as PhalconView;
class View extends PhalconView {
protected function _engineRender() {
$manager = $this->getEventsManager();
if ($manager) {
$manager->fire('view:beforeEngineRender', $this);
}
$result = call_user_func_array('parent::_engineRender', func_get_args());
if ($manager) {
$manager->fire('view:afterEngineRender', $this);
}
return $result;
}
}
... and I registered these callbacks:
$manager = $di->get('eventsManager');
$manager->attach('view:beforeEngineRender', function($event, $component) use ($di){
if (View::LEVEL_ACTION_VIEW == $component->getCurrentRenderLevel()) {
$dispatcher = $di->get('dispatcher');
if ($dispatcher->getModuleName() == 'Admin') {
switch ($dispatcher->getControllerName()) {
case 'users':
$component->setBasePath('./vendor/Auth');
break;
}
}
}
});
$manager->attach('view:afterEngineRender', function($event, $component){
$component->setBasePath('./module/Admin');
});
... AND IT WORKS LIKE A CHARM!
THANK YOU @Mech7!
Hello all.
I have similar problem. I have base project and client project.
client_project src allpication Views vendor base_project src application Views
I need to use teplates from both Views folders.
To solve my problem i have following class:
<?php
namespace Your\namespace;
class View extends \Phalcon\Mvc\View {
protected $pathList = [];
protected $firstDir = null;
public function __construct($options = null) {
parent::__construct($options);
}
public function addPath($path) {
$this->pathList[] = $path;
}
public function setPths($paths) {
$this->pathList = $paths;
}
public function getPaths() {
return $this->pathList;
}
protected function _engineRender($engines, $viewPath, $silence, $mustClean, $cache = null) {
if (null === $this->firstDir) {
$this->firstDir = $this->_viewsDir;
}
$this->_viewsDir = $this->firstDir;
$extentions = array_keys($engines);
foreach ($this->pathList as $path) {
foreach ($extentions as $extention) {
$dir = $this->_basePath.$path.$viewPath.$extention;
if (file_exists($dir)) {
$this->_viewsDir = $path;
break 2;
}
}
}
parent::_engineRender($engines, $viewPath, $silence, $mustClean, $cache);
}
}
Maybe this will help someone other too.
P.S. Sorry for bad layout.