About

Flamethrower is a simple HTML template engine for Haskell.

cabal install flamethrower

Syntax

Elements

A lone identifier, consisting of any numbers of letters, numbers, or hyphens, defines an element.

p
<p></p>

Current HTML5 void tags are recognized automatically:

link
<link>

Strings

Strings are surrounded by double quotes. Interpolated code sections are delimited by #{ and }.

"Congratulations; you’re visitor ##{show visitorCount}! You have won a prize."
Congratulations; you’re visitor #20! You have won a prize.

Text, both inside and outside of interpolated sections, is escaped as appropriate depending on context. To turn this off, add an exclamation mark as a prefix:

"<p id=\"user-content\">#{markdown input}</p>\n"
!"<p id=\"user-content\">#{markdown input}</p>"
&lt;p id="user-content"&gt;&lt;em&gt;Hello, world!&lt;/em&gt;&lt;/p&gt;
<p id="user-content"><em>Hello, world!</em></p>

Backslash escape codes are the same as those supported in Haskell, with the addition of \# to escape interpolation.

Attributes

Identifiers followed by colons are treated as attribute names. A string following an attribute name is treated as its value; attribute values cannot be raw (unescaped) strings.

header id: "example"
<header id="example"></header>

Classes

A leading period makes an identifier a class.

div.do .not .mix.spaces.like.this
<div class="do not mix spaces like this">

Hierarchy

Hierarchy in Flamethrower is currently entirely whitespace-based. Anything after or inside an element (after it on the same line or inside an indented block beneath it) is considered its child.

doctype

html
	head
		meta charset: "utf-8"

		title "Example Page"

		link
			rel: "stylesheet"
			type: "text/css"
			href: "/stylesheets/default.css"

	body
		p id: "welcome" "Hello, "
			em "world"
			"!"

		a "Visit a most exciting destination"
			href: "http://example.com/"
<!DOCTYPE html><html><head><meta charset="utf-8"><title>Example Page</title></head><body><p id="welcome">Hello, <em>world</em>!</p><a href="http://example.com/">Visit a most exciting destination</a></body></html>

Special blocks

if

An if block takes a Haskell expression as a condition and includes its content if the condition is True. An else block may immediately succeed it.

p
	"#{n} cact"
	if n == 1
		"us"
	else
		data-plural:
		"i"
<p data-plural>5 cacti</p>

for

A for block takes a Haskell variable name and a list expression and includes its content for each item in the list.

Unlike an if block, it doesn’t make sense for it to contain attributes or classes.

ul
	for item in ["one", "two", "three"]
		li "#{item}"
<ul><li>one</li><li>two</li><li>three</li></ul>

API

Flamethrower.flamethrower :: QuasiQuoter

A quasiquoter for Flamethrower templates. Usable in expression context.

hello name = [flamethrower|p "Hello, #{name}."|]

Flamethrower.flamef :: QuasiQuoter

A quasiquoter for Flamethrower template files. Usable in expression context.

hello name = [flamef|hello.flame|]

Changelog

0.0.3.0

Added for loops.

0.0.2.1

Added doctype and if/else special blocks; changed templates to generate Data.Text text.

0.0.1.3

A basic indentation-based-template-to-HTML compiler, with support for interpolation. No special blocks have been implemented. Errors don’t point to a specific origin.