cocoon-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Jonas Petersen <>
Subject AcceptSelector
Date Wed, 12 Jun 2002 17:20:42 GMT

I am working on a selector that analyses the  Accept header of the
browser and provides a way to (for example) response with the best
fitting content(-type). It's comparable with the apache module

The main class is named 'AcceptSelector'. It is based on the abstract
class 'WeightedTypesSelector'.

The (sitemap) configuration of the AcceptSelector is made up of a list
of possible variants to check against. Each variant has a name, a
mime-type and a weight.

Example of a Accept header sent by the browser:
Accept: text/xml, application/xml, application/xhtml+xml,
text/html;q=0.9, image
/png, image/jpeg, image/gif;q=0.2, text/plain;q=0.8, text/css, */*;q=0.1

Example of a sitemap configuration:
   <map:selector logger="sitemap.selector.accept" name="accept"
     <variant name="wml" mime-type="application/vnd.wap.wmlc" qs="0.9"/>
     <variant name="html" mime-type="text/html" qs="0.8"/>
     <variant name="wildcard" mime-type="*/*" qs="1.0"/>

The selector multiplies the weights of the mime-types in the Accept
header (q=...) with the weights of the variants in the sitemap (qs=...)
(if no weight is given a value of 1.0 is used). The variant with the
highest value gets selected. If multiple variants have the same result,
the variant that appears first gets selected.

In the above example the variant 'html' would make it, because the
mime-type 'text/html' is found in the header and the config and yields a
weight of 0.72 (0.9 * 0.8). 'wml' matches with '*/*' (0.1 * 0.9 = 0.09).
Using the mime-type '*/*' as a variant helps in providing default
variants (it behaves differently than <map:otherwise/>).

Example of a <map:select/> using the AcceptSelector:
    <map:match pattern="foo">
      <map:select type="accept">
        <map:when test="wml">
          <map:generate src="foo.wml"/>
          <map:serialize type="wml"/>
        <map:when test="html">
          <map:generate src="foo.html"/>
          <map:serialize type="html"/>
          <map:generate src="foo-baz.html"/>
          <map:serialize type="html"/>

Now a problem that I encountered:

For each <map:when/> the select() function gets called. There I do the
weight calculations with the current Accept header against the
configuration. This produces some overhead because this really needs to
happen only once (in the beginning of the <map:select/>.

I'm thinking about caching the results for each different Accept header.

Maybe it would be good to do these calculations at the beginning of the
<map:select/> block. But it seems there is no temporary context/instance
within the block or a way to initialize a <map:select/>. Or is there? To
me this seems to be a general problem with the selectors, because if
there is lots of <map:when/>s then there might be lots of unnecessarily
repeated code.

The best would probably be to combine the caching and the precalculation
at the beginning of the block.

So what do you think about it? Is it useful? Would it make sense to
include it into cocoon?

How should I provide the source code so you can check it out? (I'm new
to cocoon-dev.)


To unsubscribe, e-mail:
For additional commands, email:

View raw message