Skip to content

A mustache templating library for Emacs

License

Notifications You must be signed in to change notification settings

Wilfred/mustache.el

Repository files navigation

mustache.el Coverage Status

a mustache templating library in Emacs Lisp

Targeting v.1.0.2 of Mustache.

Example usage

(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))

Keywords in 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))

Implemented mustache features

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>"))) ;; "&lt;p&gt;We use mustache&lt;/p&gt;"

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"

Todo:

  • Errors on unclosed tags
  • Optional error on missing variables from the context
  • Whitespace (in)sensitivity for windows newlines
  • Run full specification test suite

Running tests

Within Emacs:

M-x mustache-run-tests

Or from a command line (you need Cask installed):

$ cask
$ cask exec ert-runner

Roadmap

v1.0 -- Pass the full mustache v1.0.2 specification tests (excluding optional parts).

Other templating projects

About

A mustache templating library for Emacs

Resources

License

Stars

Watchers

Forks

Packages

No packages published