Note: This is taken from the Chicken Wiki, where a more recent version could be available.
The sxml-templates egg uses sxml-transforms to perform variable substitution on SXML expressions. It defines a record type which represents a SXML template, and includes some procedures for substituting values into that template. The general idea is to enable the use of on-disk files containing only SXML expressions which are loaded and substituted-into as necessary, as opposed to defining procedures which return quasiquoted SXML.
sxml-templates is in the Public Domain and may be reproduced or copied without permission.
(use sxml-templates)
(printf "~A\n" (sxml-template:fill-string
(make-sxml-template '(%data key))
'((key . "value"))))
Will print the string value.
(use sxml-templates spiffy)
(define (my-app:read-sxml-template basename)
(make-sxml-template
(read (open-input-file (string-append "templates/" basename ".scm")))))
(http:add-resource
"/login-form"
(lambda (req args)
(let* ((login-form-template
(my-app:read-sxml-template "login-form-body"))
(login-form-namespace
'((form-method . "POST")
(form-action . "/login-form-post-target")
(username-input-name . "username")
(password-input-name . "password")))
(login-form-template
(sxml-templates:fill login-form-template login-form-namespace)))
; write some response headers, etc
(printf
(sxml-templates:fill-string
(my-app:read-sxml-template "shell")
`((body . ,login-form-template)))))))
templates/shell.scm would look something like:
(html (head (title "My Application")) (body (%data body)))
templates/login-form-body.scm would look something like:
(form
(@ (method (%data form-method))
(action (%data form-action)))
(label "Username")
(input (@ (type "text")
(name (%data username-input-name))))
(label "Password")
(input (@ (type "password")
(name (%data password-input-name))))
(input (@ (type "submit"))))
The resource handler in the example first subtitutes some variables into the login-form-body template, and then substitutes the result into the shell template.
[procedure] (make-sxml-template sxml)
Where sxml is an SXML expression. Returns a sxml-template record.
[procedure] (sxml-template:fill sxml-template namespace)
Where sxml-template is a sxml-template record and namespace is an association list mapping variable names to values. This will replace all instances of (%data name) in sxml-template's underlying SXML with the result of (alist-ref 'name alist), and return a new sxml-template record. If a value in namespace is a filled sxml-template, then the right thing will happen. If a value is a list, then it is assumed to be vanilla SXML and will be converted using SXML's universal-conversion-rules. If a value is mentioned in the template's SXML which does not have a corresponding entry in the alist, then an error will be signalled. See sxml-template:fill-string for an equivalent which results in a string of XML, and sxml-template->string for a procedure which will convert a filled sxml-template record (as returned by this procedure) to a string of XML.
[procedure] (sxml-template? x)
Returns a boolean indicating whether x is of the sxml-template record type.
[procedure] (sxml-template:filled? sxml-template)
Returns a boolean indicating whether sxml-template has been filled (see sxml-template:fill).
[procedure] (sxml-template:sxml sxml-template)
Returns the value of the sxml argument in the make-sxml-template call which was used to construct the given sxml-template.
[procedure] (sxml-template:fill-string sxml-template namespace)
Similar to sxml-template:fill, but results in an XML string. Defined as (compose sxml-template->string sxml-template:fill).
[procedure] (sxml-template->string sxml-template)
Converts a filled sxml-template record (as returned by sxml-template:fill) into an XML string.