Targeting v.1.0.2 of Mustache.
(require 'mustache)
(let ((context '(("name" . "J. Random user"))))
;; evaluates to: "Hello J. Random user!"
(mustache-render "Hello {{name}}!" context))
context
can be anything that Emacs's map manipulation
functions
accept: alists (as in the example above), hash tables, and (if using keyword
arguments — see below) plists.
Example with hash tables:
(let ((context
#s(hash-table test equal data ("name" "J. Random user"))))
;; evaluates to: "Hello J. Random user!"
(mustache-render "Hello {{name}}!" context))
You can use keywords in alist and plist contexts:
(require 'mustache)
;; Using an alist
(let ((mustache-key-type 'keyword)
(context '((:name . "J. Random user"))))
;; evaluates to: "Hello J. Random user!"
(mustache-render "Hello {{name}}!" context))
;; Using a plist
(let ((mustache-key-type 'keyword)
(context '(:name "J. Random user")))
;; evaluates to: "Hello J. Random user!"
(mustache-render "Hello {{name}}!" context))
Basic variable interpolation:
(mustache-render
"Coded with {{language}}!"
'(("language" . "elisp"))) ;; "Coded with elisp!"
Blocks with booleans:
(mustache-render
"{{#is-sunny}}Looks nice today.{{/is-sunny}}"
'(("is-sunny" . t))) ;; "Looks nice today."
Blocks with maps:
;; Using alists
(mustache-render
"{{#user}}{{name}}{{/user}}"
'(("user" ("name" . "Wilfred")))) ;; "Wilfred"
;; Using plists
(let ((mustache-key-type 'keyword))
(mustache-render
"{{#user}}{{name}}{{/user}}"
'(:user (:name "Wilfred")))) ;; "Wilfred"
Blocks with lists:
;; Using alists
(mustache-render
"{{#some-list}}{{item}}{{/some-list}}"
'(("some-list" . ((("item" . "a"))
(("item" . "b"))
(("item" . "c")))))) ;; "abc"
;; Using plists
(let ((mustache-key-type 'keyword))
(mustache-render
"{{#some-list}}{{item}}{{/some-list}}"
'(:some-list ((:item "a")
(:item "b")
(:item "c"))))) ;; "abc"
Inverted blocks:
(mustache-render
"{{^is-sunny}}Take an umbrella!{{/is-sunny}}"
'(("is-sunny" . nil))) ;; "Take an umbrella!"
(mustache-render
"{{^is-sunny}}Take an umbrella!{{/is-sunny}}"
'(("is-sunny" . t))) ;; ""
Mustache variables are escaped:
(mustache-render
"{{info}}"
'(("info" . "<p>We use mustache</p>"))) ;; "<p>We use mustache</p>"
Unless explicitly marked as safe:
(mustache-render
"{{{info}}}"
'(("info" . "<p>We use mustache</p>"))) ;; "<p>We use mustache</p>"
(mustache-render
"{{& info }}"
'(("info" . "<p>We use mustache</p>"))) ;; "<p>We use mustache</p>"
Comments:
(mustache-render
"hello{{! world }}"
'()) ;; "hello"
Partials:
;; assuming ~/projects/mustache.el/test.mustache exists
;; and contains "hello {{user}}"
(let ((mustache-partial-paths (list "~/projects/mustache.el")))
(mustache-render
"{{> test}}"
'(("user" . "wilfred")))) ;; "hello wilfred"
Changing delimeters:
(mustache-render
"{{=<% %>=}}<% style %>"
'(("style" . "ERB style!"))) ;; "ERB style!"
Lambdas:
(mustache-render
"{{#wrapped}}{{language}} is great.{{/wrapped}}"
`(("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}}"
'()) ;; error "Mismatched brackets: You closed a section with inner, but it wasn't open"
- Errors on unclosed tags
- Optional error on missing variables from the context
- Whitespace (in)sensitivity for windows newlines
- Run full specification test suite
Within Emacs:
M-x mustache-run-tests
Or from a command line (you need Cask installed):
$ cask
$ cask exec ert-runner
v1.0 -- Pass the full mustache v1.0.2 specification tests (excluding optional parts).