Giter Site home page Giter Site logo

mustache.php's Introduction

Mustache.php

A Mustache implementation in PHP.

Package version Monthly downloads

Usage

A quick example:

<?php
$m = new Mustache_Engine(array('entity_flags' => ENT_QUOTES));
echo $m->render('Hello {{planet}}', array('planet' => 'World!')); // "Hello World!"

And a more in-depth example -- this is the canonical Mustache template:

Hello {{name}}
You have just won {{value}} dollars!
{{#in_ca}}
Well, {{taxed_value}} dollars, after taxes.
{{/in_ca}}

Create a view "context" object -- which could also be an associative array, but those don't do functions quite as well:

<?php
class Chris {
    public $name  = "Chris";
    public $value = 10000;

    public function taxed_value() {
        return $this->value - ($this->value * 0.4);
    }

    public $in_ca = true;
}

And render it:

<?php
$m = new Mustache_Engine(array('entity_flags' => ENT_QUOTES));
$chris = new Chris;
echo $m->render($template, $chris);

Note: we recommend using ENT_QUOTES as a default of entity_flags to decrease the chance of Cross-site scripting vulnerability.

And That's Not All!

Read the Mustache.php documentation for more information.

See Also

mustache.php's People

Contributors

amitsnyderman avatar bobthecow avatar brmatt avatar conormcd avatar damz avatar dragoonis avatar elrolito avatar hcpss-banderson avatar jagermesh avatar jimbojsb avatar joycebabu avatar keradus avatar kevburnsjr avatar kirill89 avatar kriss0r avatar lostkobrakai avatar lukemorton avatar mattdeclaire avatar mikesherov avatar mircobabini avatar mlebrun avatar mogria avatar oschettler avatar rarst avatar schlessera avatar scribu avatar smarden1 avatar thewilkybarkid avatar zbuc avatar zombor avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

mustache.php's Issues

example harness?

The examples seem to be missing some common harness code. Each one contains a .php file, a .mustache file, and a .txt file with the results of the example being run. However, you cannot actually run the example, as it is missing the code that loads the class and the .mustache and produces the result.

For me, it sort of defeats the purpose of an example if you can't just run the example and get results and instead have to write code to make it work. Am I missing something?

Whitespace detection

Using 0.5 whitespace detection adds extra characters in partials when they're not always needed. In the example below, the textarea will pick up two \t characters just after the \n character. i.e. The two tab characters from in front of the {{>body}} partial.

Layout:

<body>
    <div>
        {{>body}}
    </div>
</body>

View:

public $newline = "This is a\nnewline test";

Template:

<p>
    <textarea>{{newline}}</textarea>
</p>

No escaping of quotes

Pretty nasty bug bit me tonight, I was using {{double_mustache_notation}} to escape and a variable into an HTML attribute. The data โ€” in JSON format โ€” however contained double-quotes, and the attribute was demarcated with double-quotes.

Did not end well.

Shouldnโ€™t double-mustache do this?

htmlentities($what_to_echo, ENT_QUOTES, 'UTF-8')

Allowing whitespace in iteration as in variables

Hi, this is a proposal for making the syntax in iterations as flexible/loose as it is when dealing with variables.

One can iterate through an array with the implicit iterator like this:

{{#items}}
{{ . }}
{{/items}}

But it will not work if you add whitespace (as it is allowed when typing variables):

{{ #items }}
{{ . }}
{{ /items }}

Notice the difference:
{{#items}}
{{ #items }}

It would be nice if both syntaxes was possible/valid :)

Suggestion: Overloaded methods

I use this class as another layer ontop of my view renderer. My views often use view helpers, which are retrieved by __call(). Using method_exists() instead of is_callable() only looks for methods already "known" to the object without using overloading.

After some playing around, I've come up with a solution in the _findVariableInContext() method (~ line 603).

protected function _findVariableInContext($tag_name, $context) {
    foreach ($context as $view) {
        if (is_object($view)) {
            try {
                if(is_callable(array($view, $tag_name))) return $view->$tag_name();
            } catch (Exception $e) {
                // Suppress any exceptions
            }
            if(isset($view->$tag_name)) return $view->$tag_name;
        } else if (isset($view[$tag_name])) {
            return $view[$tag_name];
        }
    }

    if ($this->_throwsException(MustacheException::UNKNOWN_VARIABLE)) {
        throw new MustacheException("Unknown variable: " . $tag_name, MustacheException::UNKNOWN_VARIABLE);
    } else {
        return '';
    }
}

The try/catch suppresses any exceptions thrown during a possible __call() lookup, and the rest is really just the same as before.

Iterator support esoteric behavior (keys)

I just run over this yesterday while using Mustache. I think it's worth to share if someone runs into the same problem. I had an iterator that was keyed starting with 1.

While using it for a Mustache section, the section was rendered (once) but did not contain any sub values (Not using a pragma).

I wondered about that and checked out the tests in specific the one which iterates over an array. I rebuild that test scenario in my template and used the testdata as a comparison which did work. The testdata array is default keyed.

As this was the only difference I changed my keying to start with 0 instead of 1. This did the trick for the moment.

While I wanted to reproduce this yesterdays behavior to make a more specific issue report here today, I was not able to reproduce this any longer (!).

So if someone runs over a similar problem, in the end the fix was easy for me. I'm a bit disappointed because I can not reproduce it right now even when I revoke the changes I made to fix the problem.

Comments spanning multiple lines don't work

Using comments in templates work fine, except when using multiple lines:

{{! Comments may contain newlines
    This is a multi-line comments,
    with new lines }}

This is not being captured and is shown in the output

A simple fix would be to include the PCRE_DOTALL modifier in the tag regex on line 388:

$this->_tagRegEx = '/' . $otag . "([#\^\/=!>\\{&])?(.+?)\\1?" . $ctag . "+/s";

This way, the . will include all the newlines.

Note: This also affects the regular, non-comment, tags as well.

Regex error with PCRE 6.6

The problem with with named groups. Basically (?<name>) is only valid in PCRE 7 +, RHEL and CentOS PHP version ships with 6.6 thus causing a problem. The solution is in using (?P<name>), this works in both versions.

The error that occurs is "Warning: preg_match(): Compilation failed: unrecognized character after (?<".

Not loading partials from filesystem

from the mustache docs I get that it should read partials from the filesystem from files with the mustache extension.

I've made a couple of templates to avoid repeating html code (details here ) but mustache.php keeps raising a Partial Unknown Exception. I've first thought it was an extension affair and tried a couple of combination of file extensions without success.

So, which is the proper way to handle partials?

throwsExceptions should be settable without subclassing

I share a library folder between a few projects that have differing requirements for whether partials should fail when they're not present. I think it would help if there was a way to set $_throwsExceptions without subclassing or editing the Mustache.php file. Perhaps it could be public so I could just go in and set it like so:

$mustache->throwsExceptions[MustacheException::UNKNOWN_PARTIAL] = true;

Or if that's too ugly, an option value like so:

$mustache = new Mustache($tpl, $view, $partials, array(
    'throws'=>array(
        MustacheException::UNKNOWN_PARTIAL => true,
    ),
));

And add the following to _setOption:

if (isset($options['throws'])) {
    foreach ($options['throws'] as $k=>$v)
        $this->_throwsExceptions[$k] = $v;
}

HTML Entities

If I have greater than and less than symbols in my templates Mustache should not be htmlentities() that should it? It does, but either my implementation is wrong, or I am missing something, I didn't templates would be escaped.

Do not escape HTML

When I do something like
$m->render('<h1>{{title_plain}}</h1>{{title_html}}', array('title_plain'=>'Hello World', 'title_html'=>'<h1>Hello World</h1>'));

it returns
<h1>Hello World</h1>
&lt;h1&gt;Hello World&lt;/h1&gt;

How do I get it to not escape the HTML in the data string?
-Sam

Fails with recursive template

Getting an endless loop with the following code:

<?php
$data = array(
    'title' => 'Parent',
    'children' => array(
        'title' => 'Child',
        'children' => array(
            'title' => 'Grand Child',
        )
    )
);

$template = <<<EOT
<li>{{title}}
    {{#children}}
    <ul>
        {{>child_list}}
    </ul>
    {{/children}}
</li>
EOT;

$m = new Mustache;
echo $m->render( $template, $data, array(
    'child_list' => $template,
) );

I've poked around in the code a little and it seems that when it reaches 'Grand Child', it keeps looping over it, instead of finishing.

lambda/closures

In mustache(5), there is a reference to lambda functions as variables, but this does not seem to be implemented with PHP. I assume this is due to the technical limitations of PHP, but would you care to comment on PHP5.3 closures and why they would not work?

return undefined tags instead of removing

Hi,

What's the best way to not remove an undefined tag but just leave it. The reason being is I'm rendering a list with data that's inside an array, but I still want to render global vars I've set that aren't inside that nested array. So if I didn't remove the tag that is undefined in the list, it would get rendered once it get's to the global vars.

Many thanks,

CJ

Incorrect iteration over special formed array.

If array has not "normalized" indexes, the Mustache is unable to iterate over the array causing to not render the part of template.

Mustache fails if
array_keys( $array ) = array(4,5,6)
array_keys( $array ) = array(0,5,1)
array_keys( $array ) = array(4,"sushi",6)

Mustache succeeds if
array_keys( $array ) = array(0,1,2)

Reproduced on 0.5 & 0.5.1

Test case:
$data = array( "lines" => array(
4 => array( "id" => 2, "name" => "second" ),
5 => array( "id" => 1, "name" => "first" ),
3 => array( "id" => 3, "name" => "third" ),
));

$m = new Mustache();
$template = "{{#lines}}{{id}}::{{name}}<br/>{{/lines}}";

print_r($data["lines"]);
echo "<br/>NO result, except for [::]<br/>";

echo $m->render( $template, $data );

$data = array( "lines" => array(
    1 => array( "id" => 2, "name" => "second" ),
    0 => array( "id" => 1, "name" => "first" ),
    2 => array( "id" => 3, "name" => "third" ),
));

echo "<hr/>";
print_r($data["lines"]);
echo "<br/>Correct result<br/>";

echo $m->render( $template, $data );

Disallow calls to certain methods

I'm wondering, what you think about this.

It sure is convenient to pass object structures to Mustache as it deals with them well, but it is also potentially dangerous, as the models may contain methods, that change states, or execute other undesirable stuff, when used in views.

The most obvious case is probably the delete() method in active record models. If a {{delete}} tag finds its way into Mustache template, a database record may be done for.

The idea I had is to provide a list of methods to Mustache somehow, that it won't execute, if encountered in template. It probably should involve a modification of _findVariableInContext() method.

htmlspecialchars() instead of htmlentities()?

The current _renderEscaped() function leaves out quotes unescaped, so rendering <input value="{{value}}"/> where value has double quotes, breaks HTML output.

Additionally, my personal opinion is, that it's not necessary to convert all possible chars to corresponding entities since today most of us use utf-8 output anyway. I suggest using htmlspecialchars() instead:

return htmlspecialchars($this->_getVariable($tag_name), ENT_QUOTES, $this->_charset);

(may as well be a little bit faster, too)

Nested sections with duplicate names

Ran into a problem when trying to do some recursion.

A template like this:

{{#parents}}Children of {{name}}:
{{#parents}}{{>children}}{{/parents}}
{{/parents}}

fails because it ends on the first {{/parents}} end block, causing an invalid template.

I'm trying to use this on a recursive method to display an infinitely recursive unordered list. Perhaps I'm going about this the wrong way though. Here's the code I'm working with:

http://github.com/zombor/Vendo/blob/feature%2Fproduct-categories/modules/admin/templates/admin/category/product_category_list.mustache

which gets data fed from:

http://github.com/zombor/Vendo/blob/feature%2Fproduct-categories/application/classes/model/product/category.php#L57

product_categories is a recursive array I'm trying to display.

Partials don't work

Hi, I don't know if there is something wrong in my test code, but the partials seems don't work properly.

This is my test code: http://pastebin.com/FDsmbch5
The output of this script, don't show the list of childs.

Whit this stupid patch http://pastebin.com/tSgaN6mu partials works fine.
Seems that when rendering a partial, the context is encapsulated recursively in another array.
Greetings

Irregular behaviour when templating arrays:

I've just found the below shown irregular behaviour that occurs when templating with arrays that doesn't have 0 as the first key element:

Working:

    array
        0 => 
             array
                'name' => string 'A name' 
        1 => 
             array
                'name' => string 'Another name' 

Non-working, leads to empty when accessing {{name}} altough mustache loops array :

    array
        1 => 
             array
                'name' => string 'A name' 
        2 => 
             array
                'name' => string 'Another name' 

Version:

    const VERSION      = '0.8.0';
    const SPEC_VERSION = '1.1.2';

Tags on their own line removes surrounding new lines

If a tag is on it's own line, with two new lines before and after, the new lines after the tag are removed.

Hello

{{name}}

How are you?

Becomes

Hello

SnikchHow are you?

If you make the end whitespace match non-greedy in the _prepareTagRegEx regex then you get one line back.

// Old, greedy regex
/(?P<whitespace>(?<=\\n)[ \\t]*)?%s(?P<type>[%s]?)(?P<tag_name>.+?)(?:\\2|})?%s(?:\\s*(?=\\n))?/s

// Non greedy regex
/(?P<whitespace>(?<=\\n)[ \\t]*)?%s(?P<type>[%s]?)(?P<tag_name>.+?)(?:\\2|})?%s(?:\\s*?(?=\\n))?/s

Commenting out the $next_offset++; at line 512 get's the second line back.

I'm worried as obviously that was there for a reason for the $next_offset++; line, and was wondering if you can fill me in as to why I should or should not be removing it?

Rendering records from idiorm

Hi, I've been playing with mustache in combination with idiorm and slim.

So I have this view:

function test(){
    $albums = ORM::for_table('album')->find_many();

    Slim::render(
        'test.html',
        array(
            'albums' => $albums,
        )
    );
}

where albums are records from the database that has two columns, "name" and "description".

Naively, I've tried this in test.html:

{{#albums}}
   {{album.name}}
{{/albums}}

or a combination of that kind of things. I don't know much of idiorm or mustache's internals and I'm new to PHP myself, but for what I get to see my problem relies in that I don't know the value of the inner object in the loop (the index inside the #albums section) so I can't access it's variables or anything.
Mustache doesn't provide any way to map the inner object to a variable, as would result with a foreach loop (which in turn works as expected):

foreach ($albums as $album ){
    echo $album->name;
}

How would you solve this situation?

PD: I'm not really sure if this is not the place to ask this questions :)
PD: I have the complete app here

internationalization with Mustache and sprintf

Sorry if this might seem as a double-post from stack-overflow (http://stackoverflow.com/questions/8695970/mustache-i18n-with-parameters/) but I'm really struggling with this and would appreciate any pointers.

I've read about higher order sections, and even though lambdas generally confuse me, I think I managed to implement something basic to do i18n of simple text with Mustache (I can copy&paste the code, but it's already on SO).

However, I'd really like to find a good (or reasonable) replacement for things like sprintf(__('translated %s with parameters'), $string)

Can anybody suggest something? Did I miss something obvious (or not so obvious)?

implicit-iterator breaks context?

Hi,

I'm a bit confused by the current IMPLICIT-ITERATOR behaviour. After having used the implicit-iterator pragma the rendering of an array doesn't work as expected.

I'll try to explain with an example.
My template looks like this:

{{%IMPLICIT-ITERATOR}}
{{#scripts}}
    <script type="text/javascript" src="{{.}}"></script> 
{{/scripts}}
{{#styles}}
    <link type="text/css" href="{{file}}" rel="stylesheet" media="{{media}}" /> 
{{/styles}}

The script and styles arrays look like this:

Scripts:
array
0 => string '/media/js/jquery.min.js' (length=23)

Styles:
array
0 =>
array
'file' => string '/media/css/default.css' (length=22)
'media' => string 'screen' (length=6)

The template is rendered like this:

<script type="text/javascript" src="/media/js/jquery.min.js"></script>  
<link type="text/css" href="" rel="stylesheet" media="" /> 

So, the dot notation enabled by implicit-iterator works, but the original behaviour not anymore.

lambdas

It appears you can't use lambda functions.... is this coming soon?

Many thanks

Whitespace issue causing problems for textarea and markdown

The problem does not exist on 0.4.0

Given the following string

Hello world, this is a test

    Some code

Another paragraph.

A mustache template with the code

<textarea cols="50" rows="10">{{description}}</textarea>

will produce the output:

What I expect to see should be:

The problem causes a lot of issues when you have a markdown editor on top of your textarea, because everything is turned into "code".

Dynamic template loading

Is anyone else doing this?
Is anyone interested in having this feature?
Should I submit it as a pull request?

<?php

namespace Web\App;

class Mustache extends \Mustache {

    public $tpl_dir;
    public $_templates;

    /**
     * Override parent partial retrieval
     *
     * Silently fails (i.e. returns '') when the requested partial is not found.
     *
     * @access protected
     * @param string $tag_name
     * @throws MustacheException Unknown partial name.
     * @return string
     */
    protected function _getPartial($tag_name) {
        return $this->getTpl($tag_name);
    }

    public function getTpl($path) {
        if (is_array($this->_templates) && isset($this->_templates[$path])) {
            return $this->_templates[$path];
        }
        // Get templates from apc if available
        $use_apc = APP_ENV != 'dev' && function_exists('apc_cache_info');
        $apc_key = VERSION.'_MUSTACHE_TEMPLATES_'.$this->tpl_dir;
        if($use_apc && $templates = apc_fetch($apc_key)) {
            $this->_templates = $templates;
        } else {
            $this->_templates = $this->getTpls($this->tpl_dir);
            if($use_apc) {
                apc_store($apc_key, $this->_templates);
            }
        }
        return $this->_templates[$path];
    }

    public function getTpls($path) {
        $tpls = array();
        $items = scandir($path);
        foreach($items as $item) {
            if(substr($item,0,1) == '.') continue;
            if(is_dir($path.'/'.$item)) {
                $sub_tpls = $this->getTpls($path.'/'.$item);
                foreach($sub_tpls as $name => $tpl) {
                    $tpls[$item.'/'.$name] = $tpl;
                }
            } else if(($pos = strpos($item, '.mustache')) > 0) {
                $tpl = file_get_contents($path.'/'.$item);
                $name = substr($item,0,$pos);
                $tpls[$name] = $tpl;
            }
        }
        return $tpls;
    }

}

Echoing mustache inside mustache acts like a partial

If I have a mustache template like so:

<script id="app" type="text/html">
    {{#templates}}{{{app}}}{{/templates}}
</script>

if the app variable contains mustache, it's treated like a partial.

Expected output:

<script id="app" type="text/html">
    <li>{{date}} - {{payee}} - {{bucket}} - ${{amount}}</li>
</script>

Actual output (if 'date' is set to 'foo'):

<script id="app" type="text/html">
    <li>foo -  -  - $</li>
</script>

errors with no templates

Warning (2): array_key_exists() expects parameter 2 to be array, string given in [/var/www/sites/dogmatic69.dev/public_html/core/libs/libs/mustache.php, line 612]

it seems to happen with pages that don't have any mustache code to parse. simple fix would be type casting.

in _findVariableInContext() else if (array_key_exists($tag_name, $view)) could be else if (array_key_exists($tag_name, (array)$view))

Methods should take priority above member variables

Supposing I have a member variable called $title and a function called title() and reference them in a template using {{title}} then mustache should call title()

In the context of the above example, this allows you to set a static title in a base class that should be used across all views (i.e. 'My Site') and then prepend it with a dynamic variable, such as the title of the post on the page to create 'Post title | My Site'.

Or in other words, "logic overrides hard coded stuff".

http://github.com/bobthecow/mustache.php/blob/master/Mustache.php#L608-612

Using objects in sections

There's a couple problems here:

  1. _renderSection() checks for _varIsIterable() which checks for is_object(). This doesn't mean that the object is iterable. Then the elseif() in _renderSection() also checks for is_object() which is kinda weird (and probably proper in this case)
  2. A problem exists with the above logic in that if the object is iterable, it will do a foreach on the object, and you'll loose access to any object methods for variable replacement in your template.

I'm trying to think of a good fix for this, as I think #2 is the real problem. It could possibly be fixed by just taking the is_object() check out of _varIsIterable().

Nested lambdas

I am trying to do this

  {{#step1}}
    Hello {{name}}, 
    {{#ifsomething}}
    Something
    {{/ifsomething}}
  {{/step1}}

but I am getting the error Unexpected close section. Is what I want possible?

Performance and caching

HI, thanks for this great port.

I really like the concept of mustache and it has finally persuaded me that PHP based views are really not the best solution in many situations.

One of the main arguments about tempting and PHP though is rendering performance. In reality this is less of an issue that it is made out to be but on a big site could be a reason not to embrace mustache in PHP.

One thing I think Twig have done well is that they compile templates into native PHP classes on first rendering and cache them so that subsequent calls don't incur the performance hit of parsing the text.

I was wondering if you felt it would be worth considering a similar approach with mustache. I realise it is actually quite a major change to output optimized PHP templates rather than compile each time. I guess in reality, parsing templates is not going to be the bottleneck in most apps so I can understand if this is not a priority, however it is possible - perhaps even not that hard - and would mitigate probably the strongest (or at least most prevalent) argument against using mustache in real projects for many.

Just a thought. It may be something I look into in a fork/alternative module - I value the simplicity of your implementation.

Higher-order sections

The current higher-order section implementation in Mustache.php is a bit dangerous (see feature/higher-order-sections or 60d593d).

"Higher-order sections" is a feature of Mustache that allows template manipulation or pre-processing. If the tag referenced by a section returns a function, this function will be called and passed the body of the section. Whatever the function returns will replace the body of the section. See the 'lambdas' section here for examples.

This works great in Ruby and Python, but can have unexpected side effects in PHP. The current implementation assumes that anything 'callable' should be treated as a higher-order function. Consider the following:

<?php

class Monster extends Mustache {
    public $_template = '{{#title}}{{title}} {{/title}}{{name}}';
    public $title;
    public $name;
}

$frank = new Monster();
$frank->title = 'Dr.';
$frank->name  = 'Frankenstein';
$frank->render();

$dracula = new Monster();
$dracula->title = 'Count';
$dracula->name  = 'Dracula';
$dracula->render();

?>

The first monster renders as Dr. Frankenstein, just as one would expect. But the second monster renders as 1Dracula since, according to PHP, the string 'Count' is a valid callback for count(). This is not desirable.

I see a couple of options:

  1. Only allow PHP 5.3+ anonymous functions for higher-order sections. This keeps us from executing unintentional callbacks, but leaves all the poor PHP 5.2 folks out of the fun.
  2. Only allow anonymous functions or class-based callbacks for higher-order sections. i.e. array($this, 'myCallback') is a valid class-based callback, as are array('SomeClass', 'myCallback') and 'SomeClass::myCallback' ... 'count', however, is not.
  3. Keep the current implementation and let the buyer beware. This seems like a bad idea, so I'd suggest not voting for number 3.

inner tag not rendered

I have this tags in my template.

{{#format_date}} {{date_from_db}} {{/format_date}}

where the format_date is a lambda function in my view class that calls a helper class

-- view class --

public function formate_date() { return array('Formats', 'fuzzy'); }

-- helper class --

public static function fuzzy($date) { return Date::fuzzy_span(strtotime($date)); };

when i trace this the parameter passed to the fuzzy_span method is still {{date_from_db}} string

Date::fuzzy_span(strtotime( {{date_from_db}} ));

[!!!] Mustache injection

I just lost my hair trying to debug an untraceable exception about an unclosed tag. So, if I try outputting a text which contains something like {{#categories}} using {{text}} or {{{text}}}, Mustache will parse the string looking for its' open / close tag.

So, what does this mean?

Since every user input is "parsable" this way, a whole variety of exploits is possible, especially when the mustache template works with some data abstraction layer (ActiveRecord, DataMapper, etc.) In my case (using Kohana 3), I have a Database_Result of ORM objects passed to view. All I need to do is input something like {{#categories}}{{delete}}{{/categories}} (or guess some other selector) and all the passed categories will be deleted. Maybe passing whole objects like this to template is a malpractice of ViewModel, IMHO not in this case.

Pragma in constructor not working

Passing the unescaped pragma as part of the options array in the constructor doesn't work.

It seems as if the problem is that _pragmas and _localPragmas are stored differently (_pragmas uses the array value as the pragma, whereas _localPragmas uses the array key, and I assume (from the code) that the value can be true or false to indicate whether the pragma is enabled or disabled)

Unfortunately, line 381 (method _renderPragmas()) simply copies _pragmas to _localPragmas, which results in data that's interpreted wrong later.

I fixed this by changing line 381 from
$this->_localPragmas = $this->_pragmas;
to
$this->_localPragmas = array_fill_keys($this->_pragmas, true);

Tag arguments

Does mustache allow any argument passing to callbacks?

Could I do the following:
{{#join_date format="Y-m-d"}}

join_date would be a method and it's supposed output a formatted date using the php function date. The first argument to the method would be an arguments array from the tag in the template.

<?php
...
public function join_date($args = array())
{
    $format = (isset($args['format']) === TRUE) ? $args['format'] : 'Y-m-d';
    return date($this->data['join_date'], $format);
}
...
?>

Multidimensional arrays

Is there a way to display such arrays in a template? I have an array, with the key "settings", which is also an array with keys like "site_name", "theme", "version"...

Something like this would be nice:
{{settings.site_name}}

Example Files

There are 103 files in mustache.php, 78 are examples, 21 are tests. Can the examples and tests be placed into their own branch to reduce clutter? The less files I have to deploy, the faster every deploy is. :)

Passing parameters to sections

Is it possible to somehow pass parameters to a section? Something like this:

{{#entries group=pages count=5}}
    {{title}}
    {{& body}}
    <hr>
{{/entries}}

This currently doesn't work, so I'm wondering if it's even possible. Or is there a workaround?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.