r3094: *** empty log message ***
[kmrcl.git] / web-utils-aserve.lisp
1 ;;;; -*- Mode: Lisp; Syntax: ANSI-Common-Lisp; Base: 10 -*-
2 ;;;; *************************************************************************
3 ;;;; FILE IDENTIFICATION
4 ;;;;
5 ;;;; Name:          web-utils-aserve.lisp
6 ;;;; Purpose:       Web utilities based on aserve functions
7 ;;;; Programmer:    Kevin M. Rosenberg
8 ;;;; Date Started:  Apr 2000
9 ;;;;
10 ;;;; $Id: web-utils-aserve.lisp,v 1.9 2002/10/18 05:14:49 kevin Exp $
11 ;;;;
12 ;;;; This file, part of KMRCL, is Copyright (c) 2002 by Kevin M. Rosenberg
13 ;;;;
14 ;;;; KMRCL users are granted the rights to distribute and use this software
15 ;;;; as governed by the terms of the Lisp Lesser GNU Public License
16 ;;;; (http://opensource.franz.com/preamble.html), also known as the LLGPL.
17 ;;;; *************************************************************************
18
19
20 (in-package :kmrcl)
21 (declaim (optimize (speed 3) (safety 1) (compilation-speed 0) (debug 3)))
22
23
24 ;;; AllegroServe interaction functions
25
26 (defun cgi-var (var req)
27   "Look CGI variable in AllegroServe association list"
28   (cdr (assoc var (net.aserve:request-query req) :test #'equal)))
29
30 (defun princ-http (s)
31   (princ s *html-stream*))
32
33 (defun print-http (s)
34   (format *html-stream* "~a~%" s))
35
36
37 ;;; Tag functions
38
39 (defmacro with-tag (tag &rest body)
40   "Outputs to http tag and executes body"
41   `(prog1
42        (progn
43          (princ-http (format nil "<~a>" ,tag))
44          ,@body)
45      (princ-http (format nil "</~a>" ,tag))))
46   
47 (defmacro with-tag-attribute (tag attribute &rest body)
48   "Outputs to http tag + attribute and executes body"
49   `(prog1
50        (progn
51          (princ-http (format nil "<~a ~a>" ,tag ,attribute))
52          ,@body)
53      (princ-http (format nil "</~a>" ,tag))))
54   
55 (defun princ-http-with-color (text color)
56   (with-tag-attribute "font" (format nil "color=\"~a\"" color)
57                       (princ-http text)))
58
59 (defun princ-http-with-size (text size)
60   (with-tag-attribute "font" (format nil "size=\"~a\"" size)
61                       (princ-http text)))
62
63 (defmacro with-link ((href &key (format :html)) &rest body)
64 ;   (format *html-stream* "Return to <cui2 xml:href=\"qstr\">Home</cui2>")
65 ;   (format *html-stream* "Return to <go xml:link=\"simple\" show=\"replace\" href=\"qstr/\">Home</go>")
66   `(case ,format
67      (:xml
68       (princ-http "<elem xlink:type=\"simple\" xlink:href=\"")
69       (princ-http ,href)
70       (princ-http "\">")
71       ,@body
72       (princ-http "</elem>"))
73      (:ie-xml
74       (princ-http "<html:a href=\"")
75       (princ-http ,href)
76       (princ-http "\">")
77       ,@body
78       (princ-http "</html:a>"))
79      (:html
80       (princ-http "<a href=\"")
81       (princ-http ,href)
82       (princ-http "\">")
83       ,@body
84       (princ-http "</a>"))))
85
86 (defun home-link (&key (format :html) (vars nil))
87   (case format
88     (:html
89      (princ-http "<div class=\"homelink\">Return to ")
90      (with-link ((make-url "index.html" :vars vars))
91                 (princ-http "Home"))
92      (princ-http "</div>"))
93     ((:xml :ie-xml)
94      (princ-http "<homelink>Return to ")
95      (with-link ((make-url "index.html" :vars vars :format format) :format format)
96        (princ-http "Home"))
97      (princ-http "</homelink>"))))
98
99 (defun head (title-str &key css)
100   (unless css
101     (setq css "http://b9.com/main.css"))
102   (net.html.generator:html 
103    (:head
104     (princ-http (format nil "<link rel=\"stylesheet\" href=\"~A\" type=\"text/css\"></link>" css))
105     (:title (:princ-safe title-str)))))
106
107
108
109 ;;; Page wrappers
110
111 (defmacro with-page ((title &key css (format :xhtml)) &rest body)
112   (case format
113     (:xhtml
114      `(prog1
115           (progn
116             (net.html.generator:html
117              (print-http *standard-xhtml-header*)
118              (print-http "<html xmlns=\"http://www.w3.org/1999/xhtml\">")
119              (head ,title :css ,css)
120              (print-http "<body>")
121              (prog1 
122                  ,@body
123                (print-http "</body></html>"))))))
124     (:html
125      `(prog1
126           (progn
127             (net.html.generator:html
128              (print-http *standard-html-header*)
129              (head ,title :css ,css)
130              (print-http "<body>")
131              (prog1 
132                  ,@body
133                (print-http "</body></html>"))))))
134     (:xml
135      `(prog1
136           (progn
137             (net.html.generator:html
138              (princ-http *standard-xml-header*)
139              (princ-http "<pagedata xmlns:xlink=\"http://www.w3.org/1999/xlink\" xmlns:html=\"http://www.w3.org/TR/REC-html40\">"))
140             (with-tag "pagetitle" (princ-http ,title))
141             ,@body)
142         (princ-http "</pagedata>")))))
143
144
145 ;;; URL Encoding
146
147 (defun encode-query (query)
148   "Escape [] from net.aserve's query-to-form-urlencoded"
149   (substitute-string-for-char
150    (substitute-string-for-char
151     (substitute-string-for-char 
152      (substitute #\+ #\space query)
153      #\[ "%5B")
154     #\] "%5D")
155    #\" "%22"))
156
157