diff --git a/README.markdown b/README.markdown index 6c6b807..9f85e09 100644 --- a/README.markdown +++ b/README.markdown @@ -1,198 +1,144 @@ -KOstache -============ +# KOstache -KOstache is a kohana module for using [Mustache](http://defunkt.github.com/mustache/) templates in your application. +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 & Simple Example ------ +## Example -View classes go in classes/view/ +Did you know the pagination view in Kohana is terrible? We are going to fix it: -classes/view/example.php +### How it exists now: - - class View_Example extends Kostache - { - public $foo = 'bar'; - } + + + + + -Template files go in templates/ + + + + + -templates/example.mustache + - This is a {{foo}} + + + + + -In your controller, just do: + - $view = new View_Example; - echo $view; + + + + + -And you get: + + + + + - "This is a bar" +

-Complex Example ------ +Wow, look at all that login in there! How do you plan on effectively maintaining that?!? -Model (This example uses [AutoModeler](http://github.com/zombor/Auto-Modeler)): - - '', - 'name' => '', - 'value' => '', - ); - - protected $_rules = array( - 'name' => array('not_empty'), - 'value' => array('not_empty'), - ); - } - -View: - - fetch_all() as $test) - { - $tests[] = $test->as_array(); - } - return $tests; - } - } - -Template: - - - - - - {{title}} - - -

{{title}}

-

Here are all my {{things}}:

- - - - -Controller: - - '', - 'name' => '', - 'value' => '', - ); - - protected $_rules = array( - 'name' => array('not_empty'), - 'value' => array('not_empty'), - ); - } - -View: - - TRUE); - - public $thing_id = NULL; - public $title = 'Testing'; - - public function thing() - { - return new Model_Test($this->thing_id); - } - } - -Template: - - - - - - {{title}} - - -

{{title}}

-

This is just one thing:

-

{{thing.id}}

- - - - -Controller: +### Our new View Class (classes/view/pagination/basic.php) thing_id = $id; - echo $view; + protected function items() + { + $items = array(); + + // First. + $first['title'] = 'first'; + $first['name'] = __('first'); + $first['url'] = ($this->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; } - } // End Welcome + } -Using the View_Layout class ---- +Yum, logic in a class, where it belongs :) + +### Our mustache template (templates/pagination/basic.mustache) + +

