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).

original commit: 180651d04d554bb29a6128dd66a292d354140535
This commit is contained in:
Eli Barzilay 2011-12-26 12:57:25 -05:00
parent 984496bef4
commit 73784d91d9

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