Table of Contents
SISCweb programs can generate HTTP responses of a variety of data types -- HTML/XML/XHTML represented in SXML notation, images --, or they can forward requests to standard JSPs/Servlet components. Procedures to generate HTTP errors are also available. Other response types can be easily plugged on top of a basic set of response procedures.
The procedures that produce HTTP responses are in the form
send-*/*
, with the first pattern indicating
the type of response, and the latter determining whether or not to
save the execution state, and whether or not to clear previously
saved states.
All the procedures accept an optional association list of HTTP
response headers as the first, optional argument. The association
list is in the form ((name value)
...)
. This can be used to override the default
Content-Type, to set caching options, etc.
SISCweb provides a number of modules with an uniform API to produce HTML, XHTML and XML markup. Their procedures accept documents in SXML syntax, and in the case of HTML and XHTML, a few extra elements and attributes are used to assist with continuation-based programming (see the section called “Extended HTML markup”.)
Requires:
(import siscweb/html)
Requires:
(import siscweb/xhtml)
Located in:
siscweb-sxml.jar
The core procedures to send (X)HTML content follow the basic
send-html/*
and
send-xhtml/*
patterns. They differ in
whether or not they clear the continuation table, and whether
or not they return after the user interacts with the page.
The XHTML and HTML modules serialize SXML differently, with the former producing pure XML, and the latter producing markup tweaked to display properly in known browsers. When producing XHTML for common user agents, it is advisable to keep the HTML Compatibility Guidelines in mind.
Also, while the XHTML module implements the complete SXML
specification, the HTML module is more limited in that only
understands DTD declarations,
*VERBATIM*
and
*COMMENT*
elements besides the basic
element+attribute syntax. Also, while the XHTML module
considers the *TOP*
element functional,
the HTML module silently ignores it.
procedure:
(send-html/suspend [header-alist] (lambda (k-url) <sxml>)) => request
procedure:(send-xhtml/suspend [header-alist] (lambda (k-url) <sxml>)) => request
Sends the given SXML to the browser in the form of (X)HTML and suspends the execution flow. The
k-url
will contain a hash used to resume the program's execution, and should therefore be used in forms and links as needed. When the browser submits a request to thek-url
, said request will become the return value of the procedure.
(let loop ((n 0)) (send-html/suspend (lambda (k-url) `(html (body (a (@ (href ,k-url)) ,n))))) (loop (+ n 1)))
procedure:
(send-html/forward [header-alist] (lambda (k-url) <sxml>)) => request
procedure:(send-xhtml/forward [header-alist] (lambda (k-url) <sxml>)) => request
These procedures behave like
send-html/suspend
andsend-xhtml/suspend
, except that they clear the continuation table first. This will prevent the client from using the back button to resume the program flow from earlier points.
procedure:
(send-html/back [header-alist] <sxml>) => does not return
procedure:(send-xhtml/back [header-alist] <sxml>) => does not return
These procedures send the provided SXML to the browser and stop.
(send-html/back `(html (body (a (@ (href "http://www.w3.org")) "w3c"))))
Requires:
(import siscweb/xml)
Located in:
siscweb-sxml.jar
This module provides functions to send XML responses with the
same features as those in the HTML and XHTML modules. This
enables clients to conduct a stateful conversation with the
server. The same features available through the extended
(X)HTML can be reproduced in any XML element by using the
store/forward!
procedure described in
the section called “Forwarding Requests”.
procedure:
(send-xml/suspend [header-alist] (lambda (k-url) <sxml>)) => request
procedure:(send-xml/forward [header-alist] (lambda (k-url) <sxml>)) => request
procedure:(send-xml/back [header-alist] <sxml>) => does not return
procedure:(send-xml/finish [header-alist] <sxml>) => does not return
These functions are analogous to those in the HTML and XHTML modules.
SISCweb's send-[html/xhtml/xml]/*
procedures accept a slightly extended version of the SXML
syntax.
The send-html/*
procedures transform
symbols in the markup into entities. This usage is now
deprecated, and the form (& name)
should be used instead for HTML, XHTML and XML.
(send-html/back `(html (body (p "Can't" (& nbsp) "wrap" (& nbsp) "me.") (p "Nor" (& |#160|) "me."))))
Numbers in attributes and text nodes are automatically
converted to strings using pretty-print
.
(send-html/back `(html (body (table (@ (width 42)) (tr (td 42))))))
The value #f as an element or attribute value is ignored. This comes handy when generating dynamic content.
;; equivalent to (html (body (p))) (send-html/back `(html (body (p (@ (align #f)) ,(hashtable/get ht 'para)))))
The element *VERBATIM* can be used to produce non-escaped text.
(send-html/back `(*VERBATIM* "<html><body><p>Hello, "world"</p></body></html>))
The elements *DTD-INFO* and *DTD-INFO/PUBLIC* can be used to generate DTD declarations. For XML/XHTML only, the *PI* element should be used to generate the XML declaration.
(send-xhtml/back `(*TOP* (*PI* xml "version=\"1.0\"") (*DTD-INFO/PUBLIC* "html" "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd") (html (@ (xmlns "http://www.w3.org/1999/xhtml") (xml:lang "en") (lang "en")) (head (title "Hello")) (body (p "Hello")))))
The HTML and XHTML modules support a number of extra attributes to support continuation-centric programming and interaction with the J2EE environment.
attribute:
`(a (@ (bindings ,binding-alist [(anchor name)]...) ...)
attribute:`(form (@ (bindings ,binding-alist) [(anchor name)] ...) ...)
attribute:`(iframe (@ (bindings ,binding-alist) [(anchor name)] ...) ...)
attribute:`(img (@ (bindings ,binding-alist) ...) ...)
attribute:`(link (@ (bindings ,binding-alist) ...) ...)
attribute:`(object (@ (bindings ,binding-alist) [(anchor name)] ...) ...)
attribute:`(script (@ (bindings ,binding-alist) ...) ...)
This syntax is only usable from the
*/suspend
and*/forward
procedures. It will produce a link that, when followed, will bind the given bindings to the request object returned by these two functions. Thebinding-alist
is in the format specified in Chapter 6, Request Bindings.The optional
anchor
attribute allowed by some of the elements is made part of the generated URL.
attribute:
`(a (@ (href-p ,proc) [(bindings ,binding-alist)] [(anchor ,name)] ...) ...)
attribute:`(form (@ (action-p ,proc) [(bindings ,binding-alist)] [(anchor ,name)] ...) ...)
attribute:`(iframe (@ (src-p ,proc) [(bindings ,binding-alist)] [(anchor ,name)] ...) ...)
attribute:`(img (@ (src-p ,proc) [(bindings ,binding-alist)] ...))
attribute:`(link (@ (href-p ,proc) [(bindings ,binding-alist)] ...))
attribute:`(object (@ (data-p ,proc) [(bindings ,binding-alist)] [(anchor ,name) ...) ...)
attribute:`(script (@ (src-p ,proc) [(bindings ,binding-alist)] ...) ...)
These attributes produce links that invoke the given procedure
proc
when followed. The HTTP request object will be passed as the only parameter to the procedure, and will contain the bindings specified inbinding-alist
, if present.In the case of
@action-p
, the form field values and the specified bindings will be merged, with the latter taking precedence over the former.The optional
anchor
attribute allowed by some of the elements is made part of the generated URL.
attribute:
`(a (@ (href-c ,c-url) [(bindings ,binding-alist)] ...) ...)
attribute:`(form (@ (action-c ,c-url) [(bindings ,binding-alist)] ...) ...)
attribute:`(iframe (@ (src-c ,c-url) [(bindings ,binding-alist)] ...))
attribute:`(img (@ (src-c ,c-url) [(bindings ,binding-alist)] ...))
attribute:`(link (@ (href-c ,c-url) [(bindings ,binding-alist)] ...))
attribute:`(object (@ (data-c ,c-url) [(bindings ,binding-alist)] ...) ...)
attribute:`(script (@ (src-c ,c-url) [(bindings ,binding-alist)] ...) ...)
These attributes allow specifying URLs relative to the context in which the SISCweb application is running. They are useful to reference plain HTML files or JSPs that co-exist in the same context. If any bindings are specified, they will be included in the request associated to the
c-url
.The
anchor
attribute is not allowed, as it can be directly specified in thec-url
parameter.
attribute:
`(a (@ (href-e ,url) ...) ...)
attribute:`(form (@ (action-e ,url) ...) ...)
attribute:`(iframe (@ (src-e ,url) ...))
attribute:`(img (@ (src-e ,url) ...))
attribute:`(link (@ (href-e ,url) ...))
attribute:`(object (@ (data-e ,url) ...) ...)
attribute:`(script (@ (src-e ,url) ...) ...)
These attributes encode the given
url
as per the the JavaHttpServletResponse.encodeURL()
method. This is useful to support cookie-less interaction, as it will encode the session ID in theurl
as needed.The
anchor
attribute is not allowed, as it can be directly specified in the <attribute>c-url</attribute>.
attribute:
`(object (@ (type "graphviz") (layout ,layout) (format ,format) ...) (graph (@ (id ,id) ...))
If the attribute
type "graphviz"
is specified for theobject
element, a Graphviz graph will be embedded in the document.The
layout
andformat
attributes are analogous to the omonymous parameters to thesend-graphviz/*
functions (see the section called “Graphviz Procedures”.) However, the value offormat
determines how the content is included:
gif, jpg, png
: The graph is embedded as animg
tag, and a corresponding image map is generated. Links associated to nodes, edges and records will be mapped appropriately. Just as for other document elements, the@href[-[p|c|e]]
and@bindings
attributes are available, and behave as described in the section called “Extended HTML markup”.ps, svg, etc.
: The graph is embedded as anobject
tag. The appropriate mime type is automatically set, and needs not be specified explicitely.In both cases, any attribute specified for the
object
tag will be applied toward the generatedobject
orimg
tag.
(send-html/suspend (lambda (k-url) `(html (head (title "Embedded Graphviz") (body (h3 "Embedded Graphviz") (object (@ (type "graphviz") (layout dot) (format png)) (graph (@ (id "G")) (node (@ (id "c") (label "scissors") (href "http://www.google.com/search?q=scissors"))) (node (@ (id "p") (label "paper") (href "http://www.google.com/search?q=paper"))) (node (@ (id "s") (label "stone") (href "http://www.google.com/search?q=stone"))) (edge (@ (from "c") (to "p") (label "cut") (href-p ,cut))) (edge (@ (from "p") (to "s") (label "wraps") (href-c "/"))) (edge (@ (from "s") (to "c") (label "breaks") (href-e ,k-url))))))))))
Requires:
(import siscweb/text)
Located in:
siscweb.jar
This module provides functions to send plain text responses.
procedure:
(send-text/suspend [header-alist] (lambda (k-url) <text>)) => request
procedure:(send-text/forward [header-alist] (lambda (k-url) <text>)) => request
procedure:(send-text/back [header-alist] <text>) => does not return
procedure:(send-text/finish [header-alist] <text>) => does not return
These functions are analogous to those in the HTML and XHTML modules.
Requires:
(import siscweb/forward)
Located in:
siscweb.jar
Since SISCweb lives in a J2EE environment, it is sometimes convenient to generate content using traditional techniques such as JSPs and servlets rather than SXML.
The send-forward/*
procedures dispatch the
request to the indicated context-relative URL. Bindings can be
attached in the form of <bindings> objects or a-lists. The
forward/store!
function can also be used to
pass URLs mapped to closures in the style of the
@[action|data|href|src]-p
tags. Coupled
with the URL corresponding to the current-continuation being set
in the siscweb.kURL
request attribute,
this enables one to use SISCweb for control and JSP/Servlets
for presentation without losing too many features.
See the section called “Extracting Bindings from Java” for details on how to access bindings from Java.
procedure:
(send-forward/suspend context-url [bindings]) => request
Forwards the current request and suspends. The
context-url
is relative to the context in which the SISCweb application is running. The optionalbindings
parameter is either a <bindings> object or an a-list as specified in Chapter 6, Request Bindings. The continuation URL will be set in thesiscweb.kURL
request attribute.
procedure:
(send-forward/forward context-url [bindings]) => request
This function behaves like
send-forward/suspend
, except that it clears the continuation table first. This will prevent the client from using the back button and resume the program flow from earlier points.
procedure:
(send-forward/back context-url [bindings]) => does not return
Forwards the current request to the provided
context-url
and stops.
procedure:
(send-forward/finish context-url [bindings]) => does not return
Like
send-forward/back
, this function forwards the current request to the providedcontext-url
and stops, but clears the continuation table first.
procedure:
(forward/store! proc [bindings]) => k-url
procedure:(forward/store! c-url [bindings]) => k-url
In the first form, stores a closure
proc
in the continuation table, and returns the url that will invoke it. Theproc
procedure should accept a request object as its only argument. Ifbindings
are specified, either as an a-list or a <bindings> object,will see them as bindings in its request.In the second form
forward/store!
stores a closure that forwards the request to the given context-relativec-url
, including any specified bindings, if any.This function is especially useful when passing bindings through the
send-forward/*
functions, as it allows to embed links to closures in JSPs and the such, and can thus be used to implement the same style of page navigation afforded by the tags@*-c
+@bindings
and@*-c
+@bindings
in the extended (X)HTML described in the section called “Extended HTML markup” Notably missing is the equivalent of the plain@bindings
.
procedure:
(forward/store! proc [bindings]) => k-url
This procedure is similar to the first form of
forward/store!
, except that whenproc
is executed, it will run in the dynamic context in effect whenforward/dynenv/store!
is invoked.The main reason to use this procedure is that
proc
will see the same SRFI-39 parameter bindings established at the timeforward/dynenv/store!
was called.
Requires:
(import siscweb/image)
Located in:
siscweb.jar
This module provides procedures to send images from
java.awt.image.RenderedImage
or files.
procedure:
(send-image/back [header-alist] format java.awt.image.RenderedImage) => does not return
Sends the given image to the browser in the specified
format
.
procedure:
(send-image/finish [header-alist] format java.awt.image.RenderedImage) => does not return
This procedure behaves like
send-image/back
, except that it clears the continuation table. This will prevent the user from using the back button to resume the program flow from earlier points.
Requires:
(import siscweb/graphviz)
Located in:
siscweb-sxml.jar
This module provides procedures to send graphs in various formats as generated by Graphviz (http://www.graphviz.org). Most of the functions accept a markup representation of DOT, the GraphViz language, in the form of DotML (see the section called “DotML”.)
The GraphViz programs (dot, neato, etc.) should be installed
somewhere in the system path. This is usually the case in
UNIX. Alternatively, it is possible to set the absolute paths to
the GraphViz programs by using the
graphiz/put-layout-command!
function.
Graphs can be generated either using the
send-graphviz/*
functions, or by embedding
the @type="graphviz"
attribute
in the (X)HTML object
tag (see the section called “Extended HTML markup”.)
Both send-graphviz/*
procedures accept
the same three parameters:
layout
: This is a string specifying
which Graphviz layout engine to use. The current choices are
dot, neato, twopi, circo, and fdp.
format
: This is a string specifying
the output format. The most useful choices currently are
gif, jpg, 'png, 'ps, and 'svg.
<dotml>
: This is an sxml
representation of the DotML language. See the section called “DotML”.
procedure:
(send-graphviz/back layout format <dotml>) => does not return
Sends the given
dotml
graph in the specifiedformat
to the browser after laying the graph out using the indicatedlayout
engine.
(send-graphviz/back 'dot 'png `(graph (@ (id "G")) (node (@ (id "c") (label "scissors"))) (node (@ (id "p") (label "paper"))) (node (@ (id "s") (label "stone"))) (edge (@ (from "c") (to "p") (label "cut"))) (edge (@ (from "p") (to "s") (label "wraps"))) (edge (@ (from "s") (to "c") (label "breaks")))))
procedure:
(send-graphviz/finish layout format <dotml>) => does not return
This procedure behaves like
send-graphviz/back
, except that it clears the continuation table. This will prevent the user from using the back button to resume the program flow from earlier points.
procedure:
(graphviz/put-layout-command! layoutcommand) => undefined
Associates a given
layout
to the specifiedcommand
. This function can be used to add Graphviz layout engines, or to specify absolute paths for existing engines. The latter is likely to be an issue in Windows.
(graphviz/put-layout-command "dot" "d:/bin/dot.exe")
The send-graphviz/*
procedures accept a
graph description expressed in DotML. DotML was created by
Martin Loetzsch, and an exhaustive description rich with
excellent examples is at http://www.martin-loetzsch.de/DOTML.
SISCweb does not use code from the DotML project, but it implements the same markup syntax in sxml form. There are a few differences between SISCweb's implementation and the original:
graph
,
sub-graph
, cluster
and node
elements must always specify
an id
attribute.
id
attribute values at the moment
are limited to strings of alphanumeric characters and
underscore.
record
elements must
specify an id
attribute, but nested
record
and node
elements do not have to.
Requires:
(import siscweb/error)
Located in:
siscweb.jar
HTTP error responses can be generated using two functions, which differ in how the affect the continuation table. Neither function returns. The error codes should abide to the RFC2616 specifications.