Page types/classes
from
Ian Bicking
on 2008-05-05 13:42
OK, so I feel okay about a redesign of selectors and rules. So the
other thing is selecting themes and whatnot.
I still like the idea of using names and indirection, ala CSS classes.
I'm thinking of calling them page-class, like "page type" that Wichert
suggested, but using "class" to suggest that a page isn't exclusively
one thing.
The obvious and explicit way to set the class is with
X-Deliverance-Page-Class, either an HTTP header or <meta http-equiv>.
Setting these isn't always easy. You have to poke around in templates
to do it, and for something like styling Trac it would be nice to do it
completely externally to Trac itself. So back to path matching. This
seems fairly obvious:
<match path="/foo" class="foo" />
There will be the <match> tag, and these selectors as attributes:
path: a path. If it allows wildcards, I am a little concerned about
people mistakenly putting an exact path and assuming it is a prefix. So
I'm thinking this won't take wildcards. A trailing / won't matter --
/foo/ and /foo will be treated equivalently, and neither would match
/foobar.
Perhaps prefixes could allow different kinds of matches. E.g.:
"wildcard:*/manage*" or "regex:/wp-admin/(post|new-post)\.php".
I'd like a way to indicate whether just PATH_INFO or the full path
is being matched. People are naturally inclined to view it as a
full-path match. Perhaps a leading / would indicate this, and no
leading / means match SCRIPT_NAME. Except that wouldn't work for
wildcard and regex matches. For most installations PATH_INFO will be
the full path, so it's a little academic. But that's not true for
openplans, so I have to think about this.
domain: a domain, with possible wildcard.
request-header: this would be "Header: match", like
"X-Requested-With: regex:(?i)xmlhttprequest". The header name will be
parsed out. Maybe allow wildcards? The part after : will be matched
like path, except maybe a case-insensitive whitespace-normalized match
as the default. So "X-Requested-With: xmlhttprequest" would match a
value of "XMLHttpRequest", but wouldn't match "XMLHttpRequest/foo"
response-header: just like request header, but the response.
last: if this is "1", then if this <match> matches, no other matches
will be checked. (Not sure if this is the best name... it's like [L] in
a rewrite rule)
If you provide multiple attributes then they all must match. I'm not
sure how to allow multiple attributes of the same type, like if you want
to match multiple request headers.
Then there's the question: are classes entirely cumulative, like CSS
classes? Or is there a way to suppress a class? Like class="-standard
my-page-type", to remove the standard page type (there might be an
implicit <match class="standard" /> rule). Or maybe last="1" would stop
any other classes, and so you've implicitly excluded all other classes
from being added if you use it.
OK, so then the actual rules. We introduce a single attribute:
<rules class="class_name(s)">
<append ... />
</rules>
Except... we've already used <rules>. We could use <class
name="class_name">, but I would kind of prefer that the attribute name
be "class" in both the match and rules.
Maybe better than things like -standard, would be a way of including
other classes in a rule. Like:
<rules class="my-page">
<match class="standard" />
</rules>
then this would also have any standard rules. This kind of overloads
<match>, though I think in a way that's reasonably intuitive -- it feels
the same, even though the implementation would be quite different.
Though I'm not inclined to allow any other conditionals like <match
path="..." /> in this context.
Also, <theme href="..." /> would be allowed in this context, and the
first matched class (I'd maintain classes in an order) would have its
theme used.
So... modulo a few places I noted indecision, this sounds like a simple
way of providing what people need in conditional theming. Opinions?
Ian