cgrand/enlive

Unobtrusive auto-selectors

ifesdjeen opened this issue · 1 comments

You can use snippet markers within your HTML template code in order to generate *-prefixed selectors that you can later use within Enlive template.

For example, if you say:

<div snippet="content-main"></div>

You can later reference it with *content-main selector, which will be automatically generated for you.

One of the hidden benefist is that if your application code relies on some element in HTML, here it will be validated, and if there's anything referenced that's not present in HTML, you'll get an exception during compilation, which is good, I think.

For example, having an html template such as:

<!DOCTYPE html>
<html lang="en">
  <head>
    <title>App Layout</title>
  </head>
  <body>
    <div snippet="content-main">
      <ul snippet="simple-list">
        <li snippet="simple-list-item">${value}</li>
      </ul>
    </div>
  </body>
</html>

You can do:

(ns clojurewerkz.gizmo.enlive-test
  (:require [net.cgrand.enlive-html :as html])
  (:use clojure.test
        clojurewerkz.gizmo.widget
        clojurewerkz.gizmo.enlive))

(deftest defsnippet-test
  (defsnippet defsnippet-test-snippet-1 "templates/snippets/sniptest.html"
    [*content-main]
    [values]
    [*simple-list [*simple-list-item]] (html/clone-for [value values]
                                                       [html/any-node] (html/replace-vars {:value value})))

  (is (= (render* (defsnippet-test-snippet-1 ["a" "b" "c"]))
         "<div snippet=\"content-main\">
      <ul snippet=\"simple-list\">
        <li snippet=\"simple-list-item\">a</li><li snippet=\"simple-list-item\">b</li><li snippet=\"simple-list-item\">c</li>
      </ul>
    </div>")))

Where *content-main, *simple-list, *simple-list-item are symbols generated from HTML markup.

These symbols will throw an exception during compile time if they're gone from HTML markup.
They're unobtrusive (you can use different HTML ids and all other attributes without breaking application code).
You don't have to write complex (potentially nested) CSS selectors

And idea from Christophe:

You can use id attributes suffixed by # within your HTML template code in order to generate :#id# selectors that you can later use within Enlive template.

For example, if you say:

<div id="content-main#"></div>

You can later reference it with :#content-main# selector, which will be automatically generated for you.

One of the hidden benefits is that if your application code relies on some element in HTML, here it will be validated, and if there's anything referenced that's not present in HTML, you'll get a warning during compilation.

Such ids are automatically removed so duplicate ids won't show up in the output.