Source on Github

Calliope

A Haml Parser for Elixir

Calliope is a parser written in Elixir that renders Haml and Elixir to HTML.

Haml & Elixir

!!! 5
%html{lang: "en-US"}
  %head
    %title Welcome to Calliope
  %body
    %h1 Calliope
    %h2 The muse of epic poetry

HTML

<!DOCTYPE html>
<html lang="en-US">
  <head>
    <title>Welcome to Calliope</title>
  </head>
  <body>
    <h1>Calliope</h1>
    <h2>The muse of epic poetry</h2>
  </body>
</html>

Usage

If you prefer the poetic beauty of Haml templates over HTML, then Calliope is the package for you. Calliope is a parser written in Elixir that will render Haml/Elixir templates into HTML.

Calliope is simple to add to any project. If you are using the hex package manager, just add the following to your mix file:

def deps do
  [ { :calliope, "0.2.1" } ]
end

If you aren’t using hex, add the a reference to the github repo.

def deps do
  [ { :calliope, github: "nurugger07/calliope" } ]
end

Next, run mix deps.get in the shell to fetch and compile the dependencies. Then you can either call to Calliope directly:

iex(1)> Calliope.render "%h1 Welcome to Calliope"
"<h1>Welcome to Calliope</h1>"

Or use Calliope in a module and call through your module:

defmodule MyModule do
  use Calliope
end
iex(1)> MyModule.render "%h1 Welcome to Calliope"
"<h1>Welcome to Calliope</h1>"

Formatting

Refer to the Haml reference page for syntax information. Most of the syntax has been accounted for, but more functionality is being added.

Haml is basically a whitespace-sensitive shorthand for HTML that does not use end tags. Although Calliope uses Haml formatting, it has its own flavor.

Have a look:

%tag{ attr: "", attr: "" } Content
%tag(attr="" attr="") Content

The id and class attributes can also be assigned directly to the tag:

%tag#id.class Content

If you’re creating a div, you don’t need to include the tag at all. This Haml:

#main
   .blue Content

Will generate the following HTML:

<div id='main'>
  <div class='blue'>
    Content
  </div>
</div>

Passing Arguments

The render function will also take a list of named arguments that can be evaluated when compiling the HTML.

Given the following Haml:

#main
   .blue= content

Call render and pass in the haml and content:

Calliope.render haml, [content: "Hello, World"]

Calliope will render:

<div id='main'>
  <div class='blue'>
    Hello, World
  </div>
</div>

Embedded Elixir

Calliope doesn’t just evaluate arguments. You can actually embed Elixir directly into the templates:

- for name <- names do
  %h1
    %p= name

Pass the above to render with a list of posts:

Calliope.render haml, [names: ["Johnny", "Rye"]]

Which renders:

<h1>
  <p>Johnny</p>
</h1>
<h1>
  <p>Rye</p>
</h1>

Precompile Templates

Calliope provides an engine to precompile your Haml templates into functions. This parses the template at compile time and creates a function that takes the name and args needed to render the page. These functions are scoped to the module that uses the engine.

Adding this functionality is easy.

defmodule Simple do
  use Calliope.Engine

  def show do
    content_for(:show, [title: Calliope])
  end
end

If you are using layouts, you can set the layout and call the content_with_layout function.

defmodule Simple do
  use Calliope.Engine, layout: "application"

  def show do
    content_with_layout(:show, [title: Calliope])
  end
end

In addition to :layout you can also set the following options:

:path
provides the root path. The default is the current working directory.
:templates
is used to define where the templates are stored. By default it will use :path.
:alias
is used to set the directory where the templates are located. The default value is templates.
:layout_directory
is the directory where your layouts are stored relative to the templates path. The default directory is layouts.
:layout
is the layout to use for templates. The default is :none, or you can pass in the name of a layout.

Coming Soon

  • Rendering Elixir conditionals
  • Rendering partials
  • Rendering exception messages