Giter VIP home page Giter VIP logo

spec's Introduction

Mustache

Gem Version Build Status

Inspired by ctemplate and et, Mustache is a framework-agnostic way to render logic-free views.

As ctemplates says, "It emphasizes separating logic from presentation: it is impossible to embed application logic in this template language."

For a list of implementations (other than Ruby) and tips, see http://mustache.github.io/.

Overview

Think of Mustache as a replacement for your views. Instead of views consisting of ERB or HAML with random helpers and arbitrary logic, your views are broken into two parts: a Ruby class and an HTML template.

We call the Ruby class the "view" and the HTML template the "template."

All your logic, decisions, and code is contained in your view. All your markup is contained in your template. The template does nothing but reference methods in your view.

This strict separation makes it easier to write clean templates, easier to test your views, and more fun to work on your app's front end.

Why?

I like writing Ruby. I like writing HTML. I like writing JavaScript.

I don't like writing ERB, Haml, Liquid, Django Templates, putting Ruby in my HTML, or putting JavaScript in my HTML.

Installation

Install the gem locally with:

$ gem install mustache

Or add it to your Gemfile:

gem "mustache", "~> 1.0"

Usage

Quick example:

>> require 'mustache'
=> true
>> Mustache.render("Hello {{planet}}", planet: "World!")
=> "Hello World!"

We've got an examples folder but here's the canonical one:

class Simple < Mustache
  def name
    "Chris"
  end

  def value
    10_000
  end

  def taxed_value
    value * 0.6
  end

  def in_ca
    true
  end
end

We simply create a normal Ruby class and define methods. Some methods reference others, some return values, some return only booleans.

Now let's write the template:

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

This template references our view methods. To bring it all together, here's the code to render actual HTML;

Simple.render

Which returns the following:

Hello Chris
You have just won 10000 dollars!
Well, 6000.0 dollars, after taxes.

Simple.

Tag Types

For a language-agnostic overview of Mustache's template syntax, see the mustache(5) manpage or http://mustache.github.io/mustache.5.html.

Escaping

Mustache does escape all values when using the standard double Mustache syntax. Characters which will be escaped: & \ " < > (as well as ' in Ruby >= 2.0). To disable escaping, simply use triple mustaches like {{{unescaped_variable}}}.

Example: Using {{variable}} inside a template for 5 > 2 will result in 5 &gt; 2, where as the usage of {{{variable}}} will result in 5 > 2.

Dict-Style Views

ctemplate and friends want you to hand a dictionary to the template processor. Mustache supports a similar concept. Feel free to mix the class-based and this more procedural style at your leisure.

Given this template (winner.mustache):

Hello {{name}}
You have just won {{value}} bucks!

We can fill in the values at will:

view = Winner.new
view[:name] = 'George'
view[:value] = 100
view.render

Which returns:

Hello George
You have just won 100 bucks!

We can re-use the same object, too:

view[:name] = 'Tony'
view.render # => Hello Tony\nYou have just won 100 bucks!

Templates

A word on templates. By default, a view will try to find its template on disk by searching for an HTML file in the current directory that follows the classic Ruby naming convention.

TemplatePartial => ./template_partial.mustache

You can set the search path using Mustache.template_path. It can be set on a class by class basis:

class Simple < Mustache
  self.template_path = __dir__
end

Now Simple will look for simple.mustache in the directory it resides in, no matter the cwd.

If you want to just change what template is used you can set Mustache.template_file directly:

Simple.template_file = './blah.mustache'

Mustache also allows you to define the extension it'll use.

Simple.template_extension = 'xml'

Given all other defaults, the above line will cause Mustache to look for './blah.xml'

Feel free to set the template directly:

Simple.template = 'Hi {{person}}!'

Or set a different template for a single instance:

Simple.new.template = 'Hi {{person}}!'

Whatever works.

Views

Mustache supports a bit of magic when it comes to views. If you're authoring a plugin or extension for a web framework (Sinatra, Rails, etc), check out the view_namespace and view_path settings on the Mustache class. They will surely provide needed assistance.

Helpers

What about global helpers? Maybe you have a nifty gravatar function you want to use in all your views? No problem.

This is just Ruby, after all.

module ViewHelpers
  def gravatar
    gravatar_id = Digest::MD5.hexdigest(self[:email].to_s.strip.downcase)
    gravatar_for_id(gravatar_id)
  end

  def gravatar_for_id(gid, size = 30)
    "#{gravatar_host}/avatar/#{gid}?s=#{size}"
  end

  def gravatar_host
    @ssl ? 'https://secure.gravatar.com' : 'http://www.gravatar.com'
  end
end

Then just include it:

class Simple < Mustache
  include ViewHelpers

  def name
    "Chris"
  end

  def value
    10_000
  end

  def taxed_value
    value * 0.6
  end

  def in_ca
    true
  end

  def users
    User.all
  end
end

Great, but what about that @ssl ivar in gravatar_host? There are many ways we can go about setting it.

Here's an example which illustrates a key feature of Mustache: you are free to use the initialize method just as you would in any normal class.

