-*- outline -*-

This directory contains UnCommon Web (UCW), a Common Lisp web application
platform.

* Getting Started

Well, there's a shortcut nowadays.  Marco Baringer made a UCW boxset
with all the dependencies boxed up and ready to fire.

wget http://common-lisp.net/project/ucw/ucw-boxset.tar.gz
tar -zxf ucw-boxset.tar.gz
cd ucw-boxset
YOURLISPHERE (-)-load start.lisp

This will start UCW with the built in httpd server backend. But if you
want to get the dependencies seperately or want a different initial setup,
then read on!

Assuming that every dependency is set up correctly then evaluating

(load (merge-pathnames "etc/start.lisp"
                       (asdf:component-pathname (asdf:find-system :ucw))))

should start up the examples at http://localhost:8080/

** Dependencies

UCW depends an a number of external libraries:

    * arnesi - an all purpose lisp toolkit
    * yaclml - yet another common lisp markup language
    * parenscript - javascript in common-lisp
    * iterate - a lispy loop
    * rfc2388 - implements multipart/form specification
    * rfc2109 - implements cookie specification
    * trivial-garbage - portable weak hashtables and pointers
    * bordeaux-threads - portable threads
    * split-sequence - splits sequences
    * slime - Superior Lisp Interaction Mode for Emacs
    * cl-ppcre - regular expressions lib
    * cl-l10n - l10n and i18n lib
    * trivial-sockets - handles stream sockets for undemanding network  
      applications 
    * net.uri or PURI - parses URI's according to the RFC 2396
      specification 
    * cl-fad - a portable pathname library based on code from PCL
    * net-telent-date - an RFC822-compliand date parser and printer
    * cl-launch - invokes lisp code from the command line
    * detachtty - a screen-like detachment tool to be able to detach
      and reattach the lisp server from and to a console 
    * a server backend - be it mod_lisp (apache 1 or 2), araneida,
      allegroserve, portable aserve or the built in httpd server 
    * asdf - a package loader facility

    
*** arnesi

Arnesi is a Common Lisp utility suite. It contains various "bits 'n
pieces" of code which were useful while developing other code. It can
be found on http://common-lisp.net/project/bese/arnesi.html. 

You will need the latest version:

darcs get http://common-lisp.net/project/bese/repos/arnesi_dev/
    
Daily snapshots are available at
http://common-lisp.net/project/bese/tarballs/arnesi_dev-latest.tar.gz 


*** yaclml

yaclml is a collection of macros and utilities for generating XML/HTML
like markup from lisp code. It can be found on
http://common-lisp.net/project/bese/yaclml.html. 

You will need the latest version:

darcs get http://common-lisp.net/project/bese/repos/yaclml/
    
Daily snapshots are available at:
http://common-lisp.net/project/bese/tarballs/yaclml-latest.tar.gz 


*** parenscript - ucw version

Parenscript is a javascript compiler. You will need to get the latest
development version: 

darcs get http://common-lisp.net/project/ucw/repos/parenscript/
    
Daily snapshots are available at:
http://common-lisp.net/project/ucw/tarballs/parenscript-latest.tar.gz 


*** iterate

Iterate is an iteration construct for Common Lisp. It can be found on
http://common-lisp.net/project/iterate/

Download link:
http://common-lisp.net/project/iterate/releases/iterate-current.tar.gz 


*** rfc2388 - ucw version

Rfc2388 is a lisp implemantation of RFC 2388, which is used to process
form data posted with HTTP POST method using enctype
"multipart/form-data". 

UCW uses its own fork of rfc2388. You can get the latest code from the
darcs repository located at
http://common-lisp.net/project/ucw/repos/rfc2388: 

darcs get http://common-lisp.net/project/ucw/repos/rfc2388/

Daily snapshots are available at
http://common-lisp.net/project/ucw/tarballs/rfc2388-latest.tar.gz 


*** rfc2109 - ucw version

Rfc2109 is the lisp implementation of the cookie protocol. You can get
it at: http://common-lisp.net/project/rfc2109/: 

darcs get http://common-lisp.net/project/rfc2109/rfc2109
    
Daily snapshots are available at
http://www.common-lisp.net/project/rfc2109/release/rfc2109-latest.tar.gz 


*** split-sequence

splits sequences

info: http://www.cliki.net/SPLIT-SEQUENCE

download: http://ww.telent.net/cclan/split-sequence.tar.gz (you might
have to select a mirror first) 

If said link is dead, go to http://ww.telent.net/cclan-choose-mirror
to delete your CCLAN-SITE cookie and choose another mirror. At least
some of them are definitely working. 


*** SLIME

The Superior Lisp Interaction Mode for Emacs.

Download and install the latest CVS version of SLIME from
http://common-lisp.net/project/slime. 

To checkout from CVS you must first login to the repository:

export CVSROOT=:pserver:anonymous@common-lisp.net:/project/slime/cvsroot
cvs login
    
