diff --git a/ice/mvc/app.zep b/ice/mvc/app.zep index 59239d98..a58b365b 100644 --- a/ice/mvc/app.zep +++ b/ice/mvc/app.zep @@ -100,15 +100,14 @@ class App extends Access view->setSilent(true); view->setFile(dispatcher->getHandler() . "/" . dispatcher->getAction()); } - if !view->count() { + if dispatcher->getParams() { view->replace(dispatcher->getParams()); } - - view->setContent(view->render()); + view->render(); } // if there is main layout view, other case e.g. load partial view through ajax if view->getMainView() { - response->setBody(view->layout(view->getMainView())); + response->setBody(view->layout()); } else { response->setBody(view->getContent()); } diff --git a/ice/mvc/router.zep b/ice/mvc/router.zep index 2aaaf9c9..49c24f63 100644 --- a/ice/mvc/router.zep +++ b/ice/mvc/router.zep @@ -279,13 +279,13 @@ class Router */ public function match(string uri = null, string method = null) { - var name, route, params, matches; + var route, params, matches; // Remove trailing slashes from the URI let uri = uri == "/" ? "/" : rtrim(uri, "/"), matches = null; - for name, route in this->routes { + for route in this->routes { let params = route->matches(uri, method); if !empty params { return route; @@ -311,9 +311,9 @@ class Router */ public function uri(array! params, string method = "*") { - var name, route, uri; + var route, uri; - for name, route in this->routes { + for route in this->routes { let uri = route->uri(params); if uri !== false && route->checkMethod(method) { return uri; diff --git a/ice/mvc/view.zep b/ice/mvc/view.zep index c1a639af..6b9fb1b6 100644 --- a/ice/mvc/view.zep +++ b/ice/mvc/view.zep @@ -18,12 +18,12 @@ use Ice\Mvc\View\ViewInterface; class View extends Arr implements ViewInterface { - protected engines { set }; + protected engines; protected content { set, get }; - protected mainView = "index" { set, get }; - protected layoutsDir = "layouts/" { set, get }; - protected partialsDir = "partials/" { set, get }; - protected viewsDir { set, get }; + protected mainView { set, get }; + protected layoutsDir = "layouts/" { get }; + protected partialsDir = "partials/" { get }; + protected viewsDir = []; protected file { set, get }; protected silent = false { set }; @@ -46,26 +46,147 @@ class View extends Arr implements ViewInterface */ public function getEngines() { - var ext, engine; - if !this->engines { let this->engines[".phtml"] = new Php(this); - } else { - for ext, engine in this->engines { - if typeof engine == "object" { - if engine instanceof \Closure { - let this->engines[ext] = call_user_func_array(engine, [this]); - } - } else { - if typeof engine == "string" { - let this->engines[ext] = create_instance_params(engine, [this]); - } else { - throw new Exception(sprintf("Invalid template engine registration for '%s' extension", ext)); - } + } + + return this->engines; + } + + /** + * Registered engines. + * + * @param array engines + * @return object View + */ + public function setEngines(array engines) + { + var ext, engine; + + for ext, engine in engines { + if typeof engine == "object" { + if (engine instanceof \Closure) { + let this->engines[ext] = {engine}(this); + } elseif engine instanceof EngineInterface { + let this->engines[ext] = engine; } + } elseif is_string(engine) && class_exists(engine) { + let this->engines[ext] = new {engine}(this); + } + if !isset this->engines[ext] { + throw new Exception(sprintf("Invalid template engine registration for '%s' extension", ext)); } } - return this->engines; + + return this; + } + + /** + * Set the layouts dir`locate in the view dirs. + * + * @param string dirs + * @return object View + */ + public function setLayoutsDir(string dirs) + { + let dirs = trim(dirs, "/\\"); + if dirs { + let dirs .= DIRECTORY_SEPARATOR; + } + + let this->layoutsDir = dirs; + + return this; + } + + /** + * Set the partials dir`locate in the view dirs. + * + * @param string dirs + * @return object View + */ + public function setPartialsDir(string dirs) + { + let dirs = trim(dirs, "/\\"); + if dirs { + let dirs .= DIRECTORY_SEPARATOR; + } + + let this->partialsDir = dirs; + + return this; + } + + /** + * Get view directory. + * + * @return object View + */ + public function getViewsDir() + { + return count(this->viewsDir) < 2 ? current(this->viewsDir) : this->viewsDir; + } + + /** + * Set view directory. + * + * @param array vars + * @return object View + */ + public function setViewsDir(dirs) + { + var k, dir, path; + + if (is_string(dirs)) { + let dirs = [dirs]; + } + + for k, dir in dirs { + let path = realpath(dir); + if path { + let dirs[k] = path . DIRECTORY_SEPARATOR; + } else { + throw new Exception(sprintf("The view dir '%s' could not be found", dir)); + } + } + + let this->viewsDir = dirs; + + return this; + } + + /** + * Add view directory. + * + * @param mixed dir View directory or directories + * @param boolean prepend Prepend to the current views dir + * @return object View + */ + public function addViewsDir(dirs, bool prepend = false) + { + var k, dir, path; + + if (is_string(dirs)) { + let dirs = [dirs]; + } + + for k, dir in dirs { + let path = realpath(dir); + if path { + let dirs[k] = path . DIRECTORY_SEPARATOR; + } else { + throw new Exception(sprintf("The view dir '%s' could not be found", dir)); + } + } + + if (prepend) { + let dirs = array_merge(dirs, this->viewsDir); + } else { + let dirs = array_merge(this->viewsDir, dirs); + } + let this->viewsDir = array_unique(dirs); + + return this; } /** @@ -77,39 +198,30 @@ class View extends Arr implements ViewInterface */ public function render(file = null, array data = []) { - var ext, engine, engines, path, dir, dirs, exists, content; - - let exists = false, - content = null; + var ext, engine, engines, path, dir, dirs, exists; if file !== null { - let this->file = file; + let this->file = trim(file, "/\\"); } if empty this->file { throw new Exception("You must set the file to use within your view before rendering"); } - let engines = this->getEngines(); - - if typeof this->viewsDir == "array" { - let dirs = this->viewsDir; - } else { - let dirs = [this->viewsDir]; - } - - let ext = pathinfo(this->file, PATHINFO_EXTENSION); + let this->content = "", + exists = false, + dirs = this->viewsDir, + engines = this->getEngines(), + ext = pathinfo(file, PATHINFO_EXTENSION); - if !empty ext { - if fetch engine, engines["." . ext] { - for dir in dirs { - let path = dir . this->file; - if file_exists(path) { - let exists = true; + if !empty ext && fetch engine, engines["." . ext] { + for dir in dirs { + let path = dir . this->file; + if file_exists(path) { this->replace(data); - let content = engine->render(path, this->all()); - break; - } + let exists = true, + this->content = engine->render(path, this->all()); + break; } } } else { @@ -117,9 +229,9 @@ class View extends Arr implements ViewInterface for dir in dirs { let path = dir . this->file . ext; if file_exists(path) { - let exists = true; this->replace(data); - let content = engine->render(path, this->all()); + let exists = true, + this->content = engine->render(path, this->all()); break; } } @@ -133,7 +245,8 @@ class View extends Arr implements ViewInterface if !this->silent && !exists { throw new Exception(sprintf("The requested view %s could not be found", path)); } - return content; + + return this->content; } /** diff --git a/ice/tag.zep b/ice/tag.zep index 4f9ae3b5..cdb080bc 100644 --- a/ice/tag.zep +++ b/ice/tag.zep @@ -695,16 +695,13 @@ class Tag if is_numeric(key) { if fetch value, params[key] { let attributes[param] = value; + unset params[key]; } } else { let attributes[param] = key; } } - for key in defaultParams { - unset params[key]; - } - let attributes = array_merge(attributes, params), code = this->prepareTag(name, attributes, skip, single);