Hi, 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 'mod_negotiation'.
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" src="org.apache.cocoon.selection.AcceptSelector"> <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"/> </map:selector> --------------------------------------------------------------------- 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> <map:when test="html"> <map:generate src="foo.html"/> <map:serialize type="html"/> </map:when> <map:otherwise> <map:generate src="foo-baz.html"/> <map:serialize type="html"/> </map:otherwise> </map:select> </map:match> --------------------------------------------------------------------- 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.) regards, Jonas --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, email: [EMAIL PROTECTED]