Fix typos and do some rephrasing.
This commit is contained in:
parent
58a540854f
commit
d904121149
|
@ -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{"\ "}. 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}
|
||||
|
|
|
@ -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}
|
||||
|
|
|
@ -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.
|
||||
|
||||
|
|
Loading…
Reference in New Issue