+ {{#items}} + {{#url}}{{/url}}{{#num}}{{/num}}{{name}}{{#num}}{{/num}}{{#url}}{{/url}} + {{/items}} +

+ +Holy cow, that's more maintainable :) + +## 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 View_Layout class KOstache comes with a View_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 View_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 {{>body}} partial defined in it. +If you have a view that extends the View_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; + } + For specific usage and documentation, see: [PHP Mustache](http://github.com/bobthecow/mustache.php) diff --git a/classes/kohana/kostache.php b/classes/kohana/kostache.php index c005023..9dea279 100644 --- a/classes/kohana/kostache.php +++ b/classes/kohana/kostache.php @@ -2,6 +2,8 @@ class Kohana_Kostache extends Mustache { + const VERSION = 1.3; + protected $_partials_processed = FALSE; /** diff --git a/classes/view/kohana/layout.php b/classes/view/kohana/layout.php index 18c073f..47df7fb 100644 --- a/classes/view/kohana/layout.php +++ b/classes/view/kohana/layout.php @@ -4,6 +4,8 @@ class View_Kohana_Layout extends Kostache { protected $_layout = 'layout'; + public $render_layout = TRUE; + /** * @var string template title */ @@ -22,12 +24,15 @@ class View_Kohana_Layout extends Kostache $this->_template = strtolower(implode(DIRECTORY_SEPARATOR, $foo)); } - $this->_partials+=array( - 'body' => $this->_template - ); + if ($this->render_layout) + { + $this->_partials+=array( + 'body' => $this->_template + ); - // Make the layout view the child class's template - $this->_template = $this->_layout; + // Make the layout view the child class's template + $this->_template = $this->_layout; + } return parent::render($template, $view, $partials); } diff --git a/guide/kostache.about.md b/guide/kostache.about.md new file mode 100644 index 0000000..f007f5b --- /dev/null +++ b/guide/kostache.about.md @@ -0,0 +1,7 @@ +# About KOstache + +KOstache is a 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. + +This module requires mustache.php and includes it as a git submodule. See [Working With Git](tutorials.git) for more information about managing submodules. \ No newline at end of file diff --git a/guide/kostache.examples.md b/guide/kostache.examples.md new file mode 100644 index 0000000..cb259ca --- /dev/null +++ b/guide/kostache.examples.md @@ -0,0 +1,139 @@ +# KOstache Examples + +## Complex Example + +Model (This example uses [AutoModeler](http://github.com/zombor/Auto-Modeler)): + + class Model_Test extends AutoModeler + { + protected $_table_name = 'tests'; + + protected $_data = array( + 'id' => '', + 'name' => '', + 'value' => '', + ); + + protected $_rules = array( + 'name' => array('not_empty'), + 'value' => array('not_empty'), + ); + } + +View: + + class View_Example extends Kostache + { + public $title = 'Testing'; + + public function things() + { + return Inflector::plural(get_class(new Model_Test)); + } + + public function tests() + { + $tests = array(); + foreach (AutoModeler::factory('test')->fetch_all() as $test) + { + $tests[] = $test->as_array(); + } + return $tests; + } + } + +Template: + + + + + + {{title}} + + +

{{title}}

+

Here are all my {{things}}:

+ + + + +Controller: + + class Controller_Welcome extends Controller { + + public function action_index() + { + echo new View_Example; + } + + } // End Welcome + +## Grabbing a single model value + +Model (This example uses [AutoModeler](http://github.com/zombor/Auto-Modeler)): + + class Model_Test extends AutoModeler + { + protected $_table_name = 'tests'; + + protected $_data = array( + 'id' => '', + 'name' => '', + 'value' => '', + ); + + protected $_rules = array( + 'name' => array('not_empty'), + 'value' => array('not_empty'), + ); + } + +View: + + class View_Singular extends Kostache + { + protected $_pragmas = array(Kostache::PRAGMA_DOT_NOTATION => TRUE); + + public $thing_id = NULL; + public $title = 'Testing'; + + public function thing() + { + return new Model_Test($this->thing_id); + } + } + +Template: + + + + + + {{title}} + + +

{{title}}

+

This is just one thing:

+

{{thing.id}}

+ + + + +Controller: + + class Controller_Welcome extends Controller { + + public function action_singular($id) + { + $view = new View_Singular; + $view->thing_id = $id; + echo $view; + } + } // End Welcome diff --git a/guide/kostache.usage.md b/guide/kostache.usage.md new file mode 100644 index 0000000..6d2f1da --- /dev/null +++ b/guide/kostache.usage.md @@ -0,0 +1,58 @@ +# KOstache Usage + +View classes go in classes/view/ + +classes/view/example.php + + class View_Example extends Kostache + { + public $foo = 'bar'; + } + +Template files go in templates/ + +templates/example.mustache + + This is a {{foo}} + +In your controller, just do: + + $view = new View_Example; + echo $view; + +And you get: + + "This is a bar" + +## 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 View_Layout class + +KOstache comes with a View_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 View_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 {{>body}}; partial defined in it. + +If you have a view that extends the View_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; + } + +## Mustache Documentation + +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 diff --git a/guide/menu.kostache.md b/guide/menu.kostache.md new file mode 100644 index 0000000..12d4c06 --- /dev/null +++ b/guide/menu.kostache.md @@ -0,0 +1,4 @@ +1. **KOstache** + - [About](kostache.about) + - [Usage](kostache.usage) + - [Examples](kostache.examples) \ No newline at end of file diff --git a/templates/dates/days.mustache b/templates/dates/days.mustache new file mode 100644 index 0000000..7c07b70 --- /dev/null +++ b/templates/dates/days.mustache @@ -0,0 +1,33 @@ + \ No newline at end of file diff --git a/templates/dates/months.mustache b/templates/dates/months.mustache new file mode 100644 index 0000000..fec51fa --- /dev/null +++ b/templates/dates/months.mustache @@ -0,0 +1,4 @@ + \ No newline at end of file diff --git a/templates/dates/years.mustache b/templates/dates/years.mustache new file mode 100644 index 0000000..7e55a4e --- /dev/null +++ b/templates/dates/years.mustache @@ -0,0 +1,4 @@ + \ No newline at end of file diff --git a/vendor/mustache b/vendor/mustache index 8b1c9c1..a448453 160000 --- a/vendor/mustache +++ b/vendor/mustache @@ -1 +1 @@ -Subproject commit 8b1c9c113c4e189923e4874be6fca5be715239ac +Subproject commit a448453da30c6862cad912cd3db4ac4b8751deb2