Code Monkey home page Code Monkey logo

antlers's Introduction

Antlers

A swift, robust templating system for clojure

Introduction

Antlers grew out of a plain mustache library called Stencil, but under the strain of heavy use acquired many features that now no longer align with the original mustache philosophy (in particular, lambdas no longer behave like mustache lambdas, though there are many new features as well). Consider it a superset of mustache, with lambdas that make sense.

Usage

To simply render a string as a template, use render-string:

(require '[antlers.core :as antlers])

(antlers/render-string 
 "Roaming the open {{land}}"
 {:land "tundra!"})

--> "Roaming the open tundra!"

To render the same template over and over again, use render-file (which caches the parsed AST that can subsequently be reused repeatedly):

(antlers/render-file
 "some/resource/dir/roaming"
 {:land "taiga!"})

--> "Roaming the open taiga!"

This will find a file called some/resource/dir/roaming anywhere in your classpath.

To cache the AST for a string, you can register a template with a key and then call render-file using that key. It will behave as if it was loaded from a file:

(require '[antlers.parser :as parser])
(parser/register-template "roaming" "Roaming the open {{land}}")
(antlers/render-file "roaming" {:land "intergalactic void!"})

--> "Roaming the open intergalactic void!"

Blocks

Antlers supports content blocks, which are useful for things like layouts. Suppose you have a file "layout" which looks something like this:

HEADER
  MONOLITHIC BODY
FOOTER

But you would like to have other bodies, like BODY OF MODULARITY, without replicating HEADER and FOOTER over and over again. The trick is to use a block:

HEADER
  {{%body}}{{/body}}
FOOTER

Then, in another file "modular" can be the content:

{{< layout}}
{{%body}}BODY OF MODULARITY{{/body}}

Which, when called with (antlers/render-file "modular" {}) yields:

HEADER
  BODY OF MODULARITY
FOOTER

Now, you can have another file called "alternate" which can have totally different contents for the body block. You only need to specify the changes in the blocks, not the rest of the file:

{{< layout}}
{{%body}}This is a more conversational body for the same layout template{{/body}}

Which yields when rendering "alternate":

HEADER
  This is a more conversational body for the same layout template
FOOTER

Helper functions

Any function you pass in the rendering map can be used from inside the templates (this is a departure from mustache, which has lambdas which are passed blocks of unrendered text which needs to be rendered inside the lambda...)

(antlers/render-string
 "{{inc level}}" 
 {:inc inc :level 10})

 --> 11

This turns out to be very handy! A function can be used as a predicate in a conditional block (or anywhere else for that matter):

(antlers/render-string
 "{{#even? x}}X IS EVEN{{/even? x}}"
 {:even? even? :x 15})

 --> 

Loop variables

Traversing a loop is simple:

(antlers/render-file "lake" 
 {:lakes [{:name "Huron"} 
          {:name "Erie"} 
          {:name "Crater"}]})

In the "lake" template:

{{#lakes}}
  {{name}}
{{/lakes}}

--> Huron 
    Erie 
    Crater

But what if we want the last one to be emphasized? This works:

{{#lakes}}
  {{name}}{{#loop.last}}!!!{{/loop.last}}
{{/lakes}}

--> Huron 
    Erie 
    Crater!!!

Other loop variables include:

loop.first       -->  true/false
loop.last        -->  true/false
loop.item        -->  the current item in the loop
loop.index       -->  the current index
loop.inc-index   -->  one-based index (useful for things)
loop.count       -->  total count of items in this list
loop.outer       -->  a reference to any loop variables from an outer loop.  outer can also have an outer, ad infinitum.

License

Eclipse Public License

antlers's People

Contributors

davidsantiago avatar noisesmith avatar prismofeverything avatar raynes avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

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.