class Simple < Mustache
  include ViewHelpers

  def initialize(ssl = false)
    @ssl = ssl
  end
end

Now:

Simple.new(request.ssl?).render

Finally, our template might look like this:

<ul>
  {{# users}}
    <li><img src="{{ gravatar }}"> {{ login }}</li>
  {{/ users}}
</ul>

Integrations

Sinatra

Sinatra integration is available with the mustache-sinatra gem.

An example Sinatra application is also provided: https://github.com/defunkt/mustache-sinatra-example

If you are upgrading to Sinatra 1.0 and Mustache 0.9.0+ from Mustache 0.7.0 or lower, the settings have changed. But not that much.

See this diff for what you need to do. Basically, things are named properly now and all should be contained in a hash set using set :mustache, hash.

Mustache also provides a Rack::Bug panel. First you have to install the rack-bug-mustache_panel gem, then in your config.ru add the following code:

require 'rack/bug/panels/mustache_panel'
use Rack::Bug::MustachePanel

Using Rails? Add this to your initializer or environment file:

require 'rack/bug/panels/mustache_panel'
config.middleware.use "Rack::Bug::MustachePanel"

Rack::Bug

Vim

vim-mustache-handlebars is available at mustache/vim-mustache-handlebars

Emacs

mustache-mode.el is available at mustache/emacs

TextMate

Mustache.tmbundle

See https://gist.github.com/defunkt/323624 for installation instructions.

Command Line

See mustache(1) man page or http://mustache.github.io/mustache.1.html for command line docs.

Acknowledgements

Thanks to Tom Preston-Werner for showing me ctemplate and Leah Culver for the name "Mustache."

Special thanks to Magnus Holm for all his awesome work on Mustache's parser.

Contributing

Once you've made your great commits:

  1. Fork Mustache
  2. Create a topic branch - git checkout -b my_branch
  3. Push to your branch - git push origin my_branch
  4. Create an Issue with a link to your branch
  5. That's it!

Mailing List

~~To join the list simply send an email to [email protected]. This will subscribe you and send you information about your subscription, including unsubscribe information.

The archive can be found at http://librelist.com/browser/mustache/.~~

The mailing list hasn't been updated in quite a while, please join us on Gitter or IRC:

Join the chat at https://gitter.im/mustache/mustache

#{ on Freenode

Meta

spec's People

Contributors

adam-fowler avatar andrewthad avatar bobthecow avatar cjerdonek avatar danappelxx avatar davidsantiago avatar davisp avatar gasche avatar jabley avatar jgonggrijp avatar kanru avatar locks avatar mr0grog avatar mrb avatar pvande avatar ryman avatar s9105947 avatar softmoth 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

spec's Issues

Clarification on functions as context

According to the spec (from the section YAML, not mentioned in interpolation YAML):

5) Otherwise, the data is the value returned by calling the method with the given name.

So the following invocation:

Mustache.render('{{foo}}', { foo: function() { return null; } });

Would render out as (at least in JavaScript anyways) null the way I am interpreting the spec. But that seems a little on the sub-optimal side. Did I mis-interpret the sepc or is this another one of those language dependent traps?

Thanks for the clarification.

Lambda spec is at odds with mustache.js

I don't know if this is a conscious departure on the part of this spec or a quirk in the current JavaScript implementation, but the two differ in the implementation of lambdas.

According to the spec, the function in data object {lambda: function(txt) {}} will receive the content of a {{#lambda}}...{{/lambda}} section as argument.

In mustache.js (and also reflected in the documentation on mustache.github.com) a top level function is always called without arguments (but with the current context as this-object). Only if the function returns another function that function will be called with section contents and a render function.

It would be nice if somebody could shed some light on this discrepancy. I'm actually using current mustache.js behaviour for an extension I call filters.

Change Delimiters

The spec says:

The tag's content MUST be any two non-whitespace sequences (separated by
whitespace) EXCEPT an equals sign ('=') followed by the current closing delimiter.

Yet the examples include things like:

{{= | | =}}

which to me seems to break the "non-whitespace sequence" rule. That is, the new tag delimiter should always immediatelly fllow the = character (or immediately precede it).

Am I misreading the little paragraph at the top?

Partials and Trailing Newlines

Example:

{{! template.mustache }}
{{> partial }}
>> {{> partial }}
[ {{> partial }} ]

---
{{> special }}
>> {{> special }}
[ {{> special }} ]
{{! partial.mustache }}
{{! File ends with newline (common standard) }}
{{#things}}{{.}}, {{/things}}
{{! special.mustache }}
{{! File DOES NOT end with newline }}
{{#things}}{{.}}, {{/things}}

Currently specified output:

a, b, c, d, e, 
>> a, b, c, d, e, 

[ a, b, c, d, e, 
 ]

---
a, b, c, d, e, >> a, b, c, d, e, 
[ a, b, c, d, e,  ]

Proposed change:

Standalone partial tags should always interpolate a trailing newline.
Non-standalone partial tags should always chomp one trailing newline character before rendering.

Resulting output:

a, b, c, d, e, 
>> a, b, c, d, e, 
[ a, b, c, d, e,  ]

---
a, b, c, d, e, 
>> a, b, c, d, e, 
[ a, b, c, d, e,  ]

Feature: moar dot notation hotness

  1. Given that {{ . }} resolves as the current top of the context stack;
  2. And when any falsey segment in a dotted name is encountered, the whole name yields '';
  3. A name like {{ .name }} should imply {{ [current scope].name }};
  4. Thus, it must resolve as truthy only if a member of the current scope matches name.

This is a one-liner to implement in Mustache.php, and seems completely in line with current spec, so I'm considering adding it. Can we get this into spec v1.2?

c.f. bobthecow/mustache.php#98

New operator proposal: Conditional block that wont loop when given a list

This is a common idiom you'll see in the form-handling code in every framework out there:

{% if form.errors %}
<div class="errors">
  <h1>Your form has errors in it!</h1>
  <ul>{% for error in form.errors %}
    <li>{{error}}</li>
  {% endfor %}</ul>
</div>
{% endif %}

Now, how do you implement this in mustache? You can't just make "if form.errors" a section or it would trigger a loop. You would have to pass in an additional flag to indicate that the list is empty. In fact, you'd have to do this any time you wanted to omit rendering the scaffolding around an empty list. And that's no fun.

This happens because mustache uses the same syntax for loops and conditionals. It'd be really nice to have two different operators here, so we could consider a non-empty list to be a normal truthy value without looping on it.

I propose we implement a ? operator that acts just like # except that it does not loop when given a list. This is your conditional operator that only cares about truthiness.

Clarify what the empty string should be treated as.

As part of what constitutes truthiness, the spec uses the !! operator as an example for determining truthiness (in the section.yaml file). The problem is that in JavaScript (and possibly other languages, have not tried), the empty string would be coerced into a false value using that logic. Arguably this is not the intented behaviour, but this is never explicitly stated and currently open to interpretation and implementation differences. Although implementation differences are okay in some circumstances, I think this one should be eliminated by explicitly stating the role that the empty string plays.

For reference, consider the following issues logged under Mustache.js (although not spec-compliant, it is close enough in regards to truthiness to validate this issue):

New Edge Case: Nested blocks with the same name

Most mustache implementations render the following incorrectly:

a = [1,2]
{{#a}}{{#a}}{{.}}{{/a}}{{/a}}

The ruby implementation renders 1212. Other implementations throw errors or render garbage. This happens because they use regular expressions to match whole blocks at a time, including the open and close tags. This cannot be done properly with a single regular expression.

It would be nice if this edge case was included in the spec.

Proposal: HTML vs. text templates

There is a need for totally disabling HTML-escaping, and have {{name}} render just as {{{name}}}:

Currently proposed solutions fall in one of those two buckets:

  • RTFM and use triple mustache. This is missing the point, and unfaithful to the "Mustache can be used for HTML, config files, source code - anything." motto of http://mustache.github.com/mustache.5.html (emphasis mine).
  • Disable escaping via a flag or a method override. This leads to HTML-safety issues whenever such a template is embedded, via a partial tag for example, into another template that performs HTML-escaping.

After a study of the topic for GRMustache, here is more food for thoughts:

  1. The use case "disable HTML-escape" has been turned into a "HTML vs. text" templates at the API level. HTML templates escape their input, text templates do not.
  2. Two pragma tags allow to turn a template into a HTML or a text template: {{% CONTENT_TYPE:TEXT }} and {{% CONTENT_TYPE:HTML }}.
  3. Pragmas are not the only solution. At the API level, user can programmatically choose the content type of templates at different levels, globally, or per directory, whatever - this is left to the implementor. Pragma tags, if present, must have the last word.
  4. When a HTML template embeds (via a partial tag) a text template, the rendering of the text template is HTML-escaped. This basic safety feature is the reason why a "HTML-escape disabling" use case has been turned into "HTML vs. text" concept.
  5. The case of users that want to render HTML and disable HTML-escaping is not covered. The bet is that this use case is not common, if not very very rare.

"Truthiness" and "Falsiness"

Generally speaking, there is little to no consistency between languages in the truthiness (or lack thereof) of any given value. Consequently, the fundamental description of the section tag (and its inverse) -- namely, that it's rendered when the named value is truthy (and falsey, respectively) -- is difficult to test in this specification.

The following options are available:

  • Introduce two new YAML tags, !truthy and !falsey. Implementors of the spec are expected to intercept these and replace them with a non-boolean truthy or falsey value in the implementation language.

    data:
    truthy: !truthy {}
    falsey: !falsey {}

    • Pro: This provides some testing around the concept of truthiness.
    • Pro: This forces awareness of the truthiness portion of the spec.
    • Pro: This does not require any language-specific code in the core spec.
    • Con: This does not provide full coverage of all truthy / falsey values.
    • Con: This requires two additional YAML tags.
    • Con: This forces all implementors to handle these YAML tags.
      • The only other use of custom YAML tags is isolated in the optional Lambdas module.
    • Con: Non-YAML versions of the spec handle YAML tags less elegantly.
  • Utilize the existing YAML tag, !code, to provide a set of language-specific truthy and falsey values.

    data:
    truthy: !code
    ruby: '[ {value: ""}, {value: 0}, {value: Object.new} ]'
    javascript: '[ {value: "non-empty"}, {value: 1}, {value: {}} ]'
    falsey: !code
    ruby: '[ {value: nil} ]'
    javascript: '[ {value: ""}, {value: 0}, {value: undefined}, {value: null} ]'

    • Pro: This provides discreet values to test with.
    • Pro: This does not require the definition of any additional YAML tags (for those already implementing the Lambda spec).
    • Pro: This can provide reasonably complete coverage of all truthy / falsey values.
    • Con: The concept of truthiness is not inherently communicated (it may appear that these values have been arbitrarily chosen).
    • Con: This forces all implementors to handle the !code YAML tag.
    • Con: This introduces language-specific code to the core spec.
    • Con: The language-specific code being added exists only for its resultant value, not for its behavior.
    • Con: This subjects the core spec to additional churn, as each new implementation language requires modifications.
    • Con: Non-YAML versions of the spec handle YAML tags less elegantly.
  • Handle the concepts of truthiness and falsiness abstractly, using a pair of values that are generally recognized as truthy / falsey.

    data:
    truthy: "non-empty"
    falsey: null

    • Pro: This provides some testing around the concept of truthiness.
    • Pro: This does not require any language-specific code in the core spec.
    • Pro: This does not require any YAML tags.
    • Pro: This solution requires no additional work by the implementor.
    • Con: This does not provide full coverage of all truthy / falsey values.
    • Con: The concept of truthiness is not inherently communicated (it may appear that these values have been arbitrarily chosen).
    • Con: The chosen values carry no guarantee as to truthiness / falsiness in every implementation language.
    • Con: The possibility exists that no such pair of values exists globally.
    • Con: Working around these values in languages where either of these values behaves unexpectedly is ambiguous to the implementor.
  • Provide better documentation of Mustache as a whole, including guidelines for implementors (specifically calling out, among other things, truthiness and falsiness). Responsibility for proving conformance falls to the implementation's users and to the Mustache community at large.

    • Pro: This is not exclusive with the other options.
    • Pro: This represents a significant community improvement.
    • Pro: This is completely language-agnostic.
    • Pro: The solution requires no additional work by the implementor.
    • Con: This does not provide any concrete testing.
      • As such, failures are not immediately obvious, and may lay dormant for some time.

possible spec clarification: non-existent partials

Currently the spec says nothing about what action a spec compliant parser should take when it encounters a non-existent partial in a template. Consider the following invocation of a hypothetical Mustache interpreter:

     Mustache.to_html( "{{>import_this_partial}}", { import_that_partial: "oops, i named my partial incorrectly" }, { datum1: true } );

What should the parser do? Should it treat the non-existent partial as the empty string and happily go forward? Should it throw an error? Is this implementation dependant? A "strict-mode" pragma perhaps? Not even sure if the spec should cover something like this, but I figure getting some eyes on it is worthwhile.

Nested list data

How should mustache handle nested lists?

Say something like the following data:
{ list: [1, 2, 3, ["a", "b", "c"], 4] }

Given to this template:
{{#list}} ( {{#.}}{{.}}{{/.}} ) {{/list}}

I'd expect something like
( 1 )( 2 )( 3 )( abc )( 4 )

I've tried two different implementations, but both work in fully unexpected ways, the javascript implementation simply considers {{#.}} as a falsy value, so it doesn't render the section. The Ruby implementation still shows the list value of [a, b, c] not iterating through the items as I'd expect.

I consider this the best, least intrusive way of allowing access to lists within lists, since it's kinda a conclusion of the actual spec.

variable resolution within dotted-name sections

Given a context object with this structure:

 {
  foo: {
    bar: {
      qux: 42,
      quux: 43,
    },
    baz: {
      frob: 23
    }
  }
}

should these two templates render identically?

  "{{#foo.bar.qux}}{{baz.frob}}{{/foo.bar.qux}}"
  "{{#foo}}{{#bar}}{{#qux}}{{baz.frob}}{{/qux}}{{/bar}}{{/foo}}"

right now, it's possible to pass the spec tests with each of these giving different results.

Dynamic Partials and Partial Collections through Coercion

I've just created a pull request over at janl/mustache.js#242

I am using this solution in a couple of projects and it addresses a number of concerns I often hear with regards dynamic partials in Mustache, please see ticket (janl/mustache.js#242) and documentation here:

Really, I urge everyone to have a play with it as it has cleaned up my templates no end.

Kind regards,

Jamie

Add a license

Can you add a license -- e.g. to remove any issues around including a copy of the spec tests in source distributions of Mustache implementations? Thanks.

Proposal: Template inheritance

At Twitter we run into a very common case where we want to have one template where we maintain the "bones" of the page and each real page on the site merely replaces sections of that page with appropriate content. We would like to avoid putting any business logic in the bones of the page for including the right content, nor do we want to write custom backing code for each of those pages.

I give up trying to put my code in the issue, here is a gist: https://gist.github.com/1854699

Should sections with lambdas /higher order functions be able to render content?

Hello.

In the spec the ability to render section content in lambda is not mentioned.
Im talking about this example from http://mustache.github.com/mustache.5.html

{
    "name": "Willy",
    "wrapped": function() {
        return function(text) {
            return "<b>" + render(text) + "</b>"
        }
    }
}

this functionality is also mentioned in this post about using lambdas to implement caching or syntax highlighting: http://ozmm.org/posts/higher_order_mustache.html

If musteche doesn't accept this behaviour, what is the use of lambdas except for prepending/appending text to it's argument?

Make lambda test cases language independent

Many languages that support Mustache (especially non-scripting languages like C++, Java, C#, etc) are not currently supported by the lambda test cases. It is also non-trivial to write new test cases in the current form.

It occurs to me that the lambda test cases could be written in a language-independent way. Naively, one might think that a dictionary for each lambda of input-output pairs would suffice to define the lambdas for test cases purposes (similar to how partial data is handled in the partial test cases.

However, given our issue #30 discussion, something like an (ordered) list of triples of (expected lambda called, output, expected input args) might be closer to the appropriate structure. The right structure would also address the question of how best to test things like lambda evaluation order and non-caching independent of each other.

Implementers would need to change or add to their test harnesses code (in their respective languages) to create the lambdas from that data. The lambdas would need to include assertions that the expected input is correct. Assertions should probably also be made about the overall (global, across-lambda) evaluation order.

Proposal: Template inheritance

At Twitter we run into a very common case where we want to have one template where we maintain the "bones" of the page and each real page on the site merely replaces sections of that page with appropriate content. We would like to avoid putting any business logic in the bones of the page for including the right content, nor do we want to write custom backing code for each of those pages.

My proposal is a declarative syntax for defining replaceable blocks, very much akin to the way this is done in Django and some other templating systems. Here is simple example:

super.mustache:

<title>{{$title}}Default title{{/title}}</title> {{>navigation}}
{{$content}}Default content of the page{{/content}}

{{>footer}}

sub.mustache:
{{<super}}
{{$title}}Profile of {{username}} | Twitter{{/title}}
{{$content}}
Here is {{username}}'s profile page
{{/content}}
{{/super}}

the virtual mustache template that is rendered:

<title>Profile of {{username}} | Twitter</title> {{>navigation}}
Here is {{username}}'s profile page

{{>footer}}

There are many ways that people have tried to workaround this limitation including:

  • rendering sub templates into {{{content}}} values
  • using javascript to render sections separate and splatting them into the DOM
  • reproducing the bones in each sub page through a bunch of partials
  • creating massive switch statements using sections

All of these allow business logic and code to creep into the template. My proposal to maintain the declarative nature of mustache by adding this very powerful inheritance feature.

Feature Request: Inline partials

Partials are great, but it'd sure be nice to be able to define partials right inside the template that uses them. In most cases, the partials I create are only used by one parent template so it's a lot of extra work to create the partial the way it works right now. Also, a lot of my partials are one-liners. As a result, I often times end up just copy/pasting instead. It sure would be nice if we could define partials inline. See issue #59. This would allow us to write mini-templates that can be reused within the same template. Here's some possible syntax:

Definition:

{{*mypartial}}
    <li title='{{title}}'>{{text}}</li>
{{/}}

Usage:

<ul>
  {{#items}}
    {{**mypartial}}
  {{/items}}
</ul>

Possible Improvement to Comments

In the spec, the syntax for Comments states that comments are opened with '{{!' and closed with '}}', the consequence being that '}}' cannot appear inside comments. That's fine and works fairly well. But one thing I've found useful during everyday coding is to comment out Mustache code fragments using Mustache comments. Our "Mustache-like" parser achieves this by using '{{!' as the open token and '!}}' as the close token. So in our parser, when you have a code fragment like:

{{#foo}}{{bar}}{/foo}}

you can easily comment it out via:

{{! TODO: Determine why this code fragment does not work {{#foo}}{{bar}}{{/foo}} !}}

A similar thing cannot be achieved with a spec-compliant parser which I think is a shame.

As far as I understand it, this request would be backwards compatible too since existing code must not nest '}}' in comments.

What do you guys think?

Proposal: Limiting context when using implicit iterators

Given the following context:

{
    name: 'Hello World',
    list: [
        { data: '123', name: 'one' }
        { data: 'abc' }
    ]
}

The following:

{{#list}}
    {{data}} - {{#name}}{{name}}{{/name}}
{{/list}}

Will output something like:

    123 - one
    abc - Hello World

It might be nice if you could syntactically limit the context to the current iteration

{{#list}}
    {{.data}} - {{#.name}}{{.name}}{{/.name}}
{{/list}}

To get:

    123 - one
    abc - 

The use case I have is printing out html sytlesheet include fragments: the optional title attribute is missing, and it's finding the page title attribute up the context stack.

{{#stylesheets}}
    <link rel="stylesheet" href="{{href}}" type="text/css" {{#title}}title="{{title}}" {{/title}}charset="utf-8">
{{/stylesheets}}
....
<h1>{{title}}</h1>

Feature Request: Variable Defaults

Right now if you tell mustache to output a variable, it defaults to empty string if the variable has no value. I'd like to be able to specify a default string to output in this case. For example:

Data:

{
  people: [
    {name: "Bob", fav_food: "Pizza"},
    {name: "Joe", fav_color: "Orange"}
  ]
}

With the current spec, I would have to write this:

{{#people}}
  <h1>{{name}}</h1>
  <dl>
    <dt>Favorite Color:</dt><dd>{{#fav_color}}{{fav_color}}{{/fav_color}}{{^fav_color}}None{{/fav_color}}</dd>
    <dt>Favorite Food:</dt><dd>{{#fav_food}}{{fav_food}}{{/fav_food}}{{^fav_food}}None{{/fav_food}}</dd>
  </dl>
{{/people}}

If some sort of default syntax were added, I could write this instead:

{{#people}}
  <h1>{{name}}</h1>
  <dl>
    <dt>Favorite Color:</dt><dd>{{fav_color || "None"}}</dd>
    <dt>Favorite Food:</dt><dd>{{fav_food || "None"}}</dd>
  </dl>
{{/people}}

Clarify interaction of custom end delimiter versus tag name

Suppose a template sets custom delimiters to something that is allowed inside a tag name. The spec isn't clear about what happens.

For example:

  • If the end delimiter is set to X and a template contains {{ fooXbar X.... Is the tag's name foo or fooXbar?
  • If the end delimiter is set to .X and a template contains {{ foo.Xbar .X.... Is the tag's name foo or foo . Xbar?

Ie: Is the tag defined to be (start delim) (anything *except* end delim) (end delim), or is it more like (start delim) (*anything* that's allowed as part of a tag name) (something that's not allowed as part of a tag name such as }} or trailing-whitespace-followed-by-end-delim), etc) with an error raised if the "something that's not allowed as part of a tag name" doesn't qualify as an expected end tag?

JSON creation

I just sent a pull request about a Python test, I noticed that when I generated JSON that it changed every file because the order of attribute access had changed. I elected to not include those updates in the diff. Is there a way to make the JSON generation in the Rakefile emit sorted keys?

I'm not so hip to the Ruby and wasn't able to figure anything out from the json gem docs.

i18n with mustache [like: {{_i}}..{{/i}}]?

Hello.
What's the preferred strategy to i18nalize a mustache template?

Twitter's fork of Mustache.js uses {{_i}} {{/i}} sections to callout to gettext.

Will this be ported to main mustache spec? Or should One just provide a lambda and use it like {{#i}}Some text{{/i}} ?

When, Oh When, Mustache 2.0?

Is there any hope Mustache 2.0 will make a break for it within the year?

If there is a hold up b/c of so many feature possibilities and undecided choices to make about them, may I suggest that this process be divided into 2.0 and a 3.0 tracks?

For 2.0 just adopt the things you are sure about and/or already have precedence in the field. For instance Hogan.js has already adopted template inheritance. I recommend taking that, adjusting it so the notation is more intuitive/useful (for instance, my recommendation), and go with it. Another possibility is Handlebar.js style helpers. And personally I'd like to see Liquid style filters. But I digress. The point is pick the things that are ready or near ready to go, and make 2.0 out of those and save anything that is still well up in the air for 3.0.

Personally I feel there is some urgency to get the move on, as new template engines are making the scene to draw people away from a common standard, which Mustache has succeeded in doing more than any other for logicless templates.

Mustache shouldn't alter whitespace inside partials

Whitespace is sacred in HTML.

Mustache (per the current spec) plays fast and loose with whitespace inside partials.

This causes unexpected results:

template.mustache

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

body.mustache

<p>
    <textarea>{{ text_with_newlines }}</textarea>
</p>

context.yml

text_with_newlines: |
    This is a
    newline test

output

<body>
    <div>
        <p>
            <textarea>This is a
        newline test</textarea>
        </p>
    </div>
</body>

This is no-me-gusta. I think the "Indentation should be prepended to each line of the partial" portion of the spec should be dropped completely.

See also: this issue on Mustache.php.

Proposel: dynamic partials

Hi all, I'm new to moustache so please correct if there is a way to do this. I've been using Mu2 and Node.js as a bit of context.

I could like to be able to create a skeleton moustache template and then tell it which partials to include. The reason for this is that using this top down approach to assembling a document means that each template only needs to be aware of the content it contains, not that which is around it. An example is this - with some help from the Mu2 developer I current need templates like this:

view

{
    heading: "MY content heading",
    content: "<p>Some text</p>"
}

Main render: content.mustache

{{> header}} 
{{heading}}
{{& content}}   
{{> footer}} 

Partial: header.moustache

<html>
    <headers><!-- other partials here --></headers>
    <body>
        <!-- menu bar partials, etc -->

Partial: footer.moustache

    </body>
</html>

This will work for the moment, but it's rather ugly because the content has to know what goes around it. It also has problems if I need (for example) to select different partials in the headers and the content. What I would much prefer to be able to do is this:

view

{
    contentPartial: "content",
    heading: "MY content heading",
    content: "<p>Some text</p>"
}

Main render: page.moustache

<html>
    <headers><!-- other partials here --></headers>
    <body>
        <!-- menu bar partials, etc -->
        {{> contentPartial}}
    </body>
</html>

Partial: content.mustache

{{heading}}
{{& content}}   

So when the rendering encounters the {{> contentPartial}} code, it detects that contentPartial is a value in the view, insert's it's value and then continues to include, thus including the content.moustache partial.

Please let me know if there is a way around this issue - lamda's perhaps?

Use 'if and only if' wording

I noticed that you may be able to express some of the spec in a more precise way by borrowing wording from the field of logics.

This section MUST NOT be rendered unless the data list is empty.

This sentence has a double negation which can make it a bit confusing.
You can use the following wording instead and make the coupling crystal clear:

This section MUST be rendered if and only if the data list is empty.

Partials fallback to lookup by filename

I wish we could have this cemented in the spec, specifically:

When the lookup of a partial named 'sidebar.mustache' fails, lookup would fallback to the file named 'sidebar.mustache'. If rendering is being done on the client, then this simply doesn't occur.

Of course we need to support full file paths like../../layout.mustachebut I think this is trivial for most languages. In PHP the path string is simply placed into a file_get_contents call. However, I'd like to hear the opinions of some implementors on this. When partials reference more partials, there's potential to mixup paths, for example:

/partials/one.mustache:

Here's one.mustache

/partials/two.mustache:

Here's two.mustache
{{> one.mustache}}

/final.mustache:

Here's final.mustache
{{> partials/two.mustache}}

Since references would be relative, implementations need to take care to look for the file relative to the file including it.

django template language features -- inheritance, blocks

The django template language offers template inheritance and blocks, which can be overridden.

Conceptually, the django template system has a dictionary of templates, which can be referred to within the templates.

Here is are some examples of the django templates in action:

# base.html
<html>
<head>
</head>
<body>
{% block content %}{% endblock %}
</body>
</html>

# mypage.html
{% extends base.html %}
{% block content %}<div>Hey, I'm in your content</div>{% endblock %}

Perhaps mustache can adopt something like:

# base.html
<html>
<head>
</head>
<body>
{{{content}}}
</body>
</html>

# mypage.html
{{< base.html}}
{{%content}}<div>Hey, I'm in your content</div>{{/content}}

Improve name resolution documentation

The name resolution descriptions in the "interpolation," "sections," and "inverted" parts of the documentation are very similar. Indeed, it looks like the descriptions in "sections" and "inverted" are identical. It would help to combine these descriptions into a single section so that it is easier to see how name resolution differs or is the same in these three contexts.

In the meantime, can someone clarify the following?

Should name resolution for sections and inverted sections obey the same rules? Also, is it intentional that a single period cannot be used for sections and inverted sections?

Finally, the spec says for sections, "if the context is an object and the method with the given name has an arity of 1, the method SHOULD be called with a String containing the unprocessed contents of the sections; the data is the value returned." Can someone clarify whether this should be done even for the non-final parts of the name split on periods?

Thanks.

clarify what is meant by `standalone`

There are a number of places in the specs that mention an entity should be treated one way if it is standalone and another if it is not without giving any definition of what it means to be standalone. Can someone please elaborate what exactly it means to be standalone?

formating of dates, numbers and more

I've been discussing the viability of mustache as a templating solution with a colleague and he raised some questions about a lacking key feature; formating. And I tend to agree with him - having this as part of the mustache spec would be very helpful.

The string representation of a date or time, the numbers of decimals of a price or the number of characters shown shouldn't be part of your viewmodel - it should (in a perfect world) be handled by the templating language.

I'm thinking something along the lines of being able to define a "format" in some form immediately after the variable name:

{
    price: 2.7532
}

{{price:0.00}}USD

2.75USD

I know JSON doesn't support a native date representation - maybe just treat an ISO datestring as a date object and present it through a format like php's date function (other formats might be more fitting/standard)?

I'm sorry if this issue has been raised a thousand times (it seems so obvious somehow) - but I haven't been able to find an answer to this yet ;D

Idea: named html chunks

Taking a little inspiration from DerbyJS here.

In derby, and in the multiplex of other templating solutions, you can abstract a chunk of html and use it in various places. Same concept as functions for chunks of code. In derby, it looks like:

<ui:modal>
  <div class="...
  </div>

//Use the modal:
...
  <ui:modal />

Perhaps in mustache this could be like:

{{ *widgetName }}
  <div>widget code</div>
{{/}}

//Using it:
...
  {{ **widgetName }}

Haven't put any thought into the potential syntax of it yet, but what do you guys think? @groue

v2.0.0 Target Acquisition

The list of issues we want to address in v2.0.0 is as follows:

  • Adding Pragmas
    • Change Delimiter Pragma
  • Removing the Change Delimiter tag
  • Layout Facilities (several proposals)
  • Comment Changes (allow commented tags)
  • Lookup Changes (anchored lookups, "skips")
  • Conditional Else
  • Order Independence
  • Language-agnostic Lambda tests
  • Standardized Errors

This list is malleable at this point; comment now if you have additional targets you'd like considered.

"Interpolation - Multiple Calls" test should be implementation-independent

I ran into this issue in the process of refactoring. The "Interpolation - Multiple Calls" test is currently written in a way that assumes tags are evaluated left to right:

template: '{{lambda}} == {{{lambda}}} == {{lambda}}'
expected: '1 == 2 == 3'

The test should probably be rewritten to be implementation-independent (unless there is a left-right requirement that I'm not aware of). If there is a left-right requirement, it is still probably better to rewrite so that the test is more specific and not testing two unrelated things.

Give each test case a unique alphanumeric label

I think it would help if each test case were given a unique alphanumeric label or id (with underscores). I think this would make it a bit easier to reference specific test cases.

So instead of saying the "Interpolation - Multiple Calls" lambda test case, for example, you could say the lambda_interpolation_multiple_calls test case.

This would also make it easier to reference a test case in one's code, say, if you were maintaining a skip list or if you wanted an unambiguous way to generate a variable or function name from a test case. The current "name" value currently can include things like hyphens, colons, spaces, and parentheses.

if/else/each keywords

A form of the if keyword is being requested here: #22
And similarly a form of the each keyword here: #23
@janl made a request for an easier else too: http://writing.jan.io/mustache-2.0.html

I think obscuring the meaning of something that actually means each down to a one symbol: , is stupid and not the hard to read and learn.

@wesen, is there any reason you want short symbols instead of real keywords?

This should be part of Mustache 2.0.

Handlebars also has with and unless keywords, which we could consider.

Proposal: Safe Mode

I am creating this ticket in response to a discussion here: #54 (comment), also related is @pvande's comment here: #41 (comment)

There are a number of scenarios where it would be useful to allow end users to edit Mustache templates. For example, a Shopify type application, a CMS, or to allow users to insert credentials into a templated email (think Campaign Monitor). I'm sure there are many more use cases.

There is a problem with this in how Mustache currently operates as the template author can access properties/methods of a given implementation's objects such as {{thing.private_instance_methods}} (Ruby example) etc. Although you could remove methods that you don't want users to call (kind of like Ruby's BlankSlate object), users will always be able to get to the underlying language methods on strings such as inspect etc.

I envisage a "safe mode" much like how Liquid templates and maybe Liquid Drops work i.e. only the keys and values that are explicitly exposed in the view object are allowed. Therefore, something like {{title.downcase}} or {{collection.inspect}} (Ruby example again) should just return empty strings unless they are explicitly defined.

I'm not entirely sure of the implementation details as yet but wanted to throw this out there for discussion. I for one would love to use Mustache for these types of 'end user' applications and I have seen the question asked a number of times, as to whether Mustache is 'safe' for end user use.

What do you think?

Discussion: Accessing Masked Data

Forked from this comment: #10 (comment)

Data Sample:

name: 'Hello World'
users:
  - name: 'Bill'
    pets:
      - name: 'Yoda'
      - type: 'Cat'
  - name: 'Steve'
    pets:
      - name: 'Wayne'
      - type: 'Llama'

@janl I, like you, am still on the fence about the ../ notation.

Generally, there are a few ways to conceive of a solution:

  • Explicit address (ala handlebars.js), which provides access to literally everything on the stack, but necessarily exposes the implementation of the stack immediately to users. (e.g. are inverted section values put on the stack?)
  • Dot notation with a root anchor, sort of the inverse of handlebars' addressing, would permit you to do fully manual stack traversals (e.g. {{ @.name }} would always resolve to 'Hello World', regardless of stack depth). The downsides to this approach are again exposing the underlying implementation, and eschewing the power of the context stack entirely.
  • Reverse traversals could again solve this particular problem, but fails to solve the more general problem of providing access to any/all masked keys.
  • Skips would allow you to inform the stack traversal to bypass one or more results, which nicely solves the problem of accessing any masked value, but introduces a new syntactic construct that has the potential for abuse. The most attractive feature of this solution is the fact that stil relies on the underlying stack traversal code; this is strictly advice passed to that routine. (e.g. {{ name' }}: not the topmost occurrence of name, but the second; {{ name'' }}: the third occurrence of name)

Of these options, I'm most inclined to support the idea of "skips" at this point.

Define syntax of tag names

There doesn't appear to be any defined spec for the syntax of tag names. For example: can they include embedded whitespace? Which non-alpha-numeric symbols can/can't they include? Is empty-sting allowed as a name (the syntax does make this possible, but is it allowed)? Etc.

Add a license

[Reposting issue #44.] Can you add a license file to the project -- e.g. to remove any issues around including a copy of the spec tests in source distributions of Mustache implementations? Thanks!

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.