#lang scheme/base
(require net/url
(planet "dispatch.ss" ("untyped" "dispatch.plt" 1 5))
(planet "web.scm" ("soegaard" "web.plt" 2 1))
(planet "digest.ss" ("soegaard" "digest.plt" 1 1))
"util.scm"
"web-support.scm"
"session.scm"
"settings.scm"
"time.scm")
(provide define-page
define-session-page
page
page?
design
**
page-url
redirect-to-page
js-inc
css-inc
versioned-file-reference
)
(define-syntax define-page
(syntax-rules ()
((_ (page-name args ...)
keywords-and-body ...)
(define-controller (page-name args ...)
(page keywords-and-body ...)))))
(define-syntax define-session-page
(syntax-rules ()
((_ (page-name req-iden sesh-iden args ...)
keywords-and-body ...)
(define-controller (page-name req-iden args ...)
(sessioned-response req-iden (sesh-iden)
(page keywords-and-body ...))))))
(define (page #:doc-type (doc-type #f)
#:raw-header (raw-header '())
#:css (css '())
#:js (js '())
#:atom-feed-page (atom-feed-page #f)
#:rss-feed-page (rss-feed-page #f)
#:title (title "a LeftParen web app")
#:body-attrs (body-attrs '())
#:body-wrap (body-wrap (lambda (body) body))
#:blank (blank #f)
#:plain-text (plain-text #f)
#:design (a-design #f)
#:redirect-to (redirect-to #f)
. body)
(let ((returned-body
(if (empty? body)
(if (not redirect-to)
(e "Unless you are doing a #:redirect-to, a body is required.")
#f)
(last body))))
(cond (redirect-to (response-promise-to-redirect redirect-to))
((response/full? returned-body) returned-body)
(plain-text (basic-response (list returned-body)
#:type #"text/plain; charset=us-ascii"))
(blank returned-body) (a-design (a-design returned-body))
(else (let ((main `(html (head ,@(map css-inc css)
,@(splice-if atom-feed-page
(atom-inc (page-url atom-feed-page)))
,@(splice-if rss-feed-page
(rss-inc (page-url rss-feed-page)))
,@(map js-inc js)
,@(map raw-str raw-header)
(title ,title))
(body ,body-attrs ,(body-wrap returned-body)))))
(if doc-type
`(group ,(raw-str doc-type) ,main)
main))))))
(define (design #:raw-header (raw-header '())
#:css (css '())
#:js (js '())
#:title (title "a LeftParen web app")
#:atom-feed (atom-feed '())
#:rss-feed (rss-feed '())
#:doc-type (doc-type #f) #:body-attrs (body-attrs '())
#:body-wrap (body-wrap (lambda (body) body)))
(lambda (body) (page #:doc-type doc-type
#:raw-header raw-header
#:css css
#:atom-feed atom-feed
#:rss-feed rss-feed
#:js js
#:title title
#:body-attrs body-attrs
#:body-wrap body-wrap
body)))
(define (** . bodies)
`(group ,@bodies))
(define (js-inc script-filename)
`(script ((src ,script-filename) (type "text/javascript")) ""))
(define (css-inc css-filename)
`(link ((rel "stylesheet") (type "text/css") (href ,css-filename))))
(define (atom-inc feed-url)
`(link ((rel "alternate") (type "application/atom+xml") (href ,feed-url))))
(define (rss-inc feed-url #:title (title "RSS feed"))
`(link ((href ,feed-url) (rel "alternate") (type "application/rss+xml")
(title ,title))))
(define (versioned-file-reference filename)
(string-append filename "#" (number->string (setting *APP_VERSION*))))
(define (redirect-to-page page-name . args)
(redirect-to (apply controller-url page-name args)))
(define (page-url page #:absolute (absolute #f))
(let ((rel-url (controller-url page)))
(if absolute
(url->string (combine-url/relative (string->url (setting *WEB_APP_URL*))
rel-url))
rel-url)))
(define page? controller?)