zombor / kostache Goto Github PK
View Code? Open in Web Editor NEWLogic-less View/Mustache Module for Kohana v3
License: MIT License
Logic-less View/Mustache Module for Kohana v3
License: MIT License
Fatal error: Class 'Kohana_Mustache' not found in /www/kohanaphp/modules/kostache/classes/kohana/kostache.php on line 226
Shouldn't Kohana_Kostache_Layout extend Kostache?
Currently
class Kohana_Kostache_Layout extends Kohana_Kostache
In the past
class Kohana_Kostache_Layout extends Kostache
We should not be mixing paths and content, it leads to hard to find bugs and confusing properties. The following seems like a much simpler approach:
protected $_partials = array(
'foo' => '{{#foo}}{{name}}{{/foo}}',
);
protected $_partial_paths = array(
'bar' => 'some/path/to/partial','
);
I can submit a pull request soonish.
Any ideas on how to implement MustacheLoader with View classes to auto-load partials ?
One of my views already had a partial called 'content' obviously clashing with the new;
const CONTENT_PARTIAL = 'content';
After updating to Kostache 2 my working view blew up (somewhere in a Mustache regex?) and debugging was tricky, until the light went on.
Maybe a value less likely to clash with or be used by another coder (ie; me) could be considered.
KOstache assumes your templates will be withiin reach of the cascading file system. However Kohana::file_find() is not recursive so you need to be careful not to place your templates directory too deep outside the reach of the cascading file system. This isnt necessarily an issue with KOstache, but more of a gotcha between KO3 and KOstache.
Under Kohana 3.3 the template files are loaded according to PSR-0 naming conventions. For example the file 'about/contact.mustache' would be loaded as 'About/Contact.mustache'.
Some systems would look for these files case-sensitive, so they are not found if not properly named.
Change needed to the _load_file
method to always look for lowercase template file names.
Task / Feature request:
Add composer.json and submit the module to packagist.org - for easier inclusion in Composer-powered Kohana projects.
Is there a reason? I don't mind getting it working myself and sending a pull request. I was just wondering whether there is a reason you have not added a config for the userguide.
Is it anything todo with the {{include}} behaviour in guides?
mustache spec doesn't say anything about how to determine non-empty list. and its author denied to add this syntax to spec (mustache/mustache#47) and left this task to view.
in my test, the test? section is rendered as nothing. i thought it would be overloading the __isset and __get in view and using kind of {{#has_tests}} or any better solution?
Typical Kostache viewmodels have capitalised separators. ie. View_Page. It'd be more consistent if the default layout template be Layout.mustache (instead of lowercase) to match the typical naming of the other templates.
Shouldn't partials have their own view class when needed? Like I have a sidebar as a partial. I want to generate some dropdowns for it. Now I have to put my view code in the head view class while it actually should be in an sidebar.php view class.
Please correct me if I'm wrong.
Caching might be desirable. See http://github.com/bobthecow/mustache.php/issues/#issue/2
I know there is the variable $_partials that holds the partials for the template, which could be overwritten by extended classes. And I know there is also a partial() method that allows to set partials. However, it will be nice if we could have a way to inherent some partials from a base view and overwrite just some of them in a child view.
Example:
class View_Site extends Kostache {
protected $_template = 'site';
protected $_partials = array(
'header' => 'partials/sections/header',
'banner' => 'partials/sections/banner',
'contents' => 'partials/templates/2cols',
'footer' => 'partials/sections/footer',
);
...
}
class View_Homepage extends View_Site {
protected $_local_partials = array(
'banner' => 'partials/sections/homepage/banner',
'contents' => 'partials/templates/3cols',
// Partials specific to new content
'column1' => 'partials/sections/homepage/col1',
'column2' => 'partials/sections/homepage/col2',
'column3' => 'partials/sections/homepage/col3',
);
...
}
// Then at Kostache
abstract class Kohana_Kostache {
...
if ($this->_partials)
{
// Merge locals with partials
$this->_partials = Arr::merge($this->_partials, $this->_local_partials);
foreach ($this->_partials as $name => $path)
{
...
}
With this, My Homepage will use View_Site as the base View, using the "site" template and using the default partials; and then "overwrite" only the ones that are different (In this case from a default 2 columns to a custom 3 columns and using a different banner). I know I can achieve the same by doing:
class View_Homepage extends View_Site {
protected $_partials = array(
'header' => 'partials/sections/header',
'banner' => 'partials/sections/banner_homepage',
'contents' => 'templates/3cols',
'footer' => 'partials/sections/footer',
// Partials specific to new content
'column1' => 'partials/sections/homepage/col1',
'column2' => 'partials/sections/homepage/col2',
'column3' => 'partials/sections/homepage/col3',
);
...
}
or by overloading the construct and setting my partials via the partial() method, but I find the former way not so DRY (if I want to change the partial path for the header, I will just need to update the base View_Site and all children views will reflect the change immediately, in contrast the current way will need to change all the children as well) and the latter too verbose. I think, allowing some type of inheritance will be nice.
I also know there is a Kostache_Layout class that allows some kind of overloading of partials, but IMHO I find it not so flexible and somehow limited.
Food for thought :). Good night.
thanks.
VERY odd bug:
we have this lamba function in our view class:
public function __()
{
return function($string)
{
return __($string);
};
}
that is called in the mustache via:
{{#__}}string_to_replace{{/__}}
__() is an internal function to get a translation of a string.
if it is called inside a partial, if there is a tab character before the {{>partial}}, then on each eval of the lamba, it adds the tab characters into the result.
ensuring {{>partial}} starts at the first character 'fixes' it, but it's a very odd bug. for reference, calling my lamba on the parent does not cause this error.
Kostache_Layout
has been modified to use "content" rather than "body" but layout.mustache
still has a reference to {{>body}}
.
What do you think about creating an empty class, for example class Kohana_Mustache extends Mustache
and call Kohana_Mustache
from KOstache to allow people to customize it.
To explain, back when KOstache extended Mustache directly, I've had this method overridden:
protected function _renderEscaped($tag_name)
{
return HTML::chars($this->_getVariable($tag_name), FALSE);
}
Mustache's own method was using htmlentities()
which has done unnecessary work, since Kohana is UTF-8 only.
This would also be a convenient place to add any other custom code to Mustache.
Not sure if this is a bug or desired behavior. Example
View:
class View_Homepage extends Kostache {
$this->_template = 'home';
...
}
When using (@ controller)
// __construct called directly, $template is NULL
// $this->template->_template will be point to home.mustache
$this->template = new View_Homepage;
// factory will call __construct with $template set to 'Homepage'
// $this->template->_template will be point to homepage.mustache
$this->template = Kostache::factory('Homepage');
Either
__construct should check if $this->_template is set like this
public function __construct($template = NULL, array $partials = NULL)
{
if ($this->_template)
{
// Load the template defined in the view
$template = $this->_template;
}
elseif ( ! $template)
{
// Detect the template for this class
$template = $this->_detect_template();
}
...
}
Or that check can be done at the factory, I think the __construct way looks cleaner.
in Mustache_Loader_Kohana, line 16 you have:
$this->_extension = '.' . ltrim($options['extension'], '.');
This strips the . but adds it back in.
If you do:
$this->_extension = ltrim($options['extension'], '.');
It works
For example; I have
class View_Layout_Default extends Kostache_Layout {
protected $_layout = 'layout/default';
}
class View_Layout_News extends View_Layout_Default {
/* ..etc.. */
}
Because Kostache uses _detect_template() to construct the view I cannot instantiate View_Layout_News without having an empty template file layout/news.mustache
I think Kohana_Kostache_Layout needs a constructor:
public function __construct($template = NULL, array $partials = NULL)
{
if ( ! $template)
{
$template = $this->_layout;
}
parent::__construct($template, $partials);
}
(but I could be wrong.)
I think a long term goal should probably be the separation of templates and the view class. This would allow the changing of template engines without needing to affect the View-Model, for example you could swap out the Mustache engine for JSON.
This might be out of the scope of Kostache however.
Hi,
The README.markdown says, under "Using the View_Layout class", the following:
"your own layout file [โฆ] needs to have a {{>body}}
partial defined in it. "
While, if I'm not mistaken, it should be {{>content}}
. :)
KOstache/classes/Kohana/Kostache.php was crashing because it was unable to locate class 'html'. Changing class name to uppercase fixed the issue.
Doesn't exist as the README guides, it should be changed to Kostache_Layout
Hi,
First, I don't know if it's an issue or something I'm doing wrong, but here it is. I'm using the latest master branch of Kostache.
I have this controller action:
public function action_modify($model_id)
{
$model = Jelly::query('model', $model_id)->select();
$view = Kostache::factory('model/modify');
$view->set('model', $model);
if ($_POST)
{
/* Etc */
}
$this->request->response = $view;
}
And the views:
View_Model_Modify extends View_Model_Insert { ... }
View_Model_Insert extends View_General_Base { ... }
View_General_Base extends View_Layout { ... }
The templates doesn't have anything special, and the "layout.mustache" has the {{>body}} part.
Summary: using kostache's layout view.
Here's the problem, with this particular action and template (modify) I get this error:
ErrorException [ Warning ]: is_file(): open_basedir restriction in effect. File(/server/htdocs/XXX/admin/application/templates/ <div id="formulario_w"> MUCH MORE HTML & Mustache </div> .mustache) is not within the allowed path(s): (/server/:/home/:/tmp/:/usr/share/pear/)
After seeing that, I modified the Kostache render function:
// Convert partials to expanded template strings
foreach ($this->_partials as $key => $partial_template)
{
Kohana::$log->add('INFO', 'PARTIAL TEMPLATE: '.var_export($partial_template, TRUE));
if ($location = Kohana::find_file('templates', $partial_template, 'mustache'))
{
$this->_partials[$key] = file_get_contents($location);
}
}
In all cases, even when there's no error, $partial_template has the content of the mustache file. The only thing different with the modify template is that it's somewhat larger than the others, and maybe has something like "../" or similar, hence the open_basedir error.
I suppose that $partial_template should contain the name of the template, not the content.
Am I doing something wrong?
Update: apart from {{>body}}, I'm not using partials.
Isn't is possible to add mustache as a submodule so that when you add KOstache as a submodule to your project mustache gets added as well? I'm new to git, so I might be missing something. I'm not really sure what's the best way to add mustache in the vendor library?
KOstache now exposes public method to load partials by providing path to them. It would be nice to be able to do the same, but for literal partials (i.e. that were generated dynamically).
I've had such method in my application code, incidentally named partial
, which can't work after recent KOstache update, so I'm thinking of adding it back with another name, if you wouldn't have a better idea.
I was having difficulty getting some lambda functions working until I realized that the $m->setPartials()
function takes unrendered content. The current code in Kohana_Layout
renders the partial before it is set, then Mustache renders it again. Normally this wouldn't be a big deal, but if you attempt to change the delimiter, it matters. I ended up extending the Kohana_Layout
and changing the render function.
I have found that on Kohana 3.3 with KOstache that template files should have a upper case beginning for template names. However layout.mustache is hard coded so the files do all look the same. Would it be possible to rename layout.mustache to Layout.mustache?
It would be great, if KOstache supported i18n (internationalization).
It's very easy to implement. Just add this function to the Kohana_Kostache class:
<?php
public function i18n()
{
return array('I18n', 'get');
}
Then it will be possible to use i18n in templates:
<label for="user_email">{{#i18n}}Email{{/i18n}}</label>
I would find it useful if _detect_template()
would check for a set $_template
property first, then continue with creating the template path from the class name.
On line 118 of the kostache core class
Kohana::exception_handler($e);
Should be
Kohana_Exception::handler($e);
no?
Could you make a 3.3/develop
branch with this module prepared for Kohana 3.3? :)
In this line:
https://github.com/zombor/KOstache/blob/3.1%2Fdevelop/classes/kohana/kostache.php#L226
the value of the folder "templates" is hard-coded. Can it be possible to have that value in a public static variable defined by default with "templates" so users can change accordingly if they want? I kind of like "views" better than "templates".
$file = Kohana::find_file(Kostache::$directory, $path, 'mustache');
thanks.
Nano.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.