Remove the `referrer' argument from resources.

This turned out to be a bad idea.  The thing is that some resources need
to be referred to in multiple ways -- for example, different texts in
links of different kinds, or using the URL directly in some cases.  The
existence of `get-resource-path' is a witness for this problem, since it
was used for such cases -- this function is removed as well.

There's no point in trying to generalize this here: instead, go back to
a simpler system where a resource always returns its URL (with an
optional argument to get an absolute URL).  When a `referrer'
functionality is needed, build it on top of that, in a place where it
makes more sense.  (That is, in a specific code for generating content,
where there could be a decision that resources have plain links and also
a very short link for use in navbars.)  Otherwise, it's usually simpler
to just define resources and referrers separately (as different
bindings, the latter uses the former).
This commit is contained in:
Eli Barzilay 2011-12-26 12:57:25 -05:00
parent 1cd8e6cbf3
commit 180651d04d

View File

@ -1,9 +1,9 @@
#lang racket/base
;; Resources are referrable & renderable objects, (most are html pages)
;; Resources are renderable & referrable objects, (most are html pages).
;; (resource path renderer referrer) creates and returns a new "resource"
;; value. The arguments are:
;; (resource path renderer) creates and returns a new "resource" value. The
;; arguments are:
;; - `path': the path of the output file, relative to the working directory,
;; indicating where the resource file should be put at, also corresponding to
;; the URL it will be found at. It must be a `/'-separated relative string,
@ -13,18 +13,16 @@
;; for the file to be created as an argument. This path will be different
;; than the `path' argument because this function is invoked in the target
;; directory.
;; - `referrer': a function accepting one or more arguments (and possibly
;; keywords) that produces a value to be used to refer to this resource
;; (using `a', `img', etc). The first value that will be passed to this
;; function will be the actual URL path, which depends on the currently
;; rendered page path -- the argument will be relative to it.
;; The resulting resource value is actually a rendering function that is
;; similar to the `referrer', except without the first URL argument -- when it
;; is called, it invokes the `referrer' function with the actual (relativized)
;; URL. Creating a resource registers the `renderer' to be executed when
;; rendering is initiated. Note that more resources can be created while
;; rendering; they will also be rendered in turn until no more resources are
;; created.
;; The resulting resource value is a function that returns the URL for the
;; resource. The function takes in an optional boolean which defaults to #f,
;; and when #t is given, the result will be an absolute full URL. Note that
;; the function can be used as a value for output, which will use it as a thunk
;; (that renders as the relative URL for the resource). The default relative
;; resulting URL is, of course, a value that depends on the currently rendered
;; resource that uses this value. Creating a resource registers the `renderer'
;; to be executed when rendering is initiated by `render-all'. Note that more
;; resources can be created while rendering; they will also be rendered in turn
;; until no more resources are created.
(require scribble/text)
@ -167,7 +165,7 @@
;; can be one of: #f (do nothing), 'delete-file (delete if a file exists, error
;; if exists as a directory)
(provide resource)
(define (resource path0 renderer referrer #:exists [exists 'delete-file])
(define (resource path0 renderer #:exists [exists 'delete-file])
(define (bad reason) (error 'resource "bad path, ~a: ~e" reason path0))
(unless (string? path0) (bad "must be a string"))
(for ([x (in-list '([#rx"^/" "must be relative"]
@ -196,7 +194,6 @@
(parameterize ([rendered-dirpath dirpathlist])
(printf " ~a\n" path)
(renderer filename))))))
(define (url) (relativize filename dirpathlist (rendered-dirpath)))
(define absolute-url
(lazy (define url (relativize filename dirpathlist '()))
(if (url-roots)
@ -205,18 +202,13 @@
;; construct a `file://' result
(list* "file://" (current-directory) url))))
(add-renderer path render)
(make-keyword-procedure
(lambda (kws kvs . args) (keyword-apply referrer kws kvs (url) args))
(case-lambda [(x) (if (and (pair? x) (eq? (car x) get-path))
(if (cdr x) absolute-url (url))
(referrer (url) x))]
[args (apply referrer (url) args)])))
;; make it possible to always get the path to a resource
(provide get-resource-path)
(define get-path (gensym))
(define (get-resource-path resource [absolute? #f])
(resource (cons get-path absolute?)))
(define (url [absolute? #f])
;; be conservative, in case it needs to be extended in the future
(case absolute?
[(#f) (relativize filename dirpathlist (rendered-dirpath))]
[(#t) (force absolute-url)]
[else (error 'resource "bad absolute flag value: ~e" absolute?)]))
url)
;; a convenient utility to create renderers from some output function (like
;; `output-xml' or `display') and some content