Skip to content

Javascript template language with DRY HTML. Modified to be similar to Haskell Hamlet.

License

Notifications You must be signed in to change notification settings

ajnsit/hamlet.js

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

44 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Hamlet Html Templates for javascript

Hamlet is just html without redundancies. The big deal is that it uses your white space to automatically close tags. You already properly indent your tags right? Computers are supposed to automate things - lets have them close tags for us.

This is similar in concept to HAML. However, HAML abandons html syntax without justification. If we just apply significant white-space and a few other html-compatible shortcuts to regular HTML, we can get the benefit without the drawback. Designers that have used the Haskell version of Hamlet have really liked it.

I created this with client-side templates in mind, but it works server side with node.js

Syntax

<body>
    <p>Some paragraph.
    <ul>
        <li>Item 1
        <li>Item 2

That hamlet is equivalent to:

<body>
  <p>Some paragraph.</p>
  <ul>
    <li>Item 1</li>
    <li>Item 2</li>
  </ul>
</body>

Lets show some interpolation and CSS shortcuts:

<.foo>
  <span#bar data-attr={{foo}}>baz # this is a comment

That template invoked with: Hamlet(template, {foo:'f'}). generates:

<div class="foo"><span id="bar" data-attr="f">baz </span></div>

The library currently does not try to pretty print the resulting html, although it wouldn't be hard to do. Note the mustache style interpolation {{var}}. I have never had the opportunity to use mustache templates - this was simply easier to implement than some alternatives. You can put any javascript you would like in the interpolation.

Overview

It is just HTML! But redundancies are taken away

  • quoting attributes is not required unless they have spaces
  • Indentation is used to automatically close tags.

This loosely follows the original Haskell Hamlet template language that I helped design. This implementation is simpler because it is invoked at runtime, just does a simple javascript eval, and has no concept of type insertion - this includes no html escaping.

Usage

This uses the same style and code as the template function from underscore.js

rendered_html = Hamlet(template, object)

or

pre_compiled_template = Hamlet(template)
rendered_html = pre_compiled_template(object)

Or you can avoid all variable assertion and just expand hamlet with:

Hamlet.toHtml('<p>') // "<p></p>"

class/id shortcuts

The CSS-based shortcuts are originally taken from the HAML markup language. A '#' indicates an id, and a '.' indicates a class. You can add as many classes this way as you like.

Comments

Comments begin with a '#' character. When the template is compiled they are removed, not converted to html comments. There is no support for html comments.

White space

Using indentation does have some consequences with respect to white space. This library is designed to just do the right thing most of the time. This is a slightly different design from the original Haskell implementation of Hamlet.

A closing tag is placed immediately after the tag contents. If you want to have a space before a closing tag, use a comment sign # on the line to indicate where the end of the line is.

<b>spaces  # 2 spaces are included
<b>spaces  </b>

White space is automatically added after tags with inner text. If you have multiple lines of inner text without tags (not a common use case) they will also get a space added. If you do not want white space, you point it out with a > character, that you could think of as the end of the last tag, although you can still use it when separating content without tags onto different lines. You can also use a > if you want more than one space.

<p>
  <b>no space
  >none here either.
  >  Two spaces after a period is bad!
<p><b>no space</b>none here either.  Two spaces after a period is bad!</p>

Closing bracket

currently the '>' character is optional if there is no inner text on the same line. In the future this will be changed to be required so that tag attributes can span multiple lines.

Limitations

Hamlet just uses a simple eval interpolation. This works well for me on an AngularJS project where AngularJS is actually doing the templating. You might be able to use Hamlet to pre-process for another templating system.

Development

Requires Coffeescript, although if you are only comfortable changing js I can easily port it to the Coffeescript file.

Testing

The test suite is pretty good now. I create a test case for every issue I notice.

I wanted to run tests without the browser overhead. Probably there is a better way, but I came up with this which works fine:

coffee -cb hamlet.coffee && coffee -cb test.coffee && cp hamlet.js runtests.js && cat test.js >> runtests.js && node runtests.js && echo "PASS" || echo "FAIL"

You could run the tests in a browser or elsewhere though. Note it requires coffee: npm install coffee-script && ln -s node_modules/coffee-script/bin/coffee coffee

Test cases can be ported from the Hamlet test suite

About

Javascript template language with DRY HTML. Modified to be similar to Haskell Hamlet.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • CoffeeScript 100.0%