There are several ways for a peak.web
location to determine its URL:
- By traversal: “my URL is whatever URL you used to get to me”
- Relative to a location: “I’m here, relative to some known location”
- By component context: “I’m a child of this other component”
- Site root relative: “I’m this path from the top of the application”
- Absolutely: “I know exactly where I am”
All of these serve essential purposes. By-traversal allows most components not to worry about location. By-location allows content objects to locate themselves relative to the nearest “specialist” serving objects of their kind. By-component-context allows resources in a skin layer (or locations in a site map) to refer themselves relative to a parent. Site root relative allows objects like a skin layer or a sitemap root to position themselves according to the application. True absolute positioning is useful for creating “mount points” into some other system, such as indicating that a set of static resources are actually located on a different server.
Some object types, however, need to play more than one role. For example, a Location
object might be site-root relative (if it’s the site root), or it might be by-component (if it’s not). A ResourceDirectory
might need to be absolute (if it’s a “mount point”), or it might be by-component (normally), or even site-root relative (if it’s the root of a skin layer).
For the by-component vs. site-root relative checks, I suppose these objects can distinguish themselves by seeing whether they have a non-empty component name. If it’s empty, then they must be a site root (or something’s broken). Hm. Perhaps we should have an interface, IPlace
, that’s something like:
class IPlace(Interface):
place_url = Attribute("""My URL relative to the site root""")
The idea is that place_url
can be either a relative URL or an absolute URL, provided we use something like urlparse.urljoin()
to join it with the application’s base URL. Then, we can kill three formats with one stone:
- By defining place_url as an attribute binding, it can be overridden by a constructor keyword, allowing an absolute URL to be set.
- The binding can check whether self.getComponentName() is None, and if so, assume that the current component is the site root.
- Otherwise, it can adapt its parent component to
IPlace
, and then compute its own URL relative to that. (If its parent isn’t anIPlace
, then something’s wrong.)
This actually looks almost identical to the current web.IResource interface, but with a different name, different attribute name, and some slight tweaks to the URL computation.
Not bad. I guess I’ll make it so!