X-HTML-TEMPLATE library is a little fork of the Common Lisp library html-template which adds support for computed expressions while keeps mostly compatible. See the differences with html-template below.
I wrote this because we were using too many html-templates and migrating to a new template system was not worth. We wanted some extra flexibility however and it made our lives easier.
The HTML-TEMPLATE API is untouched (see its documentation if you are
not used HTML-TEMPLATE before), except the system name and packages
were renamed to X-HTML-TEMPLATE, to avoid possible collisions. A
package nickname x-template is also provided as shortcut.
X-HTML-TEMPLATE changes the semantic of the template attributes. The tags accept expressions instead of symbols. The expressions follow the following syntax:
expression ::= 'literal'
| "literal"
| symbol
| symbol(expression_1,expression_2,..,expression_N)
A hypothetical template could look like
<!-- tmpl_loop sort(users,'name') -->
<!-- tmpl_var escape-html(upcase(name)) -->
<!-- /tmpl_if -->
<!-- /tmpl_loop -->
This change diverges from the philosophy of HTML-TEMPLATE about separation of the code and the layout. However, this library does not provide harmful abstractions itself, but it offers the ability to provide them :-)
I really think that used properly, the extensions can be useful.
A simple use:
(with-output-to-string (*default-template-output*)
(fill-and-print-template
"<!-- tmpl_var html-escape(string) -->"
(list :string "0 <> 1" :html-escape #'escape-string-all)))=>
"0 &lt;&gt; 1"
Sometimes, it is convenient to provide a default set of user-defined
function values to the templates. You can set the special variable
*VALUE-ACCESS-FUNCTION* to provide them. The code would look like:
(defvar *x-template-default-values*
(list :html-escape #'escape-string-all))
(unless (boundp '*original-value-access-function*)
(defvar *original-value-access-function*
*value-access-function*))
(setf *value-access-function*
(lambda (symbol values &optional in-loop)
(or (funcall *original-value-access-function* symbol values in-loop)
(getf *x-template-default-values* symbol))))Then, we can write the above example without defining the html-escape function.
(with-output-to-string (*default-template-output*)
(fill-and-print-template
"<!-- tmpl_var html-escape(string) -->"
(list :string "0 <> 1")))X-HTML-TEMPLATE is not fully compatible with HTML-TEMPLATE, but it is in the common cases and porting your code should be trivial.
HTML-TEMPLATE allows to quote an attribute as <!-- tmpl_var 'foobar' -->
As ‘foobar’ is a literal string in X-HTML-TEMPLATE, this code will not
work in the same way. To port it, just remove the single or double
quotes. However, if you are quoting the symbol because it contains
spaces or non-allowed characters, then you will have to rename your
symbol.
HTML-TEMPLATE white-spaces delimiters after the template start marker are optional and you could omit them if you quote the parameters. In X-HTML-TEMPLATE, quoting parameters is not allowed, but the white-spaces are optional anyway.
Therefore, a template like <!-- tmpl_var foo--> which is not legal
in HTML-TEMPLATE, will be in X-HTML-TEMPLATE. It could seem weird,
but it becomes useful if you override the default tag
markers. Consider, for example:
<tmpl_var foo> in contrast to <tmpl_var foo >.
A full working example:
(let ((*template-start-marker* "<")
(*template-end-marker* ">"))
(with-output-to-string (*default-template-output*)
(x-template:fill-and-print-template "<tmpl_var foo>" '(:foo "bar"))))