[hunchentoot-devel] Lisp server page for hunchentoot

Mac Chan emailmac at gmail.com
Wed May 23 01:10:35 UTC 2007


I ported John Wiseman's lsp for use by hunchentoot.

You can check out the source from the contrib directory :

svn checkout svn://common-lisp.net/project/tbnl/svn

http://common-lisp.net/websvn/listing.php?repname=tbnl&path=%2Fcontrib%2Flsp%2F

Comments welcomed.

Cheers,
-- Mac


The following are copied verbatim from the comment

(asdf:oos 'asdf:load-op :cl-ppcre)
(asdf:oos 'asdf:load-op :hunchentoot-test)
(hunchentoot:start-server :port 8080)

;; verify that hunchentoot is running
;; http://localhost:8080/hunchentoot/test/

(asdf:oos 'asdf:load-op :lsp)

(in-package :lsp)

;; set debug on so we can examine the generated code
(set-lsp-debug t)

;; use cl-user package for all unqualified symbols
(set-lsp-package :cl-user)

;; compile the test file
(get-lsp-function (merge-pathnames "test.lsp" *this-dir*))

;; take a look at the generated code
(show-lsp-form (merge-pathnames "test.lsp" *this-dir*))

;; print the output to REPL
(do-lsp-request (merge-pathnames "test.lsp" *this-dir*))

;; install the dispatcher function
(push
  (create-lsp-folder-dispatcher-and-handler
  ;; uri
  "/hunchentoot/lsp/"
  ;; directory
  *this-dir*
  ;; valid lsp page suffixes
  '("lsp" "lhtml" "lhtm" "asp")
  ;; default content-type for non lsp files
  "text/plain")
  hunchentoot:*dispatch-table*)

;; try it out (click refresh a few times to verify that it is _dynamic_)
;; http://localhost:8080/hunchentoot/lsp/test.lsp

;; take a look at the source code too
;; http://localhost:8080/hunchentoot/lsp/lsp.lisp


;; alternatively, you can also create separate handler for each lsp file
(push
  (hunchentoot:create-prefix-dispatcher
  "/hunchentoot/lsp/test.lsp"
  (get-lsp-function (merge-pathnames "test.lsp" *this-dir*)))
  hunchentoot:*dispatch-table*)

;; finally, you can also reuse lsp function within a custom dispatch handler
(hunchentoot:define-easy-handler (lsp-demo :uri
"/hunchentoot/test/lsp-demo.html")
    ()
  (do-lsp-request (merge-pathnames "test.lsp" *this-dir*)))

;; http://localhost:8080/hunchentoot/test/lsp-demo.html


LAQ:

* Why another template module?

There are indeed a lot of template libraries including CL-EMB, Edi's
own HTML-TEMPLATE, etc. But these libraries are obstinate in that they
require you to construct and pass the `environment' variable in order
to generate the dynamic content.

Secondly, I found that the @if @else template extensions/add-ons are
often too limited in expressive power. You are programming lisp in the
backend, but all of a sudden you need to drop to a very dumb language
when you need to deal with the template code, which is kind of
frustrating.

John Wiseman's code is very close to what I need, but it is designed
to work with Franz's allegoserver. So I port it to work with my
preferred web server (hunchentoot) instead.


* So should I use this for all my dynamic content generation?

No. Absolutely not. If you take a look at the very simple test.lsp, it
screams like spaghetti code!

In the ideal world, if the graphics designer can deliver properly
formatted html in cl-who sexp, I'm all set. But that's not gonna
happen.

So for pages that I have total control, I prefer to write it using
sexp. However, there are times where the designer need to frequently
update a messy html template and I cannot afford to sync up with it
given the time constraint, using lsp is a good compromise.


* Any tips & tricks?

Lisp is very hard to write (and even harder to read) without a good
editor (like emacs) to help indenting your code and provide structured
editing.

So unlike other dumber languages (php, perl...), intermixed lisp code
with content is extremely hard to maintain and read.

In this regard, I would recommend you to use Franz's if-star package
( http://www.franz.com/~jkf/ifstar.txt ) in your template file because
it helps you to match the open and close parenthesis for if-then-else
conditional expression.

Also, unlike other dumber languages where if you have a syntax error
in the template file, the compiler can point you to the exact line
where it occurs. With lsp, the line number is lost when we use the
built-in lisp reader to read the form. However you can use
`show-lsp-form' in the REPL to examine the code when you encounter an
error.



More information about the Tbnl-devel mailing list