Fix typos and do some rephrasing.

This commit is contained in:
interp 2004-09-17 15:54:21 +00:00
parent 58a540854f
commit d904121149
3 changed files with 158 additions and 157 deletions

View File

@ -18,7 +18,7 @@ add the \surflet handler to it, which resides in the
\begin{alltt}
(httpd
(make-httpd-options
\dots
\dots \\
with-request-handler
(alist-path-dispatcher
(list
@ -33,9 +33,10 @@ requests directed to \surflets. Here's the interface description:
\defun{surflet-handler}{options}{request-handler}
\begin{desc}
This procedures sets up the \surflet handler and returns the request
handler for the SUnet webserver. The options argument is similar to
the one passed to \ex{httpd} and is exlpained below.
This procedures sets up the \surflet handler and returns the
according request handler for the SUnet webserver. The options
argument is similar to the one passed to \ex{httpd} and is exlpained
below.
The \surflet handler accepts requests (solely) to \surflets whose
file name must have the extension \ex{.scm}. The structure of
@ -127,7 +128,7 @@ For example,
\end{alltt}
defines the \surflet handler to serve \surflets from the directory
\ex{root/surflets} and to timeout unused session after one hour.
\ex{root/surflets} and to timeout unused sessions after one hour.
The \surflet handler allows runtime read and write access to her
options:
@ -188,12 +189,14 @@ the Scheme48 module language. See the documentation of Scheme48 for
details.
\surflets should not use the \ex{shift-reset} structure, as this might
confuse the \surflet handler.
confuse the \surflet handler. The use of threads within a surflet is
currently discouraged, as some procedures might not work, especially
procedures dealing with session IDs.
\subsection{\surflet management}
Upon an initial client request, the \surflet handler looks for the
requested \surflet, dynamically loads it, installs an error handler
requested \surflet, loads it dynamically, installs an error handler
and calls the \ex{main} function of the \surflet with the initial
\ex{surflet-request}. To minimize the time of loading a \surflet,
the \surflet handler caches the structure of the \surflet in a cache,
@ -282,7 +285,7 @@ For some unknown weird cases, there are also these two procedures:
\subsection{Surflet Response}
\surflets answer to a request by sending an \ex{surflet-response} to
\surflets answer to a request by sending a \ex{surflet-response} to
the \surflet handler. The next section deals with how the surflet
responses are sent to the \surflet handler. The relevant procedures
for \ex{surflet-response} are the following. They are all exported by
@ -357,7 +360,10 @@ structures.
\defun{instance-session-id}{}{session-id}
\begin{desc}
This returns the session ID for the current session. The current
session is the session from which the function is called.
session is the session from which the function is called. The
\surflet handler guarantees that there won't be two sessions with
the same ID for any given point in time. However, session IDs may
be reused.
\end{desc}
\defun{get-session}{session-id}{session}
@ -435,21 +441,21 @@ of a session via the following procedures.
\defunx{session-continuation-table-lock}{session}{lock}
\defunx{session-continuation-counter}{session}{thread-safe-counter}
\begin{desc}
These functions the continuation table, the lock for the
continuation table and the counter for the continuations. The
continuation \var{table} is a hash table with the continuation ID as
key and the continuation as value, based on the \ex{tables}
structure of Scheme48. The \var{lock} is based on the \ex{locks}
structure of Scheme48. The \var{thread-safe-counter} is based on
the \ex{thread-safe-counter} structure that is part of the
These functions return the continuation table, the lock for the
continuation table and the counter for the continuations,
respectively. The continuation \var{table} is a hash table with the
continuation ID as key and the continuation as value, based on the
\ex{tables} structure of Scheme48. The \var{lock} is based on the
\ex{locks} structure of Scheme48. The \var{thread-safe-counter} is
based on the \ex{thread-safe-counter} structure that is part of the
\surflets.
The access to these functions is currently unrestricted but may be
restricted in future versions of the \surflet server.
\end{desc}
The \exi{surflets/continuations} also offers procedures to access the
continuations.
The \exi{surflets/continuations} structure also offers procedures to
access the continuations.
\defun{get-continuations}{session}{list}
\begin{desc}
@ -478,7 +484,7 @@ The \exi{surflets/continuations} also offers procedures to access the
The \exi{surflets/ids} structure provides procedures to determine the
session and continuation IDs of the current session. See also the
entry for \ex{resume-url-ids} some where else in this document.
entry for \ex{resume-url-ids} somewhere else in this document.
\defun{my-session-id}{surlfet-request}{number}
\defunx{my-continuation-id}{surlfet-request}{number}
@ -538,7 +544,7 @@ the \ex{status-code} syntax.
\defun{send}{surflet-response}{\noreturn}
\begin{desc}
This procedure send the data of the \var{surflet-response} to the
This procedure sends the data of the \var{surflet-response} to the
client and does not return.
\end{desc}
@ -626,7 +632,8 @@ element of a list, right after the SXML tag.
\defunx{sxml-attribute-attributes}{sxml-attribute}{list}
\begin{desc}
These are procedures on SXML attribute forms. \ex{sxml-attribute?}
is a predicate for SXML attribute forms.
is a predicate for SXML attribute forms. It checks if \var{object}
is a list whose first element is the symbol \ex{@}.
\ex{sxml-attribute-attributes} returns the list of name-value-lists
of the attributes form. Both procedures are exported by the
\exi{surflets/sxml} structure.
@ -636,7 +643,7 @@ The translator translates list elements which are numbers and symbols
to their string representation (except for the first element, of
course). She scans strings for the special characters \verb'&',
\verb'"', \verb'>' and \verb'<' and replaces them by their HTML
equivalents, and she ignores \sharpf and the emtpy list. See below
equivalents, and she ignores \sharpf\ and the emtpy list. See below
the special SXML tag \ex{plain-html} to see how to insert HTML code
untranslated. Furthermore, the translator accepts \ex{input-fields}
as list elements, which are translated to their HTML representation.
@ -668,7 +675,7 @@ directly translate to an HTML tag.
\hfill\quad\textnormal{SXML-tag}}}\index{#1}}
\defsxmltag{url}{URL [text]}
\defsxmltag{url}{ URL [text]}
\begin{desc}
Inserts a link to \var{URL}, named with \var{text}. \var{text}
defaults to \var{URL}. Takes at least one argument. \Eg
@ -687,19 +694,19 @@ directly translate to an HTML tag.
Inserts the HTML sequence \ex{"\&nbsp;"}. Takes no arguments.
\end{desc}
\defsxmltag{plain-html}{html \ldots}
\defsxmltag{plain-html}{ html \ldots}
\begin{desc}
Inserts \var{html} without any changes, thus it works like a quote.
Takes any number of arguments.
\end{desc}
\defsxmltag{*COMMENT*}{comment \ldots}
\defsxmltag{*COMMENT*}{ comment \ldots}
\begin{desc}
Inserts a comment, \ie \var{comment} enclosed between \verb|<!--|
and \verb|-->|. Takes any number of arguments.
\end{desc}
\defsxmltag{surflet-form}{k-url [method] [attributes] [SXML \ldots]}
\defsxmltag{surflet-form}{ k-url [method] [attributes] [SXML \ldots]}
\begin{desc}
Inserts HTML code for a web form. See below for details.
\var{k-url} usually is a continuation-URL. \var{method} is the
@ -722,14 +729,14 @@ this, a short introduction to the translation process.
The translation process takes place in two steps. Step one translates
the given SXML to low level SXML, essentially a rough form of HTML in
list notation. Step two takes this low level SXML and prints to a
list notation. Step two takes this low level SXML and prints it to a
port. Step one is performed by \ex{sxml->low-level-sxml}, step two by
\ex{display-low-level-sxml}. All procedures and rules presented in
this subsection are exported from \exi{surflets/sxml}.
\defun{sxml->low-level-sxml}{sxml rules}{low-level-sxml}
\begin{desc}
Takes an SXML object (which essentially is a list) and a list of
Takes an SXML object (which is essentially a list) and a list of
SXML rules (more on this below) and translates it to low level SXML.
This procedure is an alias to the \ex{pre-post-order} procedure of
Oleg Kiselyov's SSAX module. It is an error if no rule triggers
@ -742,8 +749,8 @@ this subsection are exported from \exi{surflets/sxml}.
Takes low level SXML and \ex{display}s it to a port. She traverses
the list \var{low-level-sxml} depth-first, ignores the empty list
and \sharpf, executes thunks and \ex{display}s all other elements,
usually strings and characters, to \var{port}. Returns \sharpt if
she wrote anything, \sharpf otherwise. This function is basically
usually strings and characters, to \var{port}. Returns \sharpt\ if
she wrote anything, \sharpf\ otherwise. This function is basically
the \ex{SRV:send-reply} procedure of Oleg Kiselyov's SSAX module.
\end{desc}
@ -867,11 +874,12 @@ for the double naming \ex{resume-url} and continuation-URL.
\defunx{resume-url-session-id}{resume-url}{session-id}
\defunx{resume-url-continuation-id}{resume-url}{continuation-id}
\begin{desc}
These inspect values of a resume url. \ex{resume-url?} is predicate
for resume urls. Note that it only operates on strings.
\ex{resume-url-ids} returns the session- and the continuation-id
that is stored in the \var{resume-url}. \ex{resume-url-session-id}
and \ex{resume-url-continuation-id} return only the session- or the
These inspect values of a resume url. \ex{resume-url?} is a
predicate for resume urls (the same as continuation urls). Note
that it only operates on strings. \ex{resume-url-ids} returns the
session- and the continuation-id that is stored in the
\var{resume-url}. \ex{resume-url-session-id} and
\ex{resume-url-continuation-id} return only the session- or the
continuation-id, respectively.
\end{desc}
@ -889,9 +897,9 @@ The \surflets support all input fields defined for HTML~2.0 and allow
\surflet the input field reports as its value, which may be of any
type, not only strings.
Here is a short overview, how to use input fields. See also the howto
for more informations. First, you create the \ex{input-field} that
represents the input field you want to use. Then you put this
Here is a short overview on how to use input fields. See also the
howto for more informations. First, you create the \ex{input-field}
that represents the input field you want to use. Then you put this
\ex{input-field} into the SXML of the web page at the place the
input field shall appear. After \ex{send-html/suspend} has returned
with the next \ex{surflet-request}, you call \ex{get-bindings} with
@ -950,13 +958,13 @@ The \exi{surflets/bindings} structures exports the necessary functions
be translated to a string before use. \ex{extract-bindings} returns
a list of all values from \var{bindings} whose key is \var{key}.
\ex{extract-single-binding} returns the value from the binding whose
key is \var{key} and raises an error if there more than one such
key is \var{key} and raises an error if there is more than one such
binding. The two procedures are the same as in PLT's webserver.
\end{desc}
\ex{get-bindings} must acces the "Content-length" header field to
handle \ex{POST} request. \ex{surflets/bindings} therefore also
exports the procedure that does that job:
handle \ex{POST} requests. \ex{surflets/bindings} also exports the
procedure that does that job:
\defun{get-content-length}{headers}{number}
\begin{desc}

View File

@ -33,18 +33,18 @@ description.
%\marginpar{\surflets are pieces of code for web site scripting.}
For those who don't know it already, \surflets are pieces of code that
can be executed interactively through a website. There is a \surflet
handler who administrates their execution and suspension and as part
of the SUnet webserver. \surflets ease the implementation of web
applications in two ways, compared to other server-side scripting
tools like Java\texttrademark Servlets or Microsoft\textregistered
Active Server Pages or PHP:
handler who administrates their execution and suspension. The
\surflet handler is part of the SUnet webserver. \surflets ease the
implementation of web applications in two ways, compared to other
server-side scripting tools like Java\texttrademark Servlets or
Microsoft\textregistered Active Server Pages or PHP:
\begin{enumerate}
\item \surflets have an automatic program flow control like any
other usual program, \ie the web designer doesn't have to care about
session management at all. The sequence of the web pages result from
their appearance in the program like the print statements in any other
usual program.
other usual program (but unlike usual web programs), \ie the web
designer doesn't have to care about session management at all. The
sequence of the web pages result from their appearance in the program
like the print statements in any other usual program.
\item \surflets come along with a library for robust user
interaction. \surflets represent interaction elements of the web page
@ -125,7 +125,7 @@ Going to run SUrflet server with:
htdocs-dir: /home/andreas/bin/lib/scsh/0.6/sunet-2.1/web-server/root/htdocs
surflet-dir: /home/andreas/bin/lib/scsh/0.6/sunet-2.1/web-server/root/surflets
images-dir: /home/andreas/bin/lib/scsh/0.6/sunet-2.1/web-server/root/img
port: 8008
port: 8080
log-file-name: /tmp/httpd.log
a maximum of 5 simultaneous requests, syslogging activated,
and home-dir-handler (public_html) activated.
@ -134,7 +134,7 @@ Going to run SUrflet server with:
\end{alltt}
This means the server is up and running. Try to connect to
\url{http://localhost:8008} with your browser and you will see the
\url{http://localhost:8080} with your browser and you will see the
welcome page of the SUnet server. There's a link to the
\surflets homepage. You can also already try out some of the
\surflets that come with the distribution.
@ -144,8 +144,8 @@ the first \surflet. This is because the server has to load the
\surflet libraries. The server handles further requests to \surflets
faster.
If the port the \surflet server tries to use is occupied use, you will
see an error message similar to this one:
If the port the \surflet server tries to use is occupied, you will see
an error message similar to this one:
\begin{alltt}
Error: 98
@ -153,7 +153,7 @@ Error: 98
#{Procedure 11701 (\%bind in scsh-level-0)}
4
2
(0 . 8008)
(0 . 8080)
\end{alltt}
In this case, pass another port number to the script, \eg 8000:
@ -244,7 +244,7 @@ use to send web pages to the browser. The other two functions are
\name{send-html} and \name{send-html/suspend}.
\name{send-html/finish} -- as the name already suggests -- sends a
HTML page to the browser and finishes the \surflet. \name{send-html}
just sends the HTML page and does not return and
just sends the HTML page and does not return.
\name{send-html/suspend} sends the HTML page and suspends the
\surflet, \ie it waits until the user continues with the \surflet,
\eg by submitting a webform. We will discuss \name{send-html} and
@ -255,38 +255,35 @@ In a \surflet, HTML pages are represented as lists, or, to be more
precise, as SXML (S-expression based XML).\label{sec:SXML} The first
element of a SXML list is a symbol stating the HTML tag. The other
elements of a SXML list are the contents that are enclosed by this
HTML tag. The contents can be other SXML list, too. Here are some
HTML tag. The contents can be other SXML lists, too. Here are some
examples of SXML lists and how they translate to HTML:
\newcommand{\htmltag}[1]{$\mathtt{<}$#1$\mathtt{>}$}
\begin{tabbing}
HTML: \medskip\=\kill
SXML: \> \texttt{'(p "A paragraph.")} \\
HTML: \> \texttt{\htmltag{p}A paragraph.\htmltag{/p}}\\
%\newcommand{\htmltag}[1]{$\mathtt{<}$#1$\mathtt{>}$}
\begin{tabular}{ll}
SXML: & \verb|'(p "A paragraph.")}| \\
HTML: & \verb|<p>A paragraph.\htmltag{/p}}|\\
\\
SXML: \> \texttt{'(p "A paragraph." (br) "With break line.")} \\
HTML: \> \texttt{\htmltag{p}A paragraph.\htmltag{br}With break line.\htmltag{/p}}\\
SXML: & \verb|'(p "A paragraph." (br) "With break line.")}| \\
HTML: & \verb|<p>A paragraph.<br>With break line.</p>}|\\
\\
SXML: \> \texttt{'(p "Nested" (p "paragraphs"))}\\
HTML: \> \texttt{\htmltag{p}Nested\htmltag{p}paragraphs\htmltag{/p}\htmltag{/p}}\\
\end{tabbing}
SXML: & \verb|'(p "Nested" (p "paragraphs"))}|\\
HTML: & \verb|<p>Nested<p>paragraphs</p></p>}|\\
\end{tabular}
Attributes are stated by a special list whose first element is the
at-symbol. The attribute list must be the second element in the list:
\begin{tabbing}
HTML: \medskip\=\kill
SXML: \> \texttt{'(a (@ (href "attr.html")) "Attributed HTML tags.")} \\
HTML: \> \texttt{\htmltag{a href="attr.html"}Attributed HTML tags.\htmltag{/a}}\\
\begin{tabular}{ll}
SXML: & \verb|'(a (@ (href "attr.html")) "Attributed HTML tags.")|\\
HTML: & \verb|<a href="attr.html">Attributed HTML tags.</a>|\\
\\
SXML: \> \texttt{'(a (@ (href "attr2.html") (target "\_blank")) "2
attributes.")} \\
HTML: \> \texttt{\htmltag{a href="attr2.html" target="\_blank"}2
attributes.\htmltag{/a}}
\end{tabbing}
SXML: & \verb|'(a (@ (href "attr2.html") (target "\_blank")) "2
attributes.")}| \\
HTML: & \verb|<a href="attr2.html" target="\_blank">2 attributes.</a>}|
\end{tabular}
As you see from the \surflet example, \name{send-html/finish} expects
as an argument SXML. In the example, the SXML translates to the
SXML as an argument. In the example, the SXML translates to the
following HTML code:
\begin{alltt}
<html><body><h1>Hello, world!</h1>
@ -332,7 +329,7 @@ a regular quote (\typew{'}) as in the previous example.
Instead of passing a ``static'' list, \ie a list whose contents are
given before execution, this \surflet uses the quasiquote and unquote
feature of Scheme to create a ``dynamic'' list, \ie list whose
feature of Scheme to create a ``dynamic'' list, \ie a list whose
contents are given only during execution. A ``dynamic'' list is
introduced by a backquote (\typew{`}) and its dynamic contents are
noted by commata (\typew{,}). Thus, if the \surflet is executed while
@ -354,13 +351,13 @@ want; the quasiquote notation is just a convenient way to do it.
\subsubsection{Several web pages in a row}
The previous example \surflets only showed one page and finished
afterwards. Here, we want to present to web pages in a row. We use
afterwards. Here, we want to present two web pages in a row. We use
the previously mentioned function \name{send-html/suspend}, which
suspends after it has send the page and continues when the user
suspends after it has sent the page and continues when the user
clicked for the next page. In contrast to \name{send-html/finish},
that expected SXML, \name{send-html/suspend} expects a function that
takes an argument and returns SXML. The parameter the function gets
(here: \name{k-url} is the URL that points to the next
(here: \name{k-url}) is the URL that points to the next
page:\footnote{In the API this URL is called the \emph{continuation
URL}.}
@ -384,7 +381,7 @@ This \surflet can be found in \name{howto/hello-twice.scm}. This
example first displays a web page with the message ``Hello, world!''
and a link to the next page labeled with ``Next page --$>$''. When the
user clicks on the provided link, \name{send-html/suspend} returns and
the the next statement after the call to \name{send-html/suspend} is
the next statement after the call to \name{send-html/suspend} is
executed. Here it is \name{send-html/finish} which shows a web page
with the message ``Hello, again!''.
@ -402,16 +399,16 @@ effects, \eg if you change a variable via \name{set!}. These
variables keep their modified values, allowing communication between
sessions of the same \surflet.\footnote{If you want to change a
variable via side effects but you don't want to interfere with other
session, you can use \name{set-session-data!} and
sessions, you can use \name{set-session-data!} and
\name{get-session-data}. See the API documentation in section
\ref{sec:surflet-api}for further information.}
\ref{sec:surflet-api} for further information.}
\subsubsection{Begin and end of sessions}
So far I don't have mentioned too much details about sessions. The
reason is, as mentioned before, that the \surflet handler takes of the
session automatically as described in the previous paragraph.
reason is, as mentioned before, that the \surflet handler takes care
of the session automatically as described in the previous paragraph.
%, \ie it starts the session automatically when an
%instance of your \surflet starts and takes care of the saving and
%restoring of all variable values during suspensions of your \surflet
@ -512,8 +509,8 @@ objects. Thus, user interaction elements are first class values in
\surflet, unlike in many other web scripting languages, \eg Java
surflets, PHP or Microsoft Active Server Pages, \ie you have a
representation of a user interaction element in your program that you
can pass to functions, receive them as return values, etc. You'll see
soon the advantages of this approach.
can pass to functions, receive them as return values, etc. You'll
soon see the advantages of this approach.
\begin{alltt}
(req (send-html/suspend
@ -559,7 +556,7 @@ add the symbol \name{'POST} after the URL:
\end{alltt}
The web page \name{send-html/suspend} sends to the browser looks like
in figure [missing]
in figure [missing].
%\ref{fig:user1-1}.
After the user has entered his data into
the web form, \name{send-html/suspend} returns with the request object
@ -593,7 +590,7 @@ know what the user has entered into the \name{text-input-field}.
After we have extracted what the user has entered into the text field,
we can show the final page of our \surflet and echo her input.
The scheme for user interaction is thus about the following:
Thus, the scheme for user interaction is about the following:
\begin{itemize}
\item Create the user interaction elements, \name{input-field}s, you
@ -615,7 +612,7 @@ found in the API in section \ref{sec:surflet-api}.
As the user interaction elements are first class values in a \surflet,
they can return other types than strings. For example the \surflets
come with a number input field, \ie a input field that accepts only
come with a number input field, \ie an input field that accepts only
text that can be interpreted as a number. If the user enters
something that is not a number, \name{input-field-value} will return
\sharpf as the value of the number input field. If you'd rather want
@ -675,13 +672,13 @@ Let's go through the important part of this \surflet:
Here we define a select input field (a dropdown list). Instead of
only providing a list of values that shall show up in the dropdown
list and later examining which one was select and looking up the price
for the sweet, we bind the values in the list with the price while we
create the select input field. When the select input field is shown
in the browser, it will show the names of the sweets. When we lookup
the user's input, we will get the associated price for the sweet.
Again, this works not only with numbers, but with any arbitrary Scheme
value (\eg functions or records).
list and later examining which one was selected and looking up the
price for the sweet, we bind the values in the list with the price
while we create the select input field. When the select input field
is shown in the browser, it will show the names of the sweets. When
we lookup the user's input, we will get the associated price for the
sweet. Again, this works not only with numbers, but with any
arbitrary Scheme value (\eg functions or records).
\subsubsection{Sending error messages}
@ -691,7 +688,7 @@ has to deal with unexpected values. Usually, a forged \surflet-URL
will result in an error that is raised in one of the \surflet library
functions. If you don't catch this error, the \surflet handler will
catch it for you, send an error message to the user
\emph{and terminating the current session} as your \surflet obviously
\emph{and terminate the current session} as your \surflet obviously
encountered an unexpected error and might be in an invalid state. If
you don't want this behavior, you can catch this error (like any other
error that is raised by \scsh) and send your own error message with
@ -703,8 +700,8 @@ previous subsection (modifications emphasized):
\begin{listing}
(define-structure surflet surflet-interface
(open surflets
\codemph{ handle-fatal-error
surflets/error}
\codemph{ handle-fatal-error}
\codemph{ surflets/error}
scheme-with-scsh)
(begin
(define (main req)
@ -725,14 +722,14 @@ previous subsection (modifications emphasized):
,select-input-field)
,(make-submit-button)))))))
(bindings (get-bindings req))
\codemph{ (cost (with-fatal-error-handler
(lambda (condition decline)
(send-error (status-code bad-request)
req
"No such option or internal
error. Please try again."))
(raw-input-field-value select-input-field
bindings))))}
\codemph{ (cost (with-fatal-error-handler }
\codemph{ (lambda (condition decline) }
\codemph{ (send-error (status-code bad-request)}
\codemph{ req }
\codemph{ "No such option or internal }
\codemph{ error. Please try again."))}
\codemph{ (raw-input-field-value select-input-field }
\codemph{ bindings)))) }
(send-html/finish
`(html (head (title "Receipt"))
(body
@ -756,7 +753,7 @@ Let's examine the important part of this example:
As mentioned in \ref{subsec:input-return}, this \surflet uses
\name{raw-input-field-value} instead of \name{input-field-value}
because the former raises an error while the latter returns \sharpf in
because the former raises an error while the latter returns \sharpf\ in
case of an error.
If a user forges a continuation URL, \name{raw-input-field-value}
@ -768,7 +765,7 @@ by the error handler which was installed by
argument is the status code of the error message. See the
documentation of the \sunet webserver for different status codes. The
second argument is the request which was processed while the error
occured. The last argument is a free message text to explain the
occured. The last argument is a free text message to explain the
cause of the error to the user.
While in the original \surflet the user will still see the resulting
@ -797,7 +794,7 @@ gives you a short overview how to do this. You will find the details
in the \surflet API.
Let's have a look at an \surflet that uses its own input field. The
``input field'', called nibble input field, consists of eight check
``input field'', called nibble input field, consists of four check
boxes which represent bits of a nibble (half a byte). The value of
the input field is the number that the check boxes represent. \Eg, if
the user checks the last two checkboxes, the value of the nibble input
@ -918,7 +915,7 @@ associated to its name.
The transformer function of our nibble input field goes over each
check box, looks it up in the bindings and adds its value to a sum, if
\name{input-field-value} can find it. If it can't find it, a zero is
\name{input-field-value} can find it. If it can't find it, zero is
added instead. The value of our nibble input field is the resulting
sum.
@ -1025,8 +1022,8 @@ link the user has clicked by using \name{case-returned-via}.
\name{case-returned-via} works similar to the regular \name{case} of
Scheme. It evaluates the body of the form whose initial list contains
the address that the user used to leave the website. \Eg, if the user
has selected ``German'' as her preferred language and thus clicked on
the link we have named \name{german} in our \surflet,
has selected ``German'' as her preferred language and clicked on the
link we have named \name{german} in our \surflet,
\name{case-returned-via} will evaluate its second form and the
\surflet will display the greeting in German.
@ -1067,11 +1064,11 @@ We modify the previous code example slightly to this \surflet
(body
(h2 "Select your language:")
(ul
(li (url ,\codemph{(language k-url
"Hello, how are you?")}
(li (url ,\codemph{(language k-url }
\codemph{ "Hello, how are you?")}
"English")
(li (url ,\codemph{(language k-url
"Hallo, wie geht es Ihnen?")}
(li (url ,\codemph{(language k-url }
\codemph{ "Hallo, wie geht es Ihnen?")}
"Deutsch")))))))))
(bindings (get-bindings req)))
(case-returned-via bindings
@ -1138,7 +1135,7 @@ callbacks. A callback is a function that is called if the user leaves
the web page via an associated link. This is different from the
dispatch method where \name{send-html/suspend} returns. You can
create a web page that only uses callbacks to lead to successor web
page and thus you don't have to use \name{send-html/suspend}.
pages and you don't have to use \name{send-html/suspend}.
Instead, you can use \name{send-html}.
Although it is possible to use several different callbacks in a single
@ -1186,7 +1183,8 @@ callbacked function must accept the request from the browser as the
first argument. Furthermore, you don't have to use
\name{send-html/suspend}, if a user can only leave your web page via
callbacks. However, it can be sensible to combine the dispatch and
the callback method, so you have to use \name{send-html/suspend}.
the callback method, in which case you have to use
\name{send-html/suspend}.
Note that is nonsensical to create a callback on top level, \ie the
call to \name{make-annotated-callback} must occur every time
@ -1207,7 +1205,7 @@ you can instruct the callback to call different functions like this:
\begin{alltt}
(callback function1 arg1 arg2)
\dots
\dots \\
(callback function2 arg3 arg4 arg5)
\end{alltt}
@ -1220,15 +1218,15 @@ callback.
When you write web programs, there are usually two kinds of data that
you use: data that is local to each instance of a \surflet, \eg the
users login, and data that is global to each instance of a \surflet,
user's login, and data that is global to each instance of a \surflet,
\eg a port to a logfile. Changes to local data is only visible to
each instance of a \surflet, while changes to global data is visible
to every instance of a \surflet.
each session of a \surflet, while changes to global data is visible
to every session of a \surflet.
The \surflet library does not really distinguish between these two
types of data, but provides ways to realize both of them in a
convenient way that is not (really) different from the way you handle
this data types in a regular Scheme program.
these data types in a regular Scheme program.
If a data item is globally used in your \surflet, define it global
(on top level) and change its values with \name{set!}. If a data
@ -1242,7 +1240,7 @@ is that the \surflets are implemented with continuations.
Continuations cannot reflect changes that are done via \name{set!} (or
side effects in general) and thus such changes are globally visible.
On the other hand continuations represent states of a program and a
reified continuations reifies also the values of all (local) data.
reified continuations reifies also the values of all data.
But what to do if you happen to want to change your \emph{local}
data's value with \name{set!}? The \surflet library provides a place
@ -1359,50 +1357,45 @@ process and some necessary terms we will use in the following.
The translation process from SXML to HTML takes two steps. In the
first step, SXML is translated to an intermediate form. This is done
by the \textit{translator}. In the second step, the intermediate form
is translated into an HTML string. This is done by the
is printed into an HTML string. This is done by the
\textit{printer}. The intermediate form looks very much like SXML,
but contains only atoms or, recursively, list of \textit{atoms}.
but contains only \textit{atoms} or, recursively, list of atoms.
Atoms are numbers, characters, strings, \sharpf, and the empty list.
We call the intermediate form an \textit{atom tree} and the list from
which we've started an \textit{SXML tree}.
The basic unit in the translation process is a \textit{conversion
rule}. A conversion rule consists of a trigger and a conversion
function. The translator calls the conversion function when it sees
the trigger at the beginning of a list in the SXML tree, \ie at a
node. It calls the conversion function with the all list elements as
function. As its first element, the trigger identifies the list for
which the translator shall call the conversion function. The
translator calls the conversion function with all list elements as
parameters and replaces the whole list by the result of the conversion
function. The result of the conversion function is supposed to be an
atom tree.
The translator gets the SXML tree and a list of conversion rules as
The translator takes the SXML tree and a list of conversion rules as
arguments. It then traverses the SXML tree depth first and calls the
conversion functions according to the triggers it encounters,
replacing the nodes in the SXML tree with the result of the conversion
functions it called for each node. The result of this translation
step will be an atom tree, which the printer will print to a port.
replacing the nodes in the SXML tree with the return values of each
conversion function called. The result of this translation step will
be an atom tree, which the printer will print into a string or port.
There are exceptions to this basic rules. First, the translator might
not traverse the whole SXML tree. If the translator traverses the
whole tree, every argument to a conversion function is first
translated before it is passed to the conversion function. This is
the regular case and we say the conversion function gets its arguments
\textit{preprocessed}. However, the conversion rule can instruct the
translator not to preprocess the conversion function's arguments and
pass the arguments as they are in the SXML tree, \ie
\textit{unprocessed}. In that case, the translator will stop
traversing the SXML tree at that node and replacing the whole node by
the result of the conversion function called for this node.
The translator calls the conversion function in two different modes,
depending on the conversion rule. The regular mode is the
\textit{preprocess} mode: the translator translates every argument of
the conversion function before calling it. The other mode is the
\textit{unprocessed} mode: the translator calls the conversion
function directly without preprocessing the arguments. This is, the
translator stops traversing the SXML tree at nodes that trigger a
conversion rule in unprocessed mode.
Second, there are two default triggers which you can't use in your
translation rules: \typew{*default*} and \typew{*text*}. The
conversion rule that uses \typew{*default*} as its trigger is the
default conversion rule which the translator uses if no other
conversion rule triggers for a node in the SXML tree. The conversion
rule that uses \typew{*text*} as its trigger is the text conversion
rule and triggers, if the node in the SXML tree is a string. In the
standard conversion rule set the text conversion rule performs HTML
escaping, \eg for the ampersand (\&).
There are two default triggers which you can't use in your translation
rules: \typew{*default*} and \typew{*text*}. \typew{*default*} as the
trigger marks the default conversion rule which the translator uses if
no other conversion rule triggers. \typew{*text*} marks the text
conversion rule and triggers, if the node in the SXML tree is a
string. In the standard conversion rule set the text conversion rule
performs HTML escaping, \eg for the ampersand (\&).
\subsubsection{Outlook}

View File

@ -6,7 +6,7 @@ The \surflet server enables you to write server side scripted web
programs in Scheme.
%Currently, there is only the howto available.
%The complete API is supposed to come soon.
There are lot of example files in
There are lots of example files in
\typew{scheme/httpd/surflet/webserver/root/surflets} from which you
can copy freely.