-
Notifications
You must be signed in to change notification settings - Fork 0
Design and templating
Many Clojure web applications use Hiccup for HTML templating. If the programmer is also the designer, then Hiccup is ideal. However, most developers are bad at design. We need to work with people who are good at design and who don't need to care about Clojure. ClojureScript One proposes one approach to templating which allows designers to work with HTML, CSS and images without having to set an eye on Hiccup data structures or those pesky parentheses.
A typical designer workflow will look something like this:
- Run
lein repl
- Type
(dev-server)
to launch the development server - Open a browser to
http://localhost:8080
and click the Design button - Click on links to individual pages to assess the current look and feel of each page
- Add/Edit files in the
templates
directory, add CSS and images topublic/css
andpublic/images
- Update links to the above files by editing
public/design.html
- Go to step 4 and repeat until the designer is happy
Any changes made to template HTML files can be seen in the browser upon refresh.
ClojureScript One doesn't care how you create HTML. The templating system discussed here is not used by the running application. Its only purpose is to make designers' lives a little better.
To avoid repetition, two new HTML elements are introduced: _include
and _within
.
_include
will include another HTML file in the current file and _within
indicates that its content is to be included in another template. When using the _within
tag, HTML ids are used to determine which elements are to be replaced.
A simple example will show how these new tags may be used.
Suppose we have a layout file templates/layout.html
which contains the following HTML:
<html>
<head>Example</head>
<body>
<_include file="menu.html"/>
<div id="content"></div>
<div id="footer"></div>
</body>
</html>
Furthermore, suppose we have the following two files named templates/menu.html
and templates/example.html
.
<!-- templates/menu.html -->
<div>Navigation Menu</div>
<!-- templates/example.html -->
<_within file="layout.html">
<div id="content">New Content</div>
<div id="footer">A Footer</div>
</_within>
If we point the server at http://localhost:8080/design/example.html
, the following file will be served:
<html>
<head></head>
<body>
<div>Navigation Menu</div>
<div id="content">New Content</div>
<div id="footer">A Footer</div>
</body>
</html>
Templating works with files in the templates
directory and the public
directory. To see other examples, look at the HTML files in these directories..
How does the HTML that the designers work with end up in the ClojureScript application? Enlive is an HTML transformation library for Clojure. We use it to extract snippets of HTML and insert them into the application.
You may be wondering how this is possible given that Enlive is a Clojure library and we are working in ClojureScript. That is a great question. The answer can be found in how ClojureScript macros work.
The snippets of HTML that are used in the application are created with the snippets
macro shown below.
(defn snippet [file id]
(render (html/select (html/html-resource file) id)))
(defmacro snippets []
{:form (snippet "form.html" [:div#content])
:greeting (snippet "greeting.html" [:div#content])})
Enlive is used to grab two chunks of HTML from the design HTML pages. In both cases it is a div
element with a "content" id. Notice that snippets
is a macro. In ClojureScript, macros are Clojure macros and run only at compile time. This means we can use any Clojure library from a macro.
The JavaScript application we are creating must be hosted within an HTML page. The layout for the host page is contained in a file named templates/application.html
. The Clojure namespace one.host-page
contains the code for generating the host page for development mode, production mode and for building the deployment artifacts.
JavaScripts which are added to the host page can be configured in the one.sample.config
namespace.