yaclml (Yet Another Common Lisp Markup Language) is an HTML generator and HTML template library. yaclml is used as the html templating backend for the ucw web framework.

License: ?

Homepage: http://common-lisp.net/project/bese/yaclml.html

According to the yaclml website, it appears darcs is the preferred method to get current versions:

darcs get http://common-lisp.net/project/bese/repos/yaclml/

Getting the output

When you use the inline-html of yaclml, the rendered HTML gets printed, not returned. If you need to have it in a string, use the following:
  (<:html (<:head (<:title "Hello, world"))
          (<:body (<:h1 "Hello, world")
                  (<:p "Hello, world!!!!!!")))
and you'll get a string.

Using yaclml by itself

If you want, you can use yaclml by itself (not with ucw, maybe with another framework, like araneida) but it seems nobody is doing that so the library is not very friendly by itself: it is not really robust (in the sense that it is very easy to generate an error by providing not-so-carefully contructed input) and there's no documentation whatsoever. That last item I'll try to fix here. Including yaclml as one of the dependecies of your package or by loading it (with (asdf:oos 'asdf:load-op :yaclml)) you can start using the yaclml-in-lisp markup, something like:
(<:html (<:head (<:title "Hello, world"))
	(<:body (<:h1 "Hello, world")
		(<:p "Hello, world!!!!!!")))
That wasn't so hard, was it ? But one of the jewels of yaclml is tal. To be able to load TAL templates you need to perform the following steps. Create a generator:
(defparameter *gen* 
  (make-instance 'yaclml:file-system-generator
		 :cachep nil
		 :root-directories (list "/path/to/my/templates/")))
root-directories is where you will have the templates. I believe a relative path should work. For the whole run of the program one generator might be enough. When you are about to generate a page, you need to generate an environment which will have the key-value pairs that can be used inside the template:
(defparameter *env* (yaclml:make-standard-environment))
That builds an empty environment. The mappings should be passed as the first parameter to make-standard-environment and according to yaclml documentation: "Each binding set can be an alist, an object, a hash table, or any object for which the a method on LOOKUP-TAL-VARIABLE has been defined." Then, we have to pick up the template itself:
(defparameter *tem* (yaclml:load-tal *gen* "hello.html"))
*tem* is a closure, that is, a function, that when run will return the result of "rendering" that template. It takes two parameters, a generator and an environment. If you evaluate *tem* you may get something like:
               IT.BESE.YACLML::GENERATOR)) {BEB9355} >

One usefull function is yaclml:template-truename which returns the name of the template being picked up (or nil if none is found). When you have various root-directories it can help you find out which template is being chosen. For example:

(yaclml:template-truename *gen* "hello.html")
would return

Now we would call *tem* like this:

(funcall *tem* *env* *gen*)
and we would get out the page.

yaclml generator tutorial: http://www.3ofcoins.net/2009/02/07/yaclml-in-pictures-part-i-html-generation/

yaclml templating tutorial: http://www.3ofcoins.net/2010/01/21/yaclml-in-pictures-part-ii-templating/