kumarshantanu / basil

A general purpose template library for Clojure and ClojureScript
9 stars 1 forks source link

Implement directives #9

Open kumarshantanu opened 11 years ago

kumarshantanu commented 11 years ago

Implement named directives that are handled by directive handlers. Directives should be translated after parse phase. Directive handlers act as middleware for parsed template. Directives are always at the top-level in the template--they are never nested.

macro directive

The macro directive returns a named compiled sub-template of the directive body. For the mustache template below:

{{#items}}
  {{#first}}
    <li><strong>{{name}}</strong></li>
  {{/first}}
  {{#link}}
    <li><a href="{{url}}">{{name}}</a></li>
  {{/link}}
{{/items}}

the equivalent via Basil macros would look as follows:

Definition

<#macro {:name :strong-name}><li><strong><%name%></strong></li></#macro>

<#macro {:name :url-body
         :default {:name "No-name"}}>
  <li><a href="<%url%>"><%name%></a></li>
</#macro>

Usage

<% (in items
     (in first (include strong-name))
     (in link (include url-body))) %>

Note: Macros may never nest but a macro can have <% (include another-macro) %>, which would in turn evaluate another macro and hence exhibit nesting behavior.

refer-as directive

Directives from another template can be accessed via this. Note that this works only at runtime. Another template must be referred by an alias, which is like a virtual namespace.

Definition

<#refer-as {"/libs/mylib.html" my} />

Usage

<% (include my/copyright {:date "1999-2002"}) %>

assign directive

Defines vars that are evaluated at most once every time a template is rendered. The value is memoized and reused on subsequent lookup. The var is unconditionally evaluated in the top-level env/context independent of any slots, but may be shadowed by local vars in slots when evaluating the slots.

Definition

<#assign {:foo (let [x (inc y)]
                 (+ x z))} />

Usage

<% (str "Value: " foo) %>
kumarshantanu commented 11 years ago

Consider the traditional extends use-case as per the links @sunng87 suggested: http://thejohnfreeman.com/blog/2012/03/23/template-inheritance-for-handlebars.html https://docs.djangoproject.com/en/1.5/topics/templates/#template-inheritance

Also consider Freemarker's inheritance model.