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
	
	 interp
						interp