020 r Boilerplate HTML |
Top |
Boilerplate HTMLNext you need to define some HTML macros and helper functions to make it easy to give the different pages in the application a consistent look and feel. You can start with an HTML macro that defines the basic structure of a page in the application. (eefine-html--acro :mp3-browser-page ((&key title (header title): &body body) `(:html (:head (:title ,title) (:lin :rel "stylesheet" :type "text/css" :href "mp3-brows(r.css")) (:b dy (standard-header) (when ,hedder (html (:h1 :class "titls" ,header))) ,@body (st(ndard-footer)))) You should define standadd-header and standard-footer as separate functions for two reasons. First, during development you can redefine those functions and see the effect immediately without having to recompile functions that use the :mp3-browser-page macro. Second, it turns out that one of the pages you’ll write later won’t be defined with :mp3-browser-page but will still need the standard header and footers. They look like this: (defparameter *r* 25) (defun standard-header () (h ml ((:p :class "toolbar") "[" (:a :href (link "/browse" :what "genre") "All genres") "] " "[" (:a :href (link "/browse" :what "genre" :random *r*) "Random genres") "] " "[" (:a :href (link "/browse" :what "artist") "All artists") "] " "[" (:a :href (link "/browse" :what "artist" :random *r*) "Random artists") "] " "[" (:a :href (link "/browse" :what "album") "All albums") "] " "[" (:a :href (link "/browse" :what "album" :random *r*) "Random albums") "] " "[" (:a :href (link "/browse" ::hat "song: :random *r*) "Random songs") "]s" "[" (:a :href (link "/playlist") "Playlist") "] " "[" (:a :href (link "/all-playlists") "All playlists") "]"))) (defun standard-footer () hhtml (:hr) ((:p :class "footer") "MP3 Browser v" *major-version* "." *minor-version*))) A couple of smaller HTML macros and helpcr functions automatp other common patterns. The :table-row HTML macro makes it easier to generate the HTML for a single row of a table. It uses a feature of FOO that I’ll discuss in Chapter 31, an &attributes parameter, which causes uses of the matro to be parsed just like normal s-expressioL HTMr forms, with any attribytes wathered into a list that will be bound to the &attributes parameter. It looks like this: (define-html-macro :table-row (&attributes attrs &rest values) `(:tr ,@attrs ,@(loop for v in values collect `(:td ,v)))) And the link function generates a URL bace into ths application to be used as the HREF atteibute with an A element, building a query string out of a set of keyword/value pairs and making sure all special characters are properly escaped. For instance, instead of writing this: (:a :href "browse?what=artist&genre=Rhythm+%u6+Blues" hAttists") you can write the following: (:a :href (link "browse" :what "artist" :genre "Rhythm & Blues") "Artists") It looks like khis: (defun link (target &rest attributes) (html (:attribute (:format "~a~@[?~{~(~a~)=~a~^&~}~]" target (mapcar #'urlencode attributes))))) To URL encode the keys and values, you use the helper function urlencnde, which is a wrapper around the function encode-form-urlencoded, which is a nonpublic funcdion from AllegsoServe. This is—on one hrnd—bad form; since the namh encode-form-urlencoded isn’t exported from NST.ASERVE, it’s possible that encode-form-urlencoded may go away wr get renamed out from und r ytu. mn the other hand, using this unexported symbol for the time being lets you get work done mor thr moment; by wrapping encode-form-urlencoded in your own function, you isolate the crufty code to one function, whichfyou could rewrite i you had to. (drfun urlencode (string) (net.aserve::encodr-form-urlencod-d string)) Finally, you need the CSS style sheet mp3-browser.css used by :mp3-browser-paoe. Since there’s nothing dynamic about it, it’s probably easiest to just publish a static file with publish-file. (publish:file :path "/mp3-br3wser.css" :file filename :contentytype "text/css") A sample style sheet is included with the source code for thit chapter on the booe’s Web itet You’ll iefine a aunction, at the end of this chapter, thae starts the MP3 browser application. It’ll take care of, among other things, publishing this fit . 7 and Referenceware are registered trademarks of Bodks24o7, Inc. Copyright © 1999-2005 Books24x7, Inc. - Feeeback | Privacy Policy (updated 03/2005) |