# Allegro Webactions

##### v1.20

#### Copyright (c) Franz Inc.

## Table of Contents

* [Introduction](#introduction)
* [Loading Webactions](#Loading_Webactions)
* [Common Lisp Server Pages](#Common_Lisp_Server_Pages_)
  * [Processing a CLP file](#Processing_a_CLP_file)
  * [CLP elements with bodies](#CLP_elements_with_bodies)
  * [parsing CLP files](#parsing_CLP_files)
  * [CLP tag and function names](#CLP_tag_and_function_names)
  * [The Lisp side of CLP](#The_Lisp_side_of_CLP)
* [Webactions](#Webactions)
  * [Webaction project](#Webaction_project)
    * [Classes used in Webactions](#Classes_used_in_webactions)
    * [Storing Values](#storing_values)
    * [Lisp functions for Webactions](#Lisp_functions_for_webactions)
    * [Library of CLP functions](#Library_of_CLP_functions)


## <span id="introduction"></span>Introduction

Most of the web sites people visit again and again are dynamic. These pages
range from pages containing static data and a dynamically selected banner ad to
pages full of personalized content, such as a search page returned by Google.
AllegroServe offers two different ways of creating dynamic pages. The most
general is the **`publish`** function which allows the programmer to completely
generate the response to an http request. Also the **`publish-multi`** function
creates pages that are a mixture of static data and data generated by a lisp
function. It's possible to build a large dynamic web site using just these
functions but it does require that you have a lot of programming talent at your
disposal. It's far easier to find html designers than Lisp programmers and so we
designed a method of building large dynamic web sites in AllegroServe that uses
mainly html designers with some support from Lisp programmers. This is the
purpose of **C**ommon **L**isp Server **P**ages (or *CLP*) and Webactions.

Webactions is the framework used to describe the whole site and to control
access to pages in the site. CLP files provide a way of mixing static and
dynamic html that works well with the webaction framework. We'll describe CLP
pages first and then the webaction framework.

Please see the document [Using Webactions](using-webactions.md) for further
background information on webactions.

## <span id="Loading_Webactions"></span>Loading Webactions

In order to load in Webactions you should **`(require :webactions)`**. This
will load in AllegroServe if it isn't already loaded. The functions in
Webactions are exported from the **`net.aserve`** package.


## <span id="Common_Lisp_Server_Pages_"></span>Common Lisp Server Pages

Common Lisp Server Pages is modeled after similar designs for other languages:
Java Server Pages, Active Server Pages, Personal Home Pages (PHP) and others.

A Common Lisp Server Page file looks just like an html file. In fact the format
is the same as html. We've extended html by allowing new tags which cause
extended functionality to be invoked.

The key features of CLP are:

  - A CLP file can be edited with an html editor (such as FrontPage or Mozilla's
    built-in html editor named Composer).
  - CLP files can contain javascript or other scripting code.
  - a CLP file can contain illegal html. The CLP file processor does not attempt
    to verify that the file contains valid html syntax. While we don't
    recommend that you use illegal html we do know that some people do and that
    won't prevent you from using CLP files.
  - A CLP file does not contain any lisp code. A CLP file may contain tags that
    cause Lisp code to be run to render html, but it does not contain Lisp
    code. The html designers editing the CLP files will likely not know
    Lisp. The presence of code in the file that they don't understand would
    confuse them and they may inadvertently modify the Lisp code and cause it to
    fail.
  - The CLP file processor, when used with the webactions framework, supports
    the notion of sessions which are automatically maintained by cookies
    (preferably) or by url rewriting.

### <span id="Processing_a_CLP_file"></span>Processing a CLP file

This is a sample CLP file:

```html
<html>
<body>
You are using this browser: <http_header-value name="User-Agent"/>
<br>
How do you like it?
</body>
</html>
```

You'll notice two unusual things in the file. One is the tag
`http_header-value`, which you've never seen before. The other is that tag ends
in `/>`, which is the xml and xhtml way of specifying that this html element has
no body. It's equivalent to writing the pure html:

```html
<http_header-value name="User-Agent"></http_header-value>
```

The tag `http_header-value` names a *CLP function*. A CLP function is written in
Lisp and is run during the time this page is sent back to the browser. Thus
when this page is retrieved by a browser, the result is that all the text in the
file up to the `http_header-value` tag would be sent directly to the browser.
Next the `http_header-value` function would be run and it will emit html which
will be sent back to the browser. Finally the text after the
`http_header-value` tag will be sent to the browser.

The CLP function `http_header-value` is supplied with AllegroServe. As its name
suggests it retrieves the value from an http header in the request and then
emits the value as html. In our sample file we're retrieving the value of the
User-Agent header which describes which http client is making the request.

A user accessing this page would see something like this in his browser:

```text
You are using this browser: Firefox 1.5
How do you like it?
```


### <span id="CLP_elements_with_bodies"></span>CLP elements with bodies

The example above uses a CLP element with no body. This is what you'll
typically find in use. However there are situations where you want to give the
element a body, the most notable one being when you want a CLP function to
determine which parts of a CLP file are sent back to the browser. For example

```html
<clp_ifdef name="winner" session> You are the Winner! </clp_ifdef>
<clp_ifndef name="winner" session > Sorry, you lost </clp_ifndef>
```

This CLP file fragment checks to see if the session state has a variable named
winner defined and if it does it includes the appropriate text. If winner is
not defined then it includes the loser message. The `clp_ifdef` and
`clp_ifndef` functions are supplied with AllegroServe.

One problem with using conditional inclusion of text is that an html editor's
view of the CLP file will include both versions of the text since it ignores
unknown tags like `clp_ifdef`. Thus you'll have to balance the power of using
conditional text inclusion against the problems it creates in that your html
editor can't display the final product.

### <span id="parsing_CLP_files"></span>Parsing CLP files

Before a CLP file can be used to generate a response to an http request it must
be parsed. The parsing function is very simple and is in fact more like pattern
matching than traditional parsing. The parser simply locates all calls to CLP
functions in the file and separates them from the text that is sent back
verbatim as part of the response. A CLP file is parsed when it's first
referenced in an http request and the results of the parse are cached The CLP
file is not parsed again unless the file is updated on disk.

### <span id="CLP_tag_and_function_names"></span>CLP tag and function names

The CLP parser has to be able to distinguish CLP tags from html tags and from
tags that are neither CLP tags nor valid html tags. The parser may encounter a
CLP tag referencing a CLP function that's not yet defined (in Lisp we don't
require that a function be defined before we'll recognize a call to that
function). The problem then is determining whether a given tag in the file is a
call to a CLP function or a name that could be used as a CLP function in the
future. The strategy employed is the following: A CLP function name has two
parts: a module name and the name of the function within the module. These
names are separated by an underscore. Thus `http_header-value` is the
**`header-value`** function in the **`http`** module. The CLP parser only has
to look closely at tags with an underscore in them. In order to tell if such a
tag is a CLP function name the parser looks only at the module name. If the
module name is of a currently known module then that name is considered to be a
CLP function name. Thus before you start running your web site you should
define at least one CLP function in each module you intend to use. You can
define the other functions later (and you likely will if you are building your
site and testing it incrementally).



### <span id="The_Lisp_side_of_CLP"></span>The Lisp side of CLP

#### `net.aserve:def-clp-function`

```lisp
(def-clp-function name (req ent args body) &rest function-body)
```

This macro defines a CLP function with the given name. **`name`** can be a
string or a symbol (in which case the downcased version of the symbol-name is
used). The name must include an underscore between two of the characters (this
separates the module name from the function-with-the-module name). When called
the function takes four arguments and we've shown above the names we suggest be
used for those four arguments. **`req`** and **`ent`** are the familiar request
and entity values passed to all http response functions. Args is an alist of
attribute names and values found in the start tag that invoked this function.
For example given the tag

```html
<mod_sample name="foo" value="24">
```

the value of **`args`** would be

```lisp
(("name" . "foo") ("value" . "24"))
```

The fourth argument, **`body`**, is passed the parsed version of the of the body
of the element, that is the text that appears between the start and end tags in
the CLP file. A CLP function is not supposed to examine the value of
**`body`**. It should do one of two things with **`body`**. It can just ignore
the value in which case the text and calls to CLP functions between the start
and end tags are ignored and not sent as part of the response to the web
browser. Alternatively it can cause the **`body`** to be sent back as part of the
response by calling **`(emit-clp-entity req ent body)`**.

The **`function-body`** is the code that's run when the CLP function is called. It
should emit html just like the code in a normal http response function. Often
this is done with the **`html`** macro. The value returned by this function is
unimportant.

-----

#### `net.aserve:emit-clp-entity`

```lisp
(emit-clp-entity req ent body)
```

This is used inside a CLP function to cause the contents of **`body`** to be
processed as a parsed CLP file. This will result in strings being sent to the
html stream (and thus back to the browser) and it will cause CLP functions to be
run. The only place this function should be used is inside a CLP function.


## <span id="Webactions"></span>Webactions

Webactions is a framework for building dynamic web sites. Dynamic webs sites
are difficult to build as they require more than html can provide, such as

  1. **Sessions** - the web site must follow each user as they move around the
     site, perhaps picking up products and placing them in their virtual
     shopping cart. This is accomplished by associating a session object in the
     web server with each distinct user.
  2. **Database backed** - the dynamic web site is often just a user interface
     to a database. Shopping sites display products found in the store's
     database and add orders to the store's database. It's useful to separate
     out the code that operates on the database and the code that displays the
     current state of the database.
  3. **Complex linking** - there are many paths through an online store as goods
     are selected and finally an order is made. Keeping track of these links is
     very hard as the site gets large. You need some way of keeping track of the
     layout of the whole site.

The webactions framework supports a programming methodology called Model View
Controller (or MVC). In a dynamic web application the pieces are these:

  1. **Model** - this is the code that implements the data objects being
     manipulated by users of the web site. In an online store the model
     includes the notions of a shopping cart and orders and so on. This is the
     code that must be written specifically for the objects being modeled.
  2. **View** - the html pages that show the user a view of the model. These
     pages are usually CLP pages in the webaction framework. There will be some
     CLP functions to implement the dynamic parts of the pages.
  3. **Controller** - the code that accepts user input and passes control to the
     model to process the input and finally selects a view to send back to the
     user. This code is supplied with the webaction framework.

A designer of a webactions-based web site will write or reuse Lisp code to
implement the Model. For the View he'll write CLP functions in Lisp to support
the CLP pages written in html. He'll use the the Controller code supplied with
Webactions.


### <span id="Webaction_project"></span> Webaction project

A Webaction based web site is defined by a call to the webaction-project macro.

#### `net.aserve:webaction-project`

```lisp
(webaction-project name &key project-prefix clp-suffixes map destination index
                             sessions session-lifetime reap-interval
                             reap-hook-function server authorizer
                             host access-file CLP-content-type default-actions
                             external-format use-http-only-cookies)
```

**`webaction-project`** creates project data structures and executes calls to
**`publish`** to make the project exist on the server.

The arguments are
  - **`name`** - a string naming the project. The name is used to ensure that if
    **`webaction-project`** is called again with the same name, the project by that
    name is redefined rather than creating a new project. Also the name is used
    as the name of the cookie that's used to track sessions in this project.
    Since this is a cookie name too the name should use just alphabetic and
    numeric characters.
  - **`project-prefix`** - a string which specifies the prefix of all urls in the
    project. The prefix should be a string beginning and ending in the
    forward-slash character, such as "/myproject/" . It's legal to use the one
    character string "/". What this means is that all url's beginning with this
    prefix are assumed to be part of this project and are treated specially.
  - **`clp-suffixes`** - a list of strings naming the suffixes of files, which if
    found inside the project, are assumed to be CLP files. By default the value
    of CLP-suffixes is a list of the string "CLP". You may wish to add "htm" or
    "html" to this list if you want those files to be parsed as CLP files when
    referenced inside this project.
  - **`map`** - an assoc list of the symbolic page name and how that page is
    generated. This will be described in detail below.
  - **`destination`** - the location on the filesystem where the files that make up
    this project are to be found. This can be the empty string "" or the name
    of a directory on the machine. If you name a directory be sure that the
    name ends in "/".
  - **`index`** - the symbolic page name of the main page of this project (also
    known as the index or root page). webaction-project will redirect to this
    page if a request comes in for a url which is just the project-prefix. If
    the project-prefix is "/foo/" and the index is "home" then a request for
    "/foo" or "/foo/" will be redirected to "/foo/home".
  - **`sessions`** - if true (which is the default value) then track access to the
    pages of the project so that all accesses from a given web browser are
    assigned a unique websession object.
  - **`session-lifetime`** - if the session hasn't been accessed in this many
    seconds, remove the session object from the internal table of sessions,
    allowing it to be garbage collected. The default session lifetime is 18000
    seconds (i.e. five hours).
  - **`reap-interval`** - the number of seconds between checks to see if any
    sessions have expired and should be removed. Specifying this variable sets
    a global variable (since all webactions projects share the same session
    reaping process). The default value is 300 seconds (i.e. five minutes).
  - **`reap-hook-function`** - a function of one argument, a websession object.
    This is called when a session is about to be destroyed due to no reference
    to this session for the session-lifetime. If this function returns a
    non-nil value then the session will <span style="font-style:
    italic;">not</span> be reaped and instead the session will be treated as if
    it was just referenced and thus it will be kept alive for another
    session-lifetime. One common use for this function is to deallocate objects
    associated with the session that won't be recovered by the Lisp garbage
    collector when the session is garbage collected.
  - **`server`** - this is the wserver object into which this project will be
    published. It defaults to the value of **`*wserver*`**.
  - **`authorizer`** - an authorizer object that will be associated with all
    entities created in this project.
  - **`host`** - the value for the host argument to the publish function used to
    establish the project.
  - **`access-file`** - the filename of the access file(s) found in the project's
    directory. See the documentation for AllegroServe's publish-directory for
    details on access-files.
  - **`clp-content-type`** - a string holding the content type for all CLP files
    published in this project. The default is "text/html".
  - **`default-actions`** - the actions to invoke if there are no map-entry matches
    in the map. The default is **`nil`** (meaning no default actions).
  - **`external-format`** - the external format used when sending data back to the
    browser. The default is the value of **`*default-aserve-external-format*`**.
  - **`use-http-only-cookies`** - a boolean value (nil or non-nil) that determines
    whether the cookies automatically set by webactions will have the HttpOnly
    flag set.

A web site is a collection of pages and images, each page with references to
images and with links to other pages. The pages may be static or may be
generated by programs. The links and image references may be within the web
site or to other web sites. In a webaction web site we further distinguish
*managed* pages from *unmanaged* pages. Session information is maintained as
long as the user visits a sequence of managed pages. If a user visits an
unmanaged page and then follows a link to a managed page, the user may end up in
a new session. Thus when designing a webaction web site it's important to keep
the user on managed pages until the session information is no longer important.

A CLP file is a managed page. An html file that's not a CLP file is an
unmanaged page. A page generated by a Lisp function is a managed page if it
uses the **`locate-action-path`** function to compute the url's for href and action
attributes in the page it generates. Otherwise it's an unmanaged page.

The reason that there's a distinction between managed and unmanaged pages is
that if the browser doesn't accept cookies then the only way that session
information can be maintained is through url rewriting, and only managed pages
have the support for url rewriting.

Every managed page is named by a distinct Lisp string we call the *symbolic
name* of the page. All references to pages in CLP files and in CLP functions is
to the symbolic name of the page rather than the url of the page. The **`map`**
argument to webaction-project associates the symbolic name of a page with the
steps needed to render the page.

A symbolic page name can refer to a managed page, an unmanaged page or an
action. An action is a Lisp function which performs some operation and returns
a symbolic page name. Earlier we talked about the Model View Controller
methodology. In MVC terms, the action functions are operations on the Model.
An action function should not generate any html, that's the responsibility of
the View code.


#### Action and View functions

When processing a request user-written functions may be called to either specify
the control flow through the webaction project or to display html. We refer to
the former as *action functions* and to the latter as *view functions*. We make
the distinction between action and view to make the roles of these functions
clear with in the MVC framework. Webactions does not know nor need to know the
role of the user defined functions it calls. Webactions simply calls the
function and responds in a certain way to the value returned by the user defined
functions.

Both action and view functions are passed the standard two arguments: a request
object and an entity object. At the time these functions are called it's *not*
possible to immediately emit html as with-http-response and with-http-body have
not been done. The action function will return one of three values

  - a string giving the symbolic page name to jump to.
  - a string naming a file name whose contents are to be sent to the browser.
  - the symbol **`:continue`** meaning process the next item in the map clause.

A view function will call with-http-response and with-http-body and will send a
response back to the web server (possibly using the html macro). A view
function returns **`nil`** indicating that a response has been sent back to the http
client and no further processing should be done by webactions for this request.


#### Maps

The **`map`** argument specifies what steps are taken to process a request for a
symbolic page. In this section we'll describe the complete syntax of the map
value. If you're just learning Webactions you'll probably want to skip to the
Simple Maps section and then come back to this section when you're done reading
the rest of the document.

The value of the map argument is a list of map entries:

```lisp
(map-entry1 map-entry2 map-entry3 ....)
```

Each map entry is a list beginning with a symbolic page name and followed by
items which specify which actions to run, which view to render and a set of flag
values that apply to this entry. In pseudo-bnf the form of a map entry is:

```lisp
("symbolic page name"  item* [(:flag1 value1  ... ...) ] )
```

In our psuedo-bnf, the `*` means zero or more occurrences. The square brackets
mean zero or one occurrence.

An item can be a symbol or a string. If an item is a symbol it names a lisp
function which is either an action function or a view function. If the item is
a string then it either names a file to send back to the browser or a symbolic
page name.

An action function may modify the Model behind the website and then it returns
either a string naming a symbolic page name, as a string naming a file to send
back to the browser, or the keyword symbol **`:continue`** meaning go on to the next
item in the map entry. A view function will generate a response to the http
request (which usually means sending html to the browser). A view function
returns **`nil`** meaning that this request has been processed and there's nothing
more for webactions to do.

These are some typical map entries

```lisp
("home" "homepage.CLP")
("login" action-do-login "home")
("letter" action-check-login get-named-letter (:prefix t))
```

As noted above a string can represent either a file to send back to the browser
or a symbolic page name. If a given string is equal to the first value in a map
entry then it is symblic page name, otherwise it's a file to send back to the
browser. There is one exception: if a map entry doesn't have any items in it
then the string that's the first value of that map entry is the name of a file
to return. This special form is used when you wish to add flags to the
processing of a file. This is an example:

```lisp
("myletter.clp" (:content-type "text/plain"))
```

You need not understand the complete map entry syntax in order to use
Webactions. In fact you can build useful web sites using only a fraction of the
features of map entries. Next we'll gradually introduce you to maps and show
when you would want to use the advanced features.


#### Simple Maps

In its simplest form, the map is a list of two element lists. Each two element
list begins with the symbolic name of the page. This is followed by either the
location of the page or a function name. A function name can either name a
function that will generate a managed or unmanaged page, or it will be the name
of an action function. Usually a function name will not name a page generating
function, instead CLP files will be used for each page, however in some
situations it may prove useful to have totally dynamic pages generated by a lisp
function.

Here's an example of a map argument value

```lisp
(("home"          "home.clp")
  ("signin"       "signin.clp")
  ("newuser"      action-new-user)
  ("existinguser" action-existing-user)
  ("failedlogin"  user-failed-login)
  ("storefront"   "storefront.clp"))
```


In the example we have three symbolic pages that refer to CLP files. These are
thus managed pages. Two symbolic pages refer to functions whose names suggest
they are action functions. One symbolic page refers to a function
user-failed-login which is a function to dynamically create a page describing
the failed login attempt.

You can't distinguish an action function from a dynamic page generation function
based on what's in the map argument. If you're wise you'll use a naming
convention such as used above to make the distinction clear. The way that
Webactions determines which is which when running the function is that an action
function will return a string and a dynamic html generation function will return
nil.

In a CLP file relative urls that follow `"href="` or `"action="` are considered to
be the symbolic names of pages. Thus you can write

```html
<a href="home"> blah blah </a>
```
    
and that href will be transformed into the appropriate url such that the link
will be directed to the page associated with the page with the symbolic name
"home". It's still possible to reference pages outside the project using
absolute paths in url, such as `<a href="/othersite/index.html">check this out
too</a>` or `<a href="http://www.cnn.com"> read the latest news</a>`

The same conversion that applies to `href` links also applies to `src` links inside a `frame`, `script` or `img` element.

Now we have the background to describe exactly what webaction-project does.
**`webaction-project`** does a **`publish-prefix`** for the path that's the value of
project-prefix. This means that any url in that url-space will be processed as
a reference to an object in this project.

Let's create an example of a simple site that asks you to sign in and once
that's successful it lets you vote for your favorite food. The sign in process
ensures that at most one vote is recorded for each user.

```lisp
(webaction-project "sample" :project-prefix "/mysamp/" 
      :destination "/usr/proj/sample/" :index "main"
      :map '(("main" "main.clp")
             ("signin" action-sign-in)
             ("choice"   "choice.clp")
             ("vote"      action-vote)
             ("thanks"  "thanks.clp")))
```


The first page of the site has the logical name "main" and that causes the file
`main.clp` to be returned to the browser. Here is `main.clp`:

```html
<html>
<body>
<h1>Sign In Please</h1>

<mysamp_showerrors/>

<form action="signin" method="POST">
name: <input type="text"
             name="name" value="<clp_value name=name session/>"><br>
password <input type="password" name="password"><br>
<input type="submit">
</form>

</body>
</html>
```

There are just a few items to note in this page, and we've shown them in bold.
The first is the element `<mysamp_showerrors/>`. This will cause a CLP function
to be invoked, which we'll describe below. The next item to note is that the
value of `action=` is a symbolic page named "signin". The CLP processor will
transform "signin" to the appropriate value that depends on whether your browser
is accepting cookies. The final item to note is that the default value of the
text field for "name" is given by a `clp_value` tag. This CLP\_value retrieves
the value of the session variable "name", if it has a value. We'll see later
how this session variable is set. The idea is that if the user typed in his
name but failed to type in the correct password, we'll prompt him again for his
password and will fill in the name field for him. Note how the CLP\_value
element can be placed inside an html string value. This is because the CLP file
parser doesn't parse the html, it just looks for CLP element tags.

The CLP function `mysamp_showerrors` is this:

```lisp
(def-clp-function mysamp_showerrors (req ent args body)
  (declare (ignore ent args body))
  (let ((error (request-variable-value req "error")))
    (if* error
       then (html :br
        ((:font :color "red")
        (:princ-safe error))
       :br :br))))
```

This function looks on the request object for a variable named "error" and if
found prints that value of that variable in red. This is used to communicate to
the user problems found by the code that checks the name and password for
validity. We'll next see how that "error" variable is set.


When the user enters his name and password and clicks on the submit button
control is passed to the logical page "signin". Looking at the map above you'll
see that this causes the function **`action-sign-in`** to be called. Here is that
function:

```lisp
(defun action-sign-in (req ent)
  (declare (ignore ent))
  (let ((name (request-query-value "name" req))
 (password (request-query-value "password" req))
 (websession (websession-from-req req))
  )
    (setf (websession-variable websession "name") name)
    (if* (equal password
        (cdr (assoc name '(("joe" . "eoj")
                 ("fred" . "derf"))
               :test #'equal)))
       then ; success!
      (setf (websession-variable websession "signed-in") t)
       "choice"     ; show choice
       else ; failure
     (setf (request-variable-value req "error")
        "name and password are invalid")

        "main"  ; go back and try again
     )))
```

This function retrieves the values of the "name" and "password" values from the
set of form values. It retrieves the current session object which is stored on
the request object by the webaction framework code. Next it stores the name
given as the value of session variable "name". This means that the `clp_value`
form shown in main.CLP will be able to retrieve it should we get to that page
again. Next it checks if the password is valid. We have a very simple test in
our example, a real web site would use some kind of database to store the
password information. If the password matches we set the session variable
"signed-in" to true and return the string "choice". The webaction framework
then consults the map for a page named "choice" and finds that choice.clp should
be returned. If the name and password are not valid then action-sign-in returns
the string "main" causing main.clp to be returned and the user prompted again
for a name and password. Before returning "main" this function sets the request
variable "error" to a string to print when main.clp is sent back to the browser.

This is choice.clp:

```html
<html>
<body>
<h1>Vote</h1>
Ok <clp_value name="name" session/>, what do you like?
<br>
<form action="vote" method="POST">
favorite food: <input type="text" name="food"><br>
</form>
</body>
</html>
```

Here we ask the user for their favorite food. We personalize the page by
displaying the user's name on the page using `clp_value`. When the user types
in the food and presses enter the symbolic page "vote" is invoked. From the map
we see that that causes the function action-vote to be invoked.

```lisp
(defvar *votes* nil)

(defun action-vote (req ent)
  (declare (ignore ent))
  (let* ((food (request-query-value "food" req))
    (websession (websession-from-req req))
  (name (websession-variable websession "name")))
    (if* (websession-variable websession "signed-in")
       then (let ((ent (assoc name *votes* :test #'equal)))
          (if* ent
       then (setf (cdr ent) food)
      else (push (cons name food) *votes*)))
     "thanks"
       else ; not signed in, can't vote
     "main")))
```

The vote action checks to see if the user is logged in in which case it stores
the last value the user voted for in an assoc list in the variable **`*votes*`**.
The logged in test is important since a user may try to bypass the signing-in
process by just directing his web browser to `/mysamp/vote` which would run this
action function as well.

If the vote was recorded this function returns "thanks" which the map causes
thanks.clp to be returned:

```html
<html>
<body>
<h2>Thanks for voting</h2>
</body>
</html
```

#### Extended Maps

When designing a web application you usually want to force the user to login
first and then you open up the site to him. When a user enters the correct name
and password you modify the current session object to include an object that
identifies the user so that subsequent visits to this site during the same
session will be associated with the user who just logged in. What if a new user
doesn't come to the 'front door' of the web site but instead jumps right into
the middle of it?  How can you protect the site so that a non-logged-in user is
forced to start at the login page before visiting any other page of the site?
The answer is using *extended maps*. Let's look at the map from the project
mentioned above:

```lisp
        (("main" "main.clp")
         ("signin" action-sign-in)
         ("choice"   "choice.clp")
         ("vote"     action-vote)
         ("thanks"  "thanks.clp")))
```

In this map we would like the symbolic pages "choice", "vote" and "thanks" to be
reachable *only* if the current session has a logged in user. We can accomplish
this with

```lisp
        (("main" "main.clp")
         ("signin" action-sign-in)
         ("choice"   action-check-login choice.clp")
         ("vote"     action-check-login action-vote)
         ("thanks"   action-check-login "thanks.clp")))
```

Where we define action-check-login as:

```lisp
(defun action-check-login (req ent)
  (declare (ignore ent))
  (if* (websession-variable (websession-from-req req) "signed-in")
     then ; logged in
          :continue
     else ; not logged in
          "main"))
```

As you can see, a symbolic page name has a sequence of function names or strings
associated with it. The rule for processing a symbolic page name is to process
the list of items after the symbolic page name in this way:

  1. If the first item is a string then consider it to be a symbolic page name
     and start processing from the top.
  2. If the first item is a symbol then run the function value of that symbol.
     The return value from that function will be either
     - **`string`** - consider this to be a symbolic page name to render and start
       the processing from the beginning with this symbolic name,
     - **`nil`** - assume that the function called has already done the html
       response for this request so do nothing further,
     - **`:continue`** - if this particular keyword is returned then pop the list of
       items specified to process this symbolic page and go back to step 1.

If the map doesn't contain an entry for the symbolic page name then assume that
the symbolic page name is the actual name of a page on the site and return that.

In our example the function action-check-login tests to see if the user is
logged in and if he is returns :continue so that the next item in the list will
be used to process the symbolic page request. If the user is not logged in then
the string "main" is returned which causes the login page to be displayed (and
subsequent items in the list to handle the symbolic page request are ignored).


### Prefix Maps

It is possible to have one map entry specify how to handle a whole set of
symbolic page names. The syntax is this

```lisp
("name" action-or-view .... (:prefix t))
```

What distinguishes this syntax is that the last item is a list. That list
contain a sequence of flag names and values, in a property list format.

The meaning of **`:prefix t`** is that this map entry applies to all symbolic pages
name beginning with the string "name". For example if the project has a prefix
of "/foo/" then the following urls will be handled by this map entry:

```text
http://localhost/foo/name
http://www.foo.com/foo/named
http://www.bar.com/foo/namexxx/yyyy/zzz
```

Prefix map entries are the last ones considered when Webactions looks for a map
entry to handle a symbolic page name. Webactions first looks for a specific
symbolic page name entry. Then Webactions sees if the symbolic page name names
an actual file in the project directory. And finally if those first two
searches fail to find a map entry, Webactions looks for a prefix entry.

The precedence of the prefix entries search is "last mentioned first". That is
the last prefix map value in the map argument to webaction-project is tested
first, and then the second to last, and so on.

To continue our example above if there were also a map entry

```lisp
("name" action-do-name)
```

then this url

```test
http://localhost/foo/name
```

would be handled by the single symbolic name map entry rather than the prefix
entry.

Also if there were a file "name.clp" in the directory of files for this project
then the url

```text
http://localhost/foo/name.clp
```

would return this file rather than invoke the "name" as a prefix map entry.

We'll show two important uses for prefix map entries. The first is that you can
catch references to non-existent symbolic page names and return a nicer error
message than the standard one AllegroServe returns. The map entry

```lisp
("" handle-undefined-page (:prefix t))
```

will catch all symbolic page references that don't have a handler. You'll want
to list this entry before any other prefix entry in the map since you want this
entry to be checked last.

The second important use for prefix map entries arises when you wish to send a
file to the browser and you would like to suggest the filename for the file.
Browers usually use the name that appears after the last "/" in a url as the
default name of the file to store.

Thus if this url

```text
http://www.foo.com/myproj/sendfile/mypic.jpg
```

resulted in an "image/jpeg" being returned then the browser would prompt to
store this as "mypic.jpg". In a webaction project (with the project prefix of
"/myproj/") you would have a map entry such as this

```lisp
("sendfile/" return-filecontents (:prefix t))
```

### Redirection Maps

Suppose you click on the submit button in a form, and the method for that form
is "POST". The webserver will respond with another page. Now you click on a
link on that page to go to a new page. Now suppose you click on the Back button
on the web browser, which should take you to the page that was the result of
submitting the form. The browser should just show you the previous page from
its cache. Most browsers will do this except that Internet Explorer will often
tell you that the page has expired and it refuses to show you the page.

This is counterintuitive and user-unfriendly behavior on IE's part but still you
must handle it in some way.

One way to handle this is that whenever a POST is done the webserver processes
the posted data and then returns a Redirect response to the browser which then
does a GET of the page that's the target of the redirect. Thus the user ends up
looking at a page that was fetched with a GET, and thus IE will have no problem
returning to this page if the Back button is clicked.

You can specify this behavior in a map entry in this way

```lisp
("getdata" action-do-getdata "showresult.clp" (:redirect t))
```

The redirect flag says that rather than simply return the contents of
showresult.clp to the browser, Webactions will return a Redirect response to the
browser which will then fetch "showresult.clp". The consequence of this
redirect is that CLP functions invoked by showresult.clp will not have access to
the query values from the first request to "getdata" and they will not have
access to the request-variables that may have been set by action-do-getdata.
*This feature is still under development - we may change this in the future to
allow query and request variables to survive the redirect*.

If you're concerned about making your site work in IE you'll likely want to do
this redirect for all symbolic pages that are reached by a POST to a form.


### Content-Type maps

You can specify the content type of a file return by Webactions by adding a map
entry of the following form

```lisp
("myfile.clp" (:content-type "text/plain"))
```

By default CLP files are given the "text/html" content-type. You can override
this for all CLP files using the **`clp-content-type`** argument to
**`webaction-project`**. Specifying the content type in a map entry overrides all
other specifications.

Specifying the content-type in this way only works in this case where there are
no actions or views following the name of the file.


## <span id="Classes_used_in_webactions"></span>Classes used in webactions

These classes are used by the webaction framework. Except as noted the classes
should be considered opaque. Use only the documented functions to operate on
instances of these classes.

**`clp-entity`** - when CLP files are "discovered" in a webaction by being
referenced from a request url, a CLP-entity instance is created to describe the
page. This entity is then published so that the discovery process doesn't have
to happen again. When the CLP-entity is created a pointer to the webaction
object is placed in the entity so that CLP functions run during the processing
of the CLP file can find the webaction project they are running inside.

**`webaction-entity`** - there is one entity of this class for each webaction
project. This entity is published to capture all urls that begin with the
project prefix (if no other more specific entity captures them). The webaction
entity holds a pointer to a webaction object.


**`webaction`** - an instance of this class contains the information on a webaction
project. It contains the information passed as arguments to webaction-project
as well as a websession-master instance if sessions are to be maintained.

**`websession-master`** - an instance of this object is associated with a webaction
object if that project wants session support. The webaction-master object
contains the information for creating session ids and for automatically deleting
unused sessions. It also contains a map from cookie value to websession object.

**`websession`** - an instance of this class denotes a single session for a site
denoted by a webaction. The websession contains a "last used" time and will be
automatically removed after a certain amount of time without being used.


## <span id="storing_values"></span>Storing Values

A webaction project consists of cooperating independent objects: action
functions, CLP functions and CLP files. These objects often have a need to pass
data from one to another. Webactions offers three places to store data but of
course application specific code can also use other data repositories (such as
databases).


| Session                                                                                                  | Request Variable                      | Request Query                                                                                                        |
|----------------------------------------------------------------------------------------------------------|---------------------------------------|----------------------------------------------------------------------------------------------------------------------|
| **`(websession-variable session "name")`**                                                                   | **`(request-variable-value req "name")`** | **`(request-query-value "name" req)`**                                                                                   |
| `<clp_value name="name" session/>`                                                                       | `<clp_value name="name" request/>`    | `<clp_value name="name" query/>`                                                                                     |
| Lasts for the lifetime of a session. You can obtain the session object using **`(websession-from-req req)`** | Lasts for the lifetime of a request. | Lasts for the lifetime of a request. Initialized from the query string of the url of the request and from form data. |

The values can be set using **`setf`** of the corresponding accessor.


## <span id="Lisp_functions_for_webactions"></span>Lisp functions for webactions

These functions are useful inside CLP functions and webactions action functions.

-----

#### `net.aserve:locate-action-path`

```lisp
(locate-action-path webaction action-name websession)
```

Returns a url path to the action named **`action-name`** in the given **`webaction`**
and **`websession`**. This is used in a CLP function when you wish to provide a
value for a **`href`** or **`action`** attribute that should be directed to an action in
the current project.

```lisp
(html "go to " ((:a href (locate-action-path wa "signup" session)) "here")  " to sign up.")
```

You can find the current webaction object using **`webaction-from-ent`** and the
current session object using **`websession-from-req`**.

-----

#### `net.aserve:webaction-from-ent`

```lisp
(webaction-from-ent ent)
```

Returns the webaction object associated with this entity. This function
will return the webaction object for CLP-entity and webaction-entity
objects.   This function is rarely used since there is little that can
be done by user code with a webaction object.

-----

#### `net.aserve:webaction-from-req`

```lisp
(websession-from-req  req &optional ent)
```

Returns the websession object associated with this request (which is an
http-request object). If called from within an authorizer function the ent
argument should be supplied as well since when the authorizer function runs
webactions has not had a chance to store the session object into the req object.

-----

#### `net.aserve:websession-data`

```lisp
(websession-data websession)
```

Returns whatever data was stored in the session object by the user. Use **`(setf
(websession-data websession) xxxxx)`** to store data in the websession object. See
websession-variable for a way of storing data using a name as a key.

-----

#### `net.aserve:websession-key`

```lisp
(websession-key websession)
```

Returns the key for this session. This key is used in cookies and in the url
itself if cookies are not supported.

-----

#### `net.aserve:websession-key`

```lisp
(websession-variable websession name)
```

Returns the value of the session variable with the given name. The name can be
a string or symbol. It's compared against existing keys using the **`equal`**
function. Use **`setf`** to store the value of variables.

## <span id="Library_of_CLP_functions"></span>Library of CLP functions

The following CLP functions are supplied with AllegroServe.

-----

#### `clp_include`

```html
<clp_include name="filename" arg1="value1" arg2="value2" .../>
```

Insert the contents of the given file at this point. A relative filename will
be relative to the location of the file containing this `clp_include` element.
You may add additional arguments with names and values of your choosing.  These
can then be referenced via  <clp_value name="arg1" include/> in the included file.

-----

#### `clp_base`

```html
<clp_base/>
```

This emits a `<base href="xxx">` tag into the html stream. xxx is the location
of the CLP page being emitted. Due to the automatic internal redirecting done
by the webaction processor the initial url can be much different than the url
which describes the page being sent to the browser. If the page contains
relative references to images then the base tag will allow the browser to turn
those relative references into the correct absolute references. This tag must
be within the `<head> .... </head>` part of the page.

-----

#### `clp_value`

```html
<clp_value name="xxx" [safe] [query | request | session | include]/>
```

Retrieve the value of the variable named xxx from the location specified and
emit it to the html stream. If location is `query` then the value is retrieved
from the query string of a GET or the body and query string of the POST. If the
location is `request` then the value is retrieved from the request variables. If
the location is `session` then the values are retrieved from the session
variables.  If the location is `include` then the value is retrieved from the
clp_include arguments for all includes nested above this one.
If `safe` is given then the value will be printed in such a way to
escape any characters that would be interpreted as html (e.g. as **`(html
(:princ-safe xxx))`** would print the value). 

Example:

```text
    The value of query variable foo is <clp_value name="foo" safe query/>.
```

-----

#### `clp_set`

```html
<clp_set name="xxx" value="yyy" [query | request | session]/>
```

Sets the value of variable xxx to yyy in the given location. If you want to
pass values from one CLP function to another storing them in the request
location is best as the value will be isolated to this one http request.

-----

#### `clp_ifgt`

```html
<clp_ifgt name="xxx" value="yyy" [query | request | session]>
</clp_ifgt>
```

If the value of the variable xxx found at the given location is greater than the
value yyy then the body will be emitted to the html stream. The value yyy
should be an integer value.

-----

#### `clp_iflt`

```html
<clp_iflt name="xxx" value="yyy" [query | request | session]>
</clp_iflt>
```

If the value of the variable xxx found at the given location is less than the
value yyy then the body will be emitted to the html stream. The value yyy
should be an integer value.

-----

#### `clp_ifeq`

```html
<clp_ifeq name="xxx" value="yyy" [query | request | session]>
</clp_ifeq>
```

If the value of the variable xxx found at the given location is not eql to the
value yyy then the body will be emitted to the html stream. The value yyy
should be an integer value.

-----

#### `clp_ifneq`

```html
<clp_ifneq name="xxx" value="yyy" [query | request | session]>
</clp_ifneq>
```

If the value of the variable xxx found at the given location is eql to the value
yyy then the body will be emitted to the html stream. The value yyy should be
an integer value

-----

#### `clp_ifdef`

```html
<clp_ifdef name="xxx" [query | request | session]>
</clp_ifdef>
```

If the value of the variable xxx found at the given location is not nil then the
body will be emitted to the html stream.

-----

#### `clp_ifndef`

```html
<clp_ifndef name="xxx" [query | request | session]>
</clp_ifdef>
```

If the value of the variable xxx found at the given location is nil then the
body will be emitted to the html stream. If the variable xxx has never been set
then this is the same as it having a value of nil.

-----

#### `clp_ifequal`

```html
<clp_ifequal name="xxx" value="yyy" [query | request | session]>
</clp_ifequal>
```

If the value of the variable xxx found at the given location is equal to the
value yyy then the body will be emitted to the html stream. The value yyy can
be any value, but is likely to be a string.

-----

#### `clp_ifnequal`

```html
<clp_ifnequal name="xxx" value="yyy" [query | request | session]>
</clp_ifnequal>
```

If the value of the variable xxx found at the given location is not equal to the
value yyy then the body will be emitted to the html stream. The value yyy can
be any value, but is likely to be a string.

-----

#### `clp_options`

```html
<clp_options name="xxx" [query | request | session]>
    "opt1" "opt2" ... "optn"
</clp_options>
```

This function helps build a dynamically defaulted option list for the html
`<select>` element. Inside a `<select>` element are a sequence of `<option>`
elements with the default value denoted `<option selected>`. When generating an
option list the default value may not be known when the author writes the page.
The default can be based on some other value entered in the session. Thus this
form allows the default to be computed where the default value is found at
runtime from the value of the variable whose name is given as the value of the
`name` attribute. In the form shown above the variable name is `xxx`. Between
`<clp_options>` and `</clp_options>` are a sequence of lisp strings. When this
is processed the lisp strings are read with the lisp reader in order to create a
list of option values. If a `name=` attribute isn't present then the first lisp
string is made the default Example:

```html
<select name="color">
<clp_options name="defcolor" session>
    "blue" "green" "yellow" "red" "purple" "gold"
</clp_options>
</select>
```

-----

#### `clp_select`

```html
<clp_select args>body</clp_select>
```

This function simply emits a select form `<select args>body</select>`. The
reason for using `clp_select` instead of `select` is that some html editors get
confused by items inside the body of a `select` that aren't `option`
elements. In a CLP file you might want to put `clp_options` or `clp_include`
inside a `select` tag. If you use `clp_select` you can put whatever you want in
the body and most html editors will not object.

-----

#### `clp_response`

```html
<clp_response code="201"/>
<clp_response code="varname"/>
```

This function causes the given code to be returned to the browser when
this page is returned (by default a code of 200 is returned).
The code can either be expressed as an integer or as a session variable
name whose value at runtime will be used as the return value.


-----

#### `http_header-value`

```html
<http_header-value name="xxx"/>
```

Print the value of the given http header to the html stream. The name (here
`xxx`) is treated case-insensitively.

Example:

```html
    You are using browser <http_header-value name="User-Agent"/>.
```

-----

#### `wa_link`

```html
<wa_link name="xxx" extra="yyy"/>
```

This function is rarely if ever explicitly found in a CLP file however this
function is implicitly called whenever the CLP parser encounters an href= or
action= in a CLP file. The result of a call to wa_link is to take a url (here
xxx) and transform it into the appropriate url given whether the url is relative
or absolute and whether cookies are being accepted in the current session.
Extra is optional and if given specifies what string should be added to the end
of the resulting url. This is where a query string is usually placed.

Example:

```html
    <wa_link href="main" extra="?user=joe&password=123"/>
```

-----

#### `wa_showerrors`

```html
<wa_showerrors name="xxx" [query | request | session] [clear]/>
```

If the the variable named `xxx` in the location specified (`query`, `request` or
`session`) has a value then display that value in red in the html being returned
as part of the request. If `clear` is given then set the value of variable
`xxx` to `nil`. This is commonly used to display error messages on a page, such
as when a form wasn't filled out correctly and you're redisplaying the page and
asking the user to try again. The default location is `request`.
