GithubHelp home page GithubHelp logo

scala-mustache's Introduction

Mustache

What is Mustache?

Mustache is a logic-free template engine inspired by ctemplate and et.

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

Usage

To get the language-agnostic overview of Mustache's template syntax and examples of Mustache templates, see http://mustache.github.com/mustache.5.html.

Getting started with scala-mustache is easy:

import mustache._
...
val template = new Mustache("Hello, {{ name }}!")
template.render(Map("name"->"world"))

Returns following:

Hello, world!

Following example shows how to use partials:

val userTemplate = new Mustache("<strong>{{name}}</strong>")
val baseTemplate = new Mustache(
  "<h2>Names</h2>\n{{#names}}\n  {{> user}}\n{{/names}}"
)
val ctx = Map("names"->List(
                   Map("name"->"Alice")
                  ,Map("name"->"Bob")
          ))
val partials = Map("user" -> userTemplate)
baseTemplate.render(ctx, partials)

Templates defined here can be thought of as a single, expanded template:

<h2>Names</h2>
{{#names}}
  <strong>{{name}}</strong>
{{/names}}

You can use {{.}} and {{{.}}} to reference current context value:

val template = new Mustache("{{#list}}{{.}} {{/list}}")
template.render(Map("list"->List("alpha", "bravo", "charlie")))

Returns:

alpha bravo charlie

When the context value is a callable object, such as a function or lambda, the object will be invoked and passed the block of text. The text passed is the literal block, unrendered. {{tags}} will not have been expanded - the lambda should do that on its own. In this way you can implement filters or caching.

val template = new Mustache("{{#wrapped}}{{name}} is awesome.{{/wrapped}}")
template.render(Map("name"->"Willy"
    ,"wrapped"->((str:String, render:(String)=>String)=>{ "<b>"+render(str)+"</b>" })
)

Returns:

<b>Willy is awesome.</b>

Alternatively you can pack your helpers directly into the Mustache subclass. Following example is effectively the same as previous:

class MyMustache(template:String) 
  extends Mustache(template) {

  def wrapped(str:String) = "<b>"+render(str)+"</b>"

}
val template = new MyMustache("{{#wrapped}}{{name}} is awesome.{{/wrapped}}") 
template.render(Map("name"->"Willy"))

Sometimes it is nice to keep different kinds of helpers separate. To do so, you can define helper traits and then mix them up as needed:

trait MyHelper {
  this: MyHelper with MustacheHelperSupport =>

  def wrapped(str:String) = "<b>"+render(str)+"</b>"
}

class MyMustache(template:String) 
  extends Mustache(template) with MyHelper {}

MustacheHelperSupport trait defines following methods you can use in your helper methods:

protected def context:Any                   // returns current context
protected def render(template:String):Any   // renders template string

Dependencies / Build

This project has absolutely zero runtime dependencies and you can build it with Simple Build Tool.

Licensing

This project is licensed under the MIT license.

I’m not a lawyer and this is not a legal advice, but it is free to use in any projects. Free as in “free beer”. Should you have any questions on licensing, consult your lawyer.

Enjoy !

scala-mustache's People

Contributors

sdz-dalbrecht avatar vspy 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

Watchers

 avatar  avatar  avatar  avatar

scala-mustache's Issues

Incorrect conditional tag render result

Try this, where avatar could be a string or empty.

  {{#avatar}}
    <img src="{{avatar}}"/>
  {{/avatar}}
  {{^avatar}}
    <img src="/images/default_avatar.png" height="75" width="75" />
  {{/avatar}}

Inverted sections rendered incorrectly for existing values

This block of code in SectionToken.render:

    case str:String => StringProduct(str)

    case other =>
      composite(children, other, partials, callstack)

does not check if the section is inverted or not so it should better be

case str:String => if (!inverted) StringProduct(str) else EmptyProduct
case other => if(!inverted) composite(children, other, partials, callstack) else EmptyProduct

Update for scala-2.10

Hello,
I'd like to use your library for a project on scala-2.10. It looks like your code builds with it, but tests don't work, because of old specs version (and for newer version some code changes are needed).
So could your update the project for using latest sbt-0.12 and scala-2.10?

Section context totally hides parent context

Hi!
If I'm creating a section that introduces a context ({{#}}), it correctly switches context to the section "object" making its "attributes" available to the content of the section.
However, all "attributes" of the parent context become unavailable to the content of the section.
Take this example:

{{header}}
{{#organization}}
{{header}}
id: {{id}}
name: {{name}}
{{/organization}}

if the root context is
Map("header"->"Hello", "organization"->Map("id"->1, "name"->"My Organization"))

then {{header}} will correctly be rendered in first case, but not the second

Support for Scala's Some as context for a section

Currently if a section references a value being a Scala Some[T] is gets passed as a context as-is (SectionToken.render). Thus when trying to resolve further values within it fails. I would suggest tweaking the final cases of the match to:

case str:String => if (!inverted) StringProduct(str) else EmptyProduct
case Some(thing) => if (!inverted) composite(children, thing, partials, callstack) else EmptyProduct
case other => if(!inverted) composite(children, other, partials, callstack) else EmptyProduct

(this also considers the suggestions from issue #2)

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.