Search URLs

So far we have looked at computed URLs and computed forms. The third type of computed URL supported by CL-HTTP is the search URL.

A typical search URL looks like:

http://www.mysite.com/lookup?aardvark+bat+crayfish

where lookup is the routine, and aardvark, bat, and crayfish are parameters to the routine. An alternative format with named parameters is:

http://www.mysite.com/lookup?name=aardvark&option=1&page=3

where name, option, and page are parameters, and aardvark, 1, and 3 are their respective values. CL-HTTP can interpret both of these formats.

In this example we are going to write a response function to handle URLs of the form:

/doc?function-name

where function-name is an arbitrary string. Here's the definition:

(defun search-documentation (url stream)
  "Handles a search URL of the form: /doc?function-name to display the documentation for a function."
  (with-slots (search-keys) url
    (let* ((name (first url:search-keys))
           (title (format nil "Documentation of '~a'" name))
           (doc (documentation (find-symbol (string-upcase name) :http-user) 'function)))
      (with-page (url stream title)
        (with-paragraph (:stream stream) 
          (write-string (or doc "Not found.") stream))))))

CL-HTTP automatically parses the search keys and returns them as a list in the slot search-keys of the URL. By default it assumes the search keys are separated by '+' characters. In this example we only use the first of these.

The response function then interns the function name string, calls the documentation function to retrieve the documentation string for the function, and displays it:

search.gif

Finally, here's the routine to create the URL for the search:

(export-url "http://localhost:8000/doc?" :search :response-function 'search-documentation) 

A classic use for search URLs is to create lists of links, such as in the navigation bar of a site, or a table of contents of a directory. To illustrate this we will create a table of contents for the CL-HTTP demo routines we've already created. The routine uses the CL-HTTP routine note-anchor to create the links. For example, the following call emits the HTML for a call to /doc?mark-quiz:

(note-anchor "mark-quiz" :reference "/doc?mark-quiz" :stream stream)

The routine uses a list of the routines stored in *routines*:

(defparameter *routines* 
  '("write-demo-page" "aphorism" "write-aphorism-page" "display-bulletin-board" "display-board" 
                      "update-bulletin-board" "display-quiz" "mark-quiz" "search-documentation" "write-demo-toc"))

Here's the write-demo-toc routine:

(defun write-demo-toc (url stream)
  "Write a table of contents for the CL-HTTP demo routines."
  (with-page (url stream "Table of Contents")
    (dolist (entry *routines*)
      (with-paragraph (:stream stream)
        (note-anchor entry :reference (format nil "/doc?~a" entry) :stream stream)))))

As usual, we make the URL available with export-url:

(export-url "http://localhost:8000/toc.html"
            :computed
            :response-function #'write-demo-toc)

Here's the result:

toc.gif

Clicking on any link displays the routine's documentation using the search URL.


blog comments powered by Disqus