Enter anonymous when prompted for the password. You can then check out
the latest version with: 

cvs checkout slime
    
It's swank you want to add to your asd systems dir. To solve a current
problem with cl-launch you might want to overwrite your swank.asd file
with this one:

http://cl-debian.alioth.debian.org/repository/pvaneynd/slime/debian/swank.asd

Check the description on cl-launch to see why.


*** cl-l10n

Localization and internationalization library: http://common-lisp.net/project/cl-l10n/

Get the latest version with:
  darcs get http://www.common-lisp.net/project/cl-l10n/repos/cl-l10n


*** cl-ppcre

Edi Weitz's regular expression library: http://www.weitz.de/cl-ppcre/.

Download the latest version: http://weitz.de/files/cl-ppcre.tar.gz


*** trivial-sockets

Networking library to create small server applications. Download the
latest version from: http://ww.telent.net/cclan/trivial-sockets.tar.gz
(you might have to select a mirror first. 

If said link is dead, go to http://ww.telent.net/cclan-choose-mirror
to delete your CCLAN-SITE cookie and choose another mirror. At least
some of them are definitely working. 

Or use asdf install.


*** net.uri/PURI

All of the backends (except araneida) depend on Franz's open-source
net.uri library. It only works on Allegro but Kevin Rosenberg has made
a portable version called PURI. 

For allegro users, NET.URI can be downloaded from here (it may be
included in your version of acl):
http://opensource.franz.com/uri/index.html 

If you're not using allegro you'll need puri which can be downloaded
from http://puri.b9.com/download.html 


*** cl-fad

A portable pathname library based on code from Peter Seibels book
Practical Common Lisp. 

info: http://www.cliki.net/CL-FAD

download: http://weitz.de/files/cl-fad.tar.gz


*** net-telent-date

A library consisting mostly of the time parsing routines from CMUCL
that were removed from SBCL. Additionally it has a universal-time to
rfc822 date convertor.

info: http://www.cliki.net/net-telent-date

download: http://ww.telent.net/cclan/net-telent-date.tar.gz

*** cl-launch

A bash script to make your Lisp software easily invokable from the
shell command-line. 

info: http://www.cliki.net/cl-launch

download page: http://fare.tunes.org/files/cl-launch/

Download and add to your shell executable search path so ucw can find
it while loading. Cl-launch can either be called cl-launch or
cl-launch.sh, ucw will check for both. Also cl-launch depends on swank
behavior other than that of the current cvs code, at least under sbcl,
eg via swank-loader it looks for files under the load path, which is not
what you want if you made a symbolic link to another dir. The easiest way
to get around this problem is to overwrite your swank.asd file (in the
slime directory root), with this one:

http://cl-debian.alioth.debian.org/repository/pvaneynd/slime/debian/swank.asd 

If you are a Debian user and you got slime/swank through apt-get, you
already have this version on your harddisk/pendrive.

The downside might be that swank won't work anymore as it should,
although i haven't heard anyone about this yet. Another approach is to
copy your swank*.fasls from the slime directory to the relevant shadow
directory under ~/.cache/... 

Check this thread for more info:
http://common-lisp.net/pipermail/slime-devel/2006-March/004664.html

Yes, ucw is bleeding edge ;)


*** detachtty - ucw version

A screen-like detachment tool to be able to detach and re-attach the
lisp server from and to a console. Ucw uses a custom detachtty
version, e.g. detachtty-9 plus a patch by Kevin Rosenberg. It accepts
an eval argument when invoking a lisp, with obvious benefits. Get it
through Darcs: 

darcs get http://common-lisp.net/project/bese/repos/detachtty/

Go to the directory root and compile and install:

make
make install
    

** the backend

choose one of mod_lisp/mod_lisp2, araneida, aserve/paserve or the
built-in httpd server


*** mod_lisp/mod_lisp2 for apache

You can choose between apache 1 and 2. First of course you have to
have a Apache web server up and runnnig; then you have to add the
mod-lisp module by Marc Battyani which you find at
http://www.fractalconcept.com/asp/html/mod_lisp.html 

First download the mod_lisp c file. Watch out, don't follow the logic
of the website. Except for the windows version the info is outdated
concerning the apache 1 version and info about apache 2 is
non-existent. Go to subversion from the download page or click the
links below: 

    * apache 1 .c file - mod_lisp.c
    * apache 2 .c file - mod_lisp2.c
   
use the command:

apxs -i -c mod_lisp.c
    
or

apxs2 -i -c mod_lisp2.c
    
for respectively apache 1 or 2. This will install the module in the
appropriate apache directory. Then add the following lines to
'httpd.conf' in your apache configuration directory for both apache 1
and 2. Just be sure to change mod_lisp.so to mod_lisp2.so for apache
2:

# This goes near the other LoadModlue directives
    
LoadModule lisp_module modules/mod_lisp.so
    
