https://github.com/Wilfred/mustache.el.git
git clone 'git://github.com/Wilfred/mustache.el.git'
Targeting v.1.0.2 of Mustache.
(require 'mustache)
(require 'ht) ;; hash table library
(let ((context (ht ("name" "J. Random user"))))
;; evaluates to: "Hello J. Random user!"
(mustache-render "Hello {{name}}!" context))
You‘re not forced to use ht
, it's just an easier way of creating
hash tables. You can use Emacs’ reader syntax for hash tables instead:
(require 'mustache)
(let ((context
#s(hash-table test equal data ("name" "J. Random user"))))
;; evaluates to: "Hello J. Random user!"
(mustache-render "Hello {{name}}!" context))
Note that hash tables default to using eql
as the key comparison
function. You must set it to equal
since mustache.el uses hash
tables with string keys.
You can use keywords in contexts, which allows you to skip setting the key comparison function.
(require 'mustache)
(let ((mustache-key-type 'keyword)
(context
#s(hash-table data (:name "J. Random user"))))
;; evaluates to: "Hello J. Random user!"
(mustache-render "Hello {{name}}!" context))
Basic variable interpolation:
(mustache-render
"Coded with {{language}}!"
(ht ("language" "elisp"))) ;; "Coded with elisp!"
Blocks with booleans:
(mustache-render
"{{#is-sunny}}Looks nice today.{{/is-sunny}}"
(ht ("is-sunny" t))) ;; "Looks nice today."
(mustache-render
"{{#is-sunny}}Looks nice today.{{/is-sunny}}"
(ht ("is-sunny" nil))) ;; ""
Blocks with hash tables:
(mustache-render
"{{#user}}{{name}}{{/user}}"
(ht ("user"
(ht ("name" "Wilfred"))))) ;; "Wilfred"
Blocks with lists:
(mustache-render
"{{#some-list}}{{item}}{{/some-list}}"
(ht ("some-list"
(list
(ht ("item" "a"))
(ht ("item" "b"))
(ht ("item" "c")))))) ;; "abc"
Inverted blocks:
(mustache-render
"{{^is-sunny}}Take an umbrella!{{/is-sunny}}"
(ht ("is-sunny" nil))) ;; "Take an umbrella!"
(mustache-render
"{{^is-sunny}}Take an umbrella!{{/is-sunny}}"
(ht ("is-sunny" t))) ;; ""
Mustache variables are escaped:
(mustache-render
"{{info}}"
(ht ("info" "<p>We use mustache</p>"))) ;; "<p>We use mustache</p>"
Unless explicitly marked as safe:
(mustache-render
"{{{info}}}"
(ht ("info" "<p>We use mustache</p>"))) ;; "<p>We use mustache</p>"
(mustache-render
"{{& info }}"
(ht ("info" "<p>We use mustache</p>"))) ;; "<p>We use mustache</p>"
Comments:
(mustache-render
"hello{{! world }}"
(ht)) ;; "hello"
Partials:
;; assuming ~/projects/mustache.el/test.mustache exists
;; and contains "hello {{user}}"
(let ((mustache-partial-paths (list "~/projects/mustache.el")))
(mustache-render
"{{> test}}"
(ht ("user" "wilfred")))) ;; "hello wilfred"
Changing delimeters:
(mustache-render
"{{=<% %>=}}<% style %>"
(ht ("style" "ERB style!"))) ;; "ERB style!"
Lambdas:
(mustache-render
"{{#wrapped}}{{language}} is great.{{/wrapped}}"
(ht ("language" "elisp")
("wrapped"
(lambda (template context)
(concat "<b>" (mustache-render template context) "</b>")))))
;; "<b>elisp is great.</b>"
Error checking on invalid sections:
(mustache-render
"{{#outer}}{{#inner}}mismatched!{{/outer}}{{/inner}}"
(ht)) ;; error "Mismatched brackets: You closed a section with inner, but it wasn't open"
mustache.el is broken up into several files, using load
to import
them. If you have a checked-out copy of mustache.el, you will need to
do:
(add-to-list 'load-path "~/projects/mustache.el/")
Within Emacs:
M-x mustache-run-tests
Or from a command line (you need Cask installed):
$ make test
v1.0 – Pass the full mustache v1.0.2 specification tests (excluding optional parts).
mustache-key-type
which allows contexts
with keyword for keys.{{&escaped blocks}}
{{^blocks}}
and
{{!comments}}
default-directory
was set.mustache-partial-path
not being a list{{=<% %>=}}
{{ variable }}
interpolation{{> foo}}
{{#blocks}}
when the context value is a
hash table.with-namespace
in favour of internal
functions/variables being of the form mst--foo
.{{#foo}}{{/bar}}
and {{#foo}}
.{{#blocks}}
now optionally support using vectors instead of
lists{{{blocks}}}
with-namespace
macro{{#blocks}}
when the context contains a list
of hash tables