Home

Awesome

Eco - Fast, flexible, designer-friendly templates.

Build Status

Goals

Usage

A basic template (.eco extension) looks like this:

<% deftemplate index (title &optional posts) () %>
  <!DOCTYPE html>
  <html>
    <head>
      <title><%= title %></title>
    </head>
    <body>
      <% if posts %>
        <h1>Recent Posts</h1>
        <ul id="post-list">
          <% loop for (title . snippet) in posts do %>
            <li><%= title %> - <%= snippet %></li>
          <% end %>
        </ul>
      <% else %>
        <span>No recent posts.</span>
      <% end %>
    </body>
  </html>
<% end %>

To load this template, put this in your system definition file:

(:eco-template "filename")

For interactive or quick tests on the REPL, templates can be loaded using ECO:COMPILE-STRING,

(eco:compile-string "<% deftemplate inline-test () () %>This is a test.<% end %>")

All templates are eventually compiled into Lisp functions. To get their outputs, call the templates like any Lisp function:

(eco-template:index "My Blog" nil)

Eco is designed to be output-agnostic, however, by default it will autoescape HTML for convenience. Specify :ESCAPE-HTML NIL when defining each template to disable this behaviour individually for each template.

<% deftemplate output-js-logger (module) (:escape-html nil) %>
   function logDebug (message) {
       console.log("<%= module %>: " + message);
   }
<% end %>

Tags

There are three types of tags in Eco:

Blocks are used to specify Lisp code "inline" in the template, and tend to contain imperative code, their return values are ignored. Expressions and calls are more functional as they return values to be interpolated into their templates. The function called by the CALL construct may be another templates, or any arbitrary Lisp function.

The if tag is a special case: it supports using an else tag to separate the true and false branches. For example:

<% if posts %>
  <h1>Recent Posts</h1>
  ... loop over posts ...
<% else %>
  No recent posts.
<% end %>

Options

Reference

deftemplate

Syntax:

<% deftemplate name (&rest args) (&rest options) %>
  <body>
<% end %>

Defines a template. The only option that is currently defined is :ESCAPE-HTML (default T)

Examples

if

Syntax:

<% if cond %>
  true branch
<% else %>
  false branch
<% end %>

Implementation

Eco uses esrap to parse templates, which it then compiles down to Common Lisp code.

License

Copyright (c) 2014-2019 Fernando Borretti (fernando@borretti.me)

Licensed under the MIT License.