#lang scribble/doc @require[(planet cce/scheme:4:1/planet) scribble/manual scribble/eval scribble/basic] @require[(for-label web-server/servlet web-server/servlet-env web-server/http scheme/base "main.ss")] @title[#:tag "top"]{@bold{Static Page}: Developing Static Web Pages} by @author+email["Dave Herman" "dherman@ccs.neu.edu"] This library provides a simple abstraction for building static web content that can be rapidly developed and tested, and then exported to raw HTML. @defmodule/this-package[] @table-of-contents[] @section[#:tag "intro"]{Introduction} This package is intended to ease the development of web sites that contain only static pages. This is useful for generating sites with multiple pages that share common structure. In this case, while the full power of dynamic servlets may not be necessary, the benefits of building templates and abstractions are still important. Moreover, PLT Scheme and the PLT Web Server are fantastic for rapidly developing and debugging a web site---X-expressions, @scheme[quasiquote] and @scheme[unquote], and of course data and functional abstraction are all simple and powerful tools for building web pages. Even better, with @scheme[serve/servlet] it's easy to test a web site from within DrScheme with a push of the @bold{Run} button. This library provides the last piece: converting that dynamically generated servlet into a static collection of HTML files. Consider a simple example of a static web site with three pages: @schemeblock[(define index (static-page "index.html" (lambda (embed-url) `(html (head (title "My Web Site")) (body (p "Check out my " (a ([href ,(embed-url cv)]) "CV."))))))) (define cv (static-page "cv.html" (lambda (embed-url) `(html (head (title "My CV")) (body (p (a ([href ,(embed-url index)]) "Dave Herman")) ,@(for/list ([job job-history]) (job->xexpr job))))))) (define (job->xexpr job) ...)] Notice how the pages are created with @scheme[static-page] instead of as explicit functions from @scheme[request?] to @scheme[response/c]. Pages built with @scheme[static-page] can @italic{behave} like procedures that call @scheme[send/suspend/dispatch], so we can actually treat this web site as a servlet and test it in DrScheme: @schemeblock[(serve/servlet index)] But we can extract the HTML source of the site and save it to disk as well: @schemeblock[(define my-site (build-site index)) (save-site my-site #:root (build-path 'same "saved"))] @section[#:tag "pages"]{Static Pages} @defproc[(static-page [path string?] [build-response ((static-page? -> string?) -> (or/c response/full? xexpr?))]) static-page?]{ Constructs a static page structure. The @scheme[path] is the address by which other pages in the site can link to this page. The @scheme[build-response] procedure generates a response, similar to regular servlets. Note, however, that incremental responses are unsupported. The argument to @scheme[build-response] is a procedure that produces the address of static pages in the site. } @defproc[(static-page? [x any]) boolean?]{Determines whether @scheme[x] is a static page.} @defproc[(static-page-path [page static-page?]) string?]{ Returns the local address of @scheme[page].} @section[#:tag "sites"]{Sites} @defproc[(build-site [front-page static-page?]) site?]{ Builds all pages in a site, recursively following all local links and adding the generated pages to the site. } @defproc[(site? [x any]) boolean?]{Determines whether @scheme[x] is a site.} @defproc[(save-site [site site?] [#:root root path-string? (current-directory)] [#:exists exists-flag (or/c 'error 'append 'update 'replace 'truncate 'trunace/replace) 'error]) any]{ Saves all the pages in @scheme[site] to the filesystem, based in the @scheme[root] directory. The optional @scheme[exists-flag] determines the behavior of @scheme[call-with-output-file*] in case any of the files already exist. }