LispServer 127.0.0.1 3001 ucw
    
<LocationMatch "/path/.*\.ucw">
               SetHandler lisp-handler
</LocationMatch>
    
This means that ucw INTERNALLY talks to apache on port 3001 at the
internet address 127.0.0.1 (so in this case your localhost). The
locationmatch part redirects all traffic from (in this case) 127.0.0.1
with prefix "/path/" and files ending on .ucw to ucw. So
http://127.0.0.1/path/something.ucw as well as
http://127.0.0.1/path/anotherpath/somethingelse.ucw will be
redirected, but not http://127.0.0.1/somethingfaulty.ucw or
http://127.0.0.1/path/somethingfaulty.html.


*** allegroserve or portableaserve

Should you want to use the aserve backend you will need to download
and install either the AllegroServe if you use acl or portableaserve
for any other. AllegroServe doesn't seem to have an asdf file, you're
going to have to load it manually or however AllegroServe handles it's
own files. Portableaserve does however.

AllegroServe can be downloaded from here (it may be included in your
version of acl): http://opensource.franz.com/aserve/

portableaserve is hosted on sourceforge: http://portableaserve.sf.net

portableaserve download: http://constantly.at/lisp/aserve.tar.gz

To use portableaserve you'll also need the Allegro Common Lisp
compatibility package (acl-compat). It's part of portableaserve and so
it's home is also the before-mentioned sourceforge site.

acl-compat download: http://constantly.at/lisp/acl-compat.tar.gz


*** araneida

Should you want to use the araneida backend you will need to download
araneida. Get the latest version just to be on the safe
side. Originally araneida was meant to live behind apache and it can
of course still be configured as such. Explaining this is beyond the
scope of this document but have a look at this site for more info.

info: http://www.cliki.net/Araneida}

download: http://common-lisp.net/project/araneida/release/araneida-latest.tar.gz

or use darcs, although the connection seems a bit slow:

darcs get http://verisons.telent.net/araneida/


*** httpd

Ucw's in-house server. It's a simple server bundled with ucw. Nice for
testing.


** Setting up ASDF

UCW, and all the libraries it depends on, use ASDF for loading and
compiling the code in the proper order. The first thing you must do is
make sure that ASDF can find the system definitions for ucw and all
the related libraries.

ASDF searches for system definition files by looking in the
directories in the list asdf:*central-registry*. To make a system
definition visible you can either push the name of the directory which
contains the .asd file onto the list asdf:*central-registry* or you
can create a symlink from the .asd file to a directory which is
already in the list asdf:*central-registry*. 

For example: on some linux installations the directory
/usr/share/common-lisp/systems is in the list asdf:*central-registry*,
by creating a symlink from a particular .asd file to
/usr/share/common-lisp/systems (ln -s /path/to/library/lib.asd
/usr/share/common-lisp/systems) we guarentee that (adsf:oos
'asdf:load-op :lib) will Just Work(TM).


** Testing UCW

When you have set up all your dependencies correctly, you can test
ucw by first creating either /etc/ucw/applications.d or
/path/to/home/.ucw/applications.d, firing
up your favorite distribution and type:

(load "/path/to/ucw/etc/start.lisp")

If all went well, you have started ucw with the httpd backend. Surf to
\link{\href{http://127.0.0.1:8080}\text{http://127.0.0.1:8080}} and
again if all went well you should see the example page. That's it!
Start hacking!!

To run ucw detached use the ucwctl script under /path/to/ucw/bin/
For an explanation of it's configuration check the ucw-intro html under
/docs/ucw-intro.


* Documentation

Check the docs section for various introductions, tutorials, quickstarts and
code examples. The API documentation is, as much as possible, contained in
the docstrings of the various classes, methods, and packages which make
up UCW itself. Using a good inspector (SLIME's inspector for example)
you should be able to easily navigate and browse the API.

* Developing UCW

Eventually (probably too soon) you'll discover a bug or a missing
feature in UCW and want to fix it. The first thing to do is to send an
email to bese-devel@common-lisp.net and make sure it's a real bug or
missing feature (and not a user or documentation error).

If you do have a bug fix or feature improvement you'd like to submit
there are two ways to go about sending the patch: if the patch is
relativly small than just send a plain old diff or a tar ball of the
arch changeset to the list. If it is bigger, send it to ucw_public
and eventually it will find it's way to ucw_dev. If the change is
bigger than bigger or requires multiple patches over time then branch
off of ucw_dev and publish your repository with your changes. 

** Reporting BUGS

The simplest thing you can is just send an email to
bese-devel@common-lisp.net. We keep a collection of all the known bugs
and issues as text files in the directory docs/issues.

*** Using darcs

**** Creating a changeset

# darcs send

or, if you don't have sendmail properly set up;

# darcs send -o CHANGESET

Then just mail the file CHANGESET to bese-devel@common-lisp.net

**** Branching from ucw--dev

You already have a branch. :)