From 8906a63e8ea96a59ec404e8de17a244090b8ae09 Mon Sep 17 00:00:00 2001 From: Jeremy Bush Date: Tue, 23 Oct 2012 18:17:02 -0500 Subject: [PATCH 01/12] Switch to mustache v2, not done --- .gitignore | 1 + classes/Kohana/Kostache.php | 264 ++--------------------------- classes/Mustache/Loader/Kohana.php | 33 ++++ init.php | 3 +- vendor/mustache | 2 +- 5 files changed, 48 insertions(+), 255 deletions(-) create mode 100644 .gitignore create mode 100644 classes/Mustache/Loader/Kohana.php diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..1377554 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +*.swp diff --git a/classes/Kohana/Kostache.php b/classes/Kohana/Kostache.php index cc35b7f..100ea70 100644 --- a/classes/Kohana/Kostache.php +++ b/classes/Kohana/Kostache.php @@ -12,260 +12,18 @@ */ abstract class Kohana_Kostache { - const VERSION = '3.0.0'; + const VERSION = '4.0.0'; - /** - * Factory method for Kostache views. Accepts a template path and an - * optional array of partial paths. - * - * @param string template path - * @param array partial paths - * @return Kostache - * @throws Kohana_Exception if the view class does not exist - */ - public static function factory($path, array $partials = NULL) + public static function engine() { - $class = 'View_'.str_replace('/', '_', $path); - - if ( ! class_exists($class)) - { - throw new Kohana_Exception('View class does not exist: :class', array( - ':class' => $class, - )); - } - - return new $class(NULL, $partials); + $m = new Mustache_Engine( + array( + 'loader' => new Mustache_Loader_Kohana(), + 'partials_loader' => new Mustache_Loader_Kohana('templates/partials'), + 'escape' => function($value) { + return html::chars($value); + }, + ) + ); } - - /** - * @var string Mustache template - */ - protected $_template; - - /** - * @var array Mustache partials - */ - protected $_partials = array(); - - /** - * Loads the template and partial paths. - * - * @param string template path - * @param array partial paths - * @return void - * @uses Kostache::template - * @uses Kostache::partial - */ - public function __construct($template = NULL, array $partials = NULL) - { - if ( ! $template) - { - if ($this->_template) - { - // Load the template defined in the view - $template = $this->_template; - } - else - { - // Detect the template for this class - $template = $this->_detect_template(); - } - } - - // Load the template - $this->template($template); - - if ($this->_partials) - { - foreach ($this->_partials as $name => $path) - { - // Load the partials defined in the view - $this->partial($name, $path); - } - } - - if ($partials) - { - foreach ($partials as $name => $path) - { - // Load the partial - $this->partial($name, $path); - } - } - } - - /** - * Magic method, returns the output of [Kostache::render]. - * - * @return string - * @uses Kostache::render - */ - public function __toString() - { - try - { - return $this->render(); - } - catch (Exception $e) - { - ob_start(); - - // Render the exception - Kohana_Exception::handler($e); - - return (string) ob_get_clean(); - } - } - - /** - * Loads a new template from a path. - * - * @return Kostache - */ - public function template($path) - { - $this->_template = $this->_load($path); - - return $this; - } - - /** - * Loads a new partial from a path. If the path is empty, the partial will - * be removed. - * - * @param string partial name - * @param mixed partial path, FALSE to remove the partial - * @return Kostache - */ - public function partial($name, $path) - { - if ( ! $path) - { - unset($this->_partials[$name]); - } - else - { - $this->_partials[$name] = $this->_load($path); - } - - return $this; - } - - /** - * Assigns a variable by name. - * - * // This value can be accessed as {{foo}} within the template - * $view->set('foo', 'my value'); - * - * You can also use an array to set several values at once: - * - * // Create the values {{food}} and {{beverage}} in the template - * $view->set(array('food' => 'bread', 'beverage' => 'water')); - * - * @param string variable name or an array of variables - * @param mixed value - * @return $this - */ - public function set($key, $value = NULL) - { - if (is_array($key)) - { - foreach ($key as $name => $value) - { - $this->{$name} = $value; - } - } - else - { - $this->{$key} = $value; - } - - return $this; - } - - /** - * Assigns a value by reference. The benefit of binding is that values can - * be altered without re-setting them. It is also possible to bind variables - * before they have values. Assigned values will be available as a - * variable within the template file: - * - * // This reference can be accessed as {{ref}} within the template - * $view->bind('ref', $bar); - * - * @param string variable name - * @param mixed referenced variable - * @return $this - */ - public function bind($key, & $value) - { - $this->{$key} =& $value; - - return $this; - } - - /** - * Renders the template using the current view. - * - * @return string - */ - public function render() - { - return $this->_stash($this->_template, $this, $this->_partials)->render(); - } - - /** - * Return a new Mustache for the given template, view, and partials. - * - * @param string template - * @param Kostache view object - * @param array partial templates - * @return Mustache - */ - protected function _stash($template, Kostache $view, array $partials) - { - return new Kohana_Mustache($template, $view, $partials, array( - 'charset' => Kohana::$charset, - )); - } - - /** - * Load a template and return it. - * - * @param string template path - * @return string - * @throws Kohana_Exception if the template does not exist - */ - protected function _load($path) - { - $file = Kohana::find_file('templates', $path, 'mustache'); - - if ( ! $file) - { - throw new Kohana_Exception('Template file does not exist: :path', array( - ':path' => 'templates/'.$path, - )); - } - - return file_get_contents($file); - } - - /** - * Detect the template name from the class name. - * - * @return string - */ - protected function _detect_template() - { - // Start creating the template path from the class name - $template = explode('_', get_class($this)); - - // Remove "View" prefix - array_shift($template); - - // Convert name parts into a path - $template = strtolower(implode('/', $template)); - - return $template; - } - } diff --git a/classes/Mustache/Loader/Kohana.php b/classes/Mustache/Loader/Kohana.php new file mode 100644 index 0000000..05649bb --- /dev/null +++ b/classes/Mustache/Loader/Kohana.php @@ -0,0 +1,33 @@ +_base_dir = $base_dir; + + if (isset($options['extension'])) + { + $this->_extension = '.' . ltrim($options['extension'], '.'); + } + } + + public function load($name) + { + if (!isset($this->_templates[$name])) + { + $this->_templates[$name] = $this->_load_file($name); + } + + return $this->_templates[$name]; + } + + protected function load_file($name) + { + $filename = Kohana::find_file($this->_base_dir, $name, $this->_extension); + } +} diff --git a/init.php b/init.php index 22b0b8b..b6a24da 100644 --- a/init.php +++ b/init.php @@ -1,4 +1,5 @@ Date: Tue, 23 Oct 2012 22:22:15 -0500 Subject: [PATCH 02/12] Get loading working --- classes/Kohana/Kostache.php | 4 +++- classes/Mustache/Loader/Kohana.php | 10 ++++++---- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/classes/Kohana/Kostache.php b/classes/Kohana/Kostache.php index 100ea70..42638a7 100644 --- a/classes/Kohana/Kostache.php +++ b/classes/Kohana/Kostache.php @@ -14,7 +14,7 @@ abstract class Kohana_Kostache { const VERSION = '4.0.0'; - public static function engine() + public static function engine($template_name) { $m = new Mustache_Engine( array( @@ -25,5 +25,7 @@ abstract class Kohana_Kostache { }, ) ); + + return $m->loadTemplate($template_name); } } diff --git a/classes/Mustache/Loader/Kohana.php b/classes/Mustache/Loader/Kohana.php index 05649bb..ec23cab 100644 --- a/classes/Mustache/Loader/Kohana.php +++ b/classes/Mustache/Loader/Kohana.php @@ -3,12 +3,13 @@ class Mustache_Loader_Kohana implements Mustache_Loader { private $_base_dir = 'templates'; - private $_extension = '.mustache'; + private $_extension = 'mustache'; private $_templates = array(); - public function construct($base_dir = NULL, $options = array()) + public function __construct($base_dir = NULL, $options = array()) { - $this->_base_dir = $base_dir; + if ($base_dir) + $this->_base_dir = $base_dir; if (isset($options['extension'])) { @@ -26,8 +27,9 @@ class Mustache_Loader_Kohana implements Mustache_Loader return $this->_templates[$name]; } - protected function load_file($name) + protected function _load_file($name) { $filename = Kohana::find_file($this->_base_dir, $name, $this->_extension); + return file_get_contents($filename); } } From d01a2b3ff567c9d4e246ee7faa19e101af64ea93 Mon Sep 17 00:00:00 2001 From: Jeremy Bush Date: Tue, 23 Oct 2012 22:30:33 -0500 Subject: [PATCH 03/12] Update readme for new current usage --- README.markdown | 157 +++++++++--------------------------------------- 1 file changed, 30 insertions(+), 127 deletions(-) diff --git a/README.markdown b/README.markdown index 4b5a9e9..0bc0e99 100644 --- a/README.markdown +++ b/README.markdown @@ -2,147 +2,50 @@ Kostache is a [Kohana 3](https://github.com/kohana/kohana) module for using [Mustache](http://defunkt.github.com/mustache/) templates in your application. -Mustache is a logic-less template class. It is impossible to embed logic into mustache files. +## Usage -## Example +To use, simply create a POPO (Plain Old PHP Object) like so: -Did you know the pagination view in Kohana is terrible? We are going to fix it: +```php + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

- -Wow, look at all that logic in there! How do you plan on effectively maintaining that?!? - -### Our new View Class (classes/view/pagination/basic.php) - - pagination->first_page !== FALSE) ? $this->pagination->url($this->pagination->first_page) : FALSE; - $items[] = $first; - - // Prev. - $prev['title'] = 'prev'; - $prev['name'] = __('previous'); - $prev['url'] = ($this->pagination->previous_page !== FALSE) ? $this->pagination->url($this->pagination->previous_page) : FALSE; - $items[] = $prev; - - // Numbers. - for ($i=1; $i<=$this->pagination->total_pages; $i++) - { - $item = array(); - - $item['num'] = TRUE; - $item['name'] = $i; - $item['url'] = ($i != $this->pagination->current_page) ? $this->pagination->url($i) : FALSE; - - $items[] = $item; - } - - // Next. - $next['title'] = 'next'; - $next['name'] = __('next'); - $next['url'] = ($this->pagination->next_page !== FALSE) ? $this->pagination->url($this->pagination->next_page) : FALSE; - $items[] = $next; - - // Last. - $last['title'] = 'last'; - $last['name'] = __('last'); - $last['url'] = ($this->pagination->last_page !== FALSE) ? $this->pagination->url($this->pagination->last_page) : FALSE; - $items[] = $last; - - return $items; - } + public function testing() + { + return 'foobar'; } +} +``` -Yum, logic in a class, where it belongs :) +And create a mustache renderer. The parameter to the engine method is the template name to use. -### Our mustache template (templates/pagination/basic.mustache) +```php + - {{#items}} - {{#url}}{{/url}} - {{#num}}{{/num}}{{name}}{{#num}}{{/num}} - {{#url}}{{/url}} - {{/items}} -

+$renderer = Kohana_Kostache::engine('test'); +``` -Holy cow, that's more maintainable :) +And render it: + +```php +response->body($renderer->render(new View_Test)); +``` + +## Templates + +Templates should go in the `templates/` directory in your cascading file system. They should have a .mustache extension. ## Partials -To use a partial in your template you use the greater than sign (>) and the name, e.g. {{>header}}. - -You must define partials within the $_partials array in your view class. The key is the name that you use in your template and the value is a path to your partial file. - - protected $_partials = array( - 'header' => 'header', // Loads templates/header.mustache - 'footer' => 'footer/default', // Loads templates/footer/default.mustache - ); - -## Using the Kostache_Layout class - -Kostache comes with a Kostache_Layout class instead of a template controller. This allows your layouts to be more OOP and self contained, and they do not rely on your controllers so much. - -To use it, have your view extend the Kostache_Layout class. You can then specify your own layout file by placing it in templates/layout.mustache. At a minimum, it needs to have a {{>content}} partial defined in it. - -If you have a view that extends the Kostache_Layout class, but wish to render only the template and not the entire layout, you can set the public $render_layout property to FALSE. This is useful if you want to use the same view class for external requests and HMVC requests. - - $view = new View_Post_List; - if ($this->request !== Request::instance) // Is internal request - { - $view->render_layout = FALSE; - } +Partials are loaded automatically based on the name used in the template. So if you reference `{{>foobar}}` in your template, it will look for that partial in `templates/partials/foobar.mustache`. For specific usage and documentation, see: [PHP Mustache](http://github.com/bobthecow/mustache.php) -[Original Mustache](http://defunkt.github.com/mustache/) \ No newline at end of file +[Original Mustache](http://defunkt.github.com/mustache/) From b6e1c6e7d8d309c44802e6e48258e9dd0dfdca41 Mon Sep 17 00:00:00 2001 From: Jeremy Bush Date: Tue, 23 Oct 2012 22:46:59 -0500 Subject: [PATCH 04/12] Refactor main class to not require template explicitly --- classes/Kohana/Kostache.php | 25 ++++++++++++++++++++++--- classes/Kostache.php | 2 +- 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/classes/Kohana/Kostache.php b/classes/Kohana/Kostache.php index 42638a7..47b952b 100644 --- a/classes/Kohana/Kostache.php +++ b/classes/Kohana/Kostache.php @@ -10,11 +10,13 @@ * @copyright (c) 2011-2012 Woody Gilk * @license MIT */ -abstract class Kohana_Kostache { +class Kohana_Kostache { const VERSION = '4.0.0'; - public static function engine($template_name) + protected $_engine; + + public static function factory() { $m = new Mustache_Engine( array( @@ -26,6 +28,23 @@ abstract class Kohana_Kostache { ) ); - return $m->loadTemplate($template_name); + return new self($m); + } + + public function __construct($engine) + { + $this->_engine = $engine; + } + + public function render($class, $template = NULL) + { + if ($template == NULL) + { + $template = explode('_', get_class($class)); + array_shift($template); + $template = implode('/', $template); + } + + return $this->_engine->loadTemplate($template)->render($class); } } diff --git a/classes/Kostache.php b/classes/Kostache.php index 9566dc3..2595419 100644 --- a/classes/Kostache.php +++ b/classes/Kostache.php @@ -1,3 +1,3 @@ Date: Tue, 23 Oct 2012 22:54:19 -0500 Subject: [PATCH 05/12] Update readme for new api --- README.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.markdown b/README.markdown index 0bc0e99..6b8dcc8 100644 --- a/README.markdown +++ b/README.markdown @@ -25,7 +25,7 @@ And create a mustache renderer. The parameter to the engine method is the templa ```php Date: Wed, 24 Oct 2012 17:32:44 -0500 Subject: [PATCH 06/12] Add caching support --- classes/Kohana/Kostache.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/classes/Kohana/Kostache.php b/classes/Kohana/Kostache.php index 47b952b..41f7cee 100644 --- a/classes/Kohana/Kostache.php +++ b/classes/Kohana/Kostache.php @@ -16,7 +16,7 @@ class Kohana_Kostache { protected $_engine; - public static function factory() + public static function factory($cache = FALSE) { $m = new Mustache_Engine( array( @@ -25,6 +25,7 @@ class Kohana_Kostache { 'escape' => function($value) { return html::chars($value); }, + 'cache' => $cache ? APPPATH.'cache/mustache' : NULL, ) ); From b61870b8112a1553698bf5eefc5a616122a8f01d Mon Sep 17 00:00:00 2001 From: Jeremy Bush Date: Wed, 31 Oct 2012 20:35:08 -0500 Subject: [PATCH 07/12] Add Kostache_Layout class --- classes/Kohana/Kostache.php | 5 ++--- classes/Kohana/Kostache/Layout.php | 18 ++++++++---------- classes/Kostache/Layout.php | 2 +- classes/Mustache/Loader/Kohana.php | 23 ++++++++++++++++++++++- 4 files changed, 33 insertions(+), 15 deletions(-) diff --git a/classes/Kohana/Kostache.php b/classes/Kohana/Kostache.php index 41f7cee..dba10d9 100644 --- a/classes/Kohana/Kostache.php +++ b/classes/Kohana/Kostache.php @@ -5,9 +5,7 @@ * @package Kostache * @category Base * @author Jeremy Bush - * @author Woody Gilk * @copyright (c) 2010-2012 Jeremy Bush - * @copyright (c) 2011-2012 Woody Gilk * @license MIT */ class Kohana_Kostache { @@ -29,7 +27,8 @@ class Kohana_Kostache { ) ); - return new self($m); + $class = get_called_class(); + return new $class($m); } public function __construct($engine) diff --git a/classes/Kohana/Kostache/Layout.php b/classes/Kohana/Kostache/Layout.php index 1b8a7d2..cf67bec 100644 --- a/classes/Kohana/Kostache/Layout.php +++ b/classes/Kohana/Kostache/Layout.php @@ -5,12 +5,10 @@ * @package Kostache * @category Base * @author Jeremy Bush - * @author Woody Gilk * @copyright (c) 2010-2012 Jeremy Bush - * @copyright (c) 2011-2012 Woody Gilk * @license MIT */ -abstract class Kohana_Kostache_Layout extends Kostache { +class Kohana_Kostache_Layout extends Kohana_Kostache { /** * @var string partial name for content @@ -27,20 +25,20 @@ abstract class Kohana_Kostache_Layout extends Kostache { */ protected $_layout = 'layout'; - public function render() + public function render($class, $template = NULL) { if ( ! $this->render_layout) { return parent::render(); } - $partials = $this->_partials; + $this->_engine->setPartials( + array( + Kostache_Layout::CONTENT_PARTIAL => parent::render($class, $template) + ) + ); - $partials[Kostache_Layout::CONTENT_PARTIAL] = $this->_template; - - $template = $this->_load($this->_layout); - - return $this->_stash($template, $this, $partials)->render(); + return $this->_engine->loadTemplate($this->_layout)->render($class); } } diff --git a/classes/Kostache/Layout.php b/classes/Kostache/Layout.php index 7feeb1d..93df875 100644 --- a/classes/Kostache/Layout.php +++ b/classes/Kostache/Layout.php @@ -1,3 +1,3 @@ _base_dir, $name, $this->_extension); return file_get_contents($filename); } + + /** + * Set an associative array of Template sources for this loader. + * + * @param array $templates + */ + public function setTemplates(array $templates) + { + $this->_templates = array_merge($this->_templates, $templates); + } + + /** + * Set a Template source by name. + * + * @param string $name + * @param string $template Mustache Template source + */ + public function setTemplate($name, $template) + { + $this->_templates[$name] = $template; + } } From 8855a0f5802740b36256d665c69cf60c2ff6ce7c Mon Sep 17 00:00:00 2001 From: Jeremy Bush Date: Wed, 31 Oct 2012 20:39:43 -0500 Subject: [PATCH 08/12] Add docs for layouts --- README.markdown | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/README.markdown b/README.markdown index 6b8dcc8..fe144b7 100644 --- a/README.markdown +++ b/README.markdown @@ -44,6 +44,12 @@ Templates should go in the `templates/` directory in your cascading file system. Partials are loaded automatically based on the name used in the template. So if you reference `{{>foobar}}` in your template, it will look for that partial in `templates/partials/foobar.mustache`. +# Layouts + +KOstache supports layouts. To use, just add a `templates/layout.mustache` file (a simple one is already provided), and use `Kostache_Layout` for your renderer instead of `Kostache`. You'll probably want to put a `$title` property in your view class. The layout should include a `{{>content}}` partial to render the body of the page. + +# Additional Information + For specific usage and documentation, see: [PHP Mustache](http://github.com/bobthecow/mustache.php) From c7eccc88f8cc41c2c2117846bdcca7c71576a777 Mon Sep 17 00:00:00 2001 From: Jeremy Bush Date: Wed, 31 Oct 2012 21:35:14 -0500 Subject: [PATCH 09/12] Pass class and template to parent if render layout is off --- classes/Kohana/Kostache/Layout.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/classes/Kohana/Kostache/Layout.php b/classes/Kohana/Kostache/Layout.php index cf67bec..b80f2ec 100644 --- a/classes/Kohana/Kostache/Layout.php +++ b/classes/Kohana/Kostache/Layout.php @@ -29,7 +29,7 @@ class Kohana_Kostache_Layout extends Kohana_Kostache { { if ( ! $this->render_layout) { - return parent::render(); + return parent::render($class, $template); } $this->_engine->setPartials( From a701055a581f5a8fdf85d02138c287a824f0e955 Mon Sep 17 00:00:00 2001 From: Jeremy Bush Date: Wed, 31 Oct 2012 21:39:43 -0500 Subject: [PATCH 10/12] remove render_layout, since it is useless now that we have different renderers --- classes/Kohana/Kostache/Layout.php | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/classes/Kohana/Kostache/Layout.php b/classes/Kohana/Kostache/Layout.php index b80f2ec..d102c6b 100644 --- a/classes/Kohana/Kostache/Layout.php +++ b/classes/Kohana/Kostache/Layout.php @@ -15,11 +15,6 @@ class Kohana_Kostache_Layout extends Kohana_Kostache { */ const CONTENT_PARTIAL = 'content'; - /** - * @var boolean render template in layout? - */ - public $render_layout = TRUE; - /** * @var string layout path */ @@ -27,11 +22,6 @@ class Kohana_Kostache_Layout extends Kohana_Kostache { public function render($class, $template = NULL) { - if ( ! $this->render_layout) - { - return parent::render($class, $template); - } - $this->_engine->setPartials( array( Kostache_Layout::CONTENT_PARTIAL => parent::render($class, $template) From b8c530249faee79804d2f34d51c7c7bcba8c4c66 Mon Sep 17 00:00:00 2001 From: Jeremy Bush Date: Wed, 31 Oct 2012 22:00:11 -0500 Subject: [PATCH 11/12] Overload constructor for layout class to provide a custom layout --- classes/Kohana/Kostache/Layout.php | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/classes/Kohana/Kostache/Layout.php b/classes/Kohana/Kostache/Layout.php index d102c6b..5a99de2 100644 --- a/classes/Kohana/Kostache/Layout.php +++ b/classes/Kohana/Kostache/Layout.php @@ -20,6 +20,13 @@ class Kohana_Kostache_Layout extends Kohana_Kostache { */ protected $_layout = 'layout'; + public function __construct($engine, $layout = 'layout') + { + $this->_layout = $layout; + + parent::__construct($engine); + } + public function render($class, $template = NULL) { $this->_engine->setPartials( From 4748c07be2e8b10f1c4340800df1bd582263ad26 Mon Sep 17 00:00:00 2001 From: Jeremy Bush Date: Wed, 31 Oct 2012 22:09:32 -0500 Subject: [PATCH 12/12] Add factory method to layout class, lets you pass a custom layout into the class --- classes/Kohana/Kostache.php | 4 ++-- classes/Kohana/Kostache/Layout.php | 11 ++++++++--- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/classes/Kohana/Kostache.php b/classes/Kohana/Kostache.php index dba10d9..bacb1b0 100644 --- a/classes/Kohana/Kostache.php +++ b/classes/Kohana/Kostache.php @@ -14,7 +14,7 @@ class Kohana_Kostache { protected $_engine; - public static function factory($cache = FALSE) + public static function factory() { $m = new Mustache_Engine( array( @@ -23,7 +23,7 @@ class Kohana_Kostache { 'escape' => function($value) { return html::chars($value); }, - 'cache' => $cache ? APPPATH.'cache/mustache' : NULL, + 'cache' => APPPATH.'cache/mustache', ) ); diff --git a/classes/Kohana/Kostache/Layout.php b/classes/Kohana/Kostache/Layout.php index 5a99de2..1f85dc1 100644 --- a/classes/Kohana/Kostache/Layout.php +++ b/classes/Kohana/Kostache/Layout.php @@ -20,11 +20,16 @@ class Kohana_Kostache_Layout extends Kohana_Kostache { */ protected $_layout = 'layout'; - public function __construct($engine, $layout = 'layout') + public static function factory($layout = 'layout') { - $this->_layout = $layout; + $k = parent::factory(); + $k->set_layout($layout); + return $k; + } - parent::__construct($engine); + public function set_layout($layout) + { + $this->_layout = (string) $layout; } public function render($class, $template = NULL)