Selectors
Selectors are the conditional constructions for sitemaps. The most commonly used one is the BrowserSelector which allows different routes in the pipeline dependant on the client's browser. Useful for
differences in browser behaviour. The Paloose site makes use of this so that the text based Lynx and the iPhone browser are supported.
- BrowserSelector — selects pipeline fragment according to
user's browser.
- MobileSelector — selects pipeline fragment according to
user's browser when mobile.
- RequestParameterSelector — selects pipeline
fragment according to query string request parameter.
- RegexpSelector — selects pipeline fragment according to a
regular expression in a variable.
- VariableSelector — selects a pipeline on basis of *
request parameter from the query string.
- ResourceExistsSelector — selects a pipeline on condition of whether a resource (file) exists.
Component Declaration
Selectors are defined in the component declaration part of the Sitemap.
<map:selectors default="browser">
<map:selector name="browser" src="resource://lib/selection/BrowserSelector">
<map:browser name="explorer" useragent="MSIE"/>
...
</map:selector>
</map:selectors>
The default attribute specifies the type of selector to use if none is specified in a pipeline.
The root sitemap needs to have the BrowserSelector declared as a component:
<map:components>
...
<map:selectors default="browser">
<map:selector name="browser" src="resource://lib/selection/BrowserSelector">
<map:browser name="explorer" useragent="MSIE"/>
<map:browser name="pocketexplorer" useragent="MSPIE"/>
<map:browser name="handweb" useragent="HandHTTP"/>
<map:browser name="avantgo" useragent="AvantGo"/>
<map:browser name="imode" useragent="DoCoMo"/>
<map:browser name="opera" useragent="Opera"/>
<map:browser name="lynx" useragent="Lynx"/>
<map:browser name="java" useragent="Java"/>
<map:browser name="wap" useragent="Nokia"/>
<map:browser name="wap" useragent="UP"/>
<map:browser name="wap" useragent="Wapalizer"/>
<map:browser name="mozilla5" useragent="Mozilla/5"/>
<map:browser name="mozilla5" useragent="Netscape6/"/>
<map:browser name="netscape" useragent="Mozilla"/>
<map:browser name="safari" useragent="Safari"/>
<map:browser name="iphone" useragent="iPhone"/>
</map:selector>
</map:selectors>
...
</map:components>
where
- name — the name of this selector (in this case browser).
- src — the location of the PHP package for this component.
Each sub-element, <map:browser>, defines a particular browser by its user agent type,
where
- name — the name of the selection when used in the pipeline.
- useragent — the client browser defined by its agent.
We can use the selector in the pipeline in any position provided that the overall conditions for the pipeline are met: that is, a
pipeline must start with a generator and end with a serializer, or have a mount or reader pipeline element. For example (from this
site):
<map:match pattern="**.html">
<map:aggregate element="root" label="aggr-content">
<map:part src="cocoon:/headings.xml" element="headings" strip-root="true"/>
<map:part src="cocoon:/menus.xml" element="menus" strip-root="true"/>
<map:part src="cocoon:/newsArticles.xml" element="news-articles" strip-root="true"/>
<map:part src="cocoon:/{1}.xml" element="content" strip-root="true"/>
</map:aggregate>
<map:select type="browser">
<map:when test="lynx">
<map:transform src="context://resources/transforms/page2lynx.xsl" label="page-transform">
<map:parameter name="page" value="{1}"/>
</map:transform>
</map:when>
<map:otherwise>
<map:transform src="context://resources/transforms/page2html.xsl" label="page-transform">
<map:parameter name="page" value="{1}"/>
</map:transform>
</map:otherwise>
</map:select>
<map:transform src="context://resources/transforms/stripNamespaces.xsl"/>
<map:serialize type="html" />
</map:match>
The root sitemap needs to have the MobileSelector declared as a component:
<map:components>
...
<map:selectors default="mobile">
<map:selector name="mobile" src="resource://lib/selection/MobileSelector"/>
</map:selectors>
...
</map:components>
We can use the selector in the pipeline in any position provided that the overall conditions for the pipeline are met: that is, a
pipeline must start with a generator and end with a serializer, or have a mount or reader pipeline element. For example (from this
site):
<map:match pattern="**.html">
<map:aggregate element="root" label="aggr-content">
<map:part src="cocoon:/headings.xml" element="headings" strip-root="true"/>
<map:part src="cocoon:/menus.xml" element="menus" strip-root="true"/>
<map:part src="cocoon:/newsArticles.xml" element="news-articles" strip-root="true"/>
<map:part src="cocoon:/{1}.xml" element="content" strip-root="true"/>
</map:aggregate>
<map:select type="mobile">
<map:when test="mobile">
<map:transform src="context://resources/transforms/page2mobile.xsl" label="page-transform">
<map:parameter name="page" value="{1}"/>
</map:transform>
</map:when>
<map:otherwise>
<map:transform src="context://resources/transforms/page2html.xsl" label="page-transform">
<map:parameter name="page" value="{1}"/>
</map:transform>
</map:otherwise>
</map:select>
<map:transform src="context://resources/transforms/stripNamespaces.xsl"/>
<map:serialize type="html" />
</map:match>
The sitemap needs to have the RequestParameterSelector declared as a component:
<map:selectors default="browser">
...
<map:selector name="request-parameter" src="resource://lib/selection/RequestParameterSelector">
<map:parameter-name>type</map:parameter-name>
</map:selector>
</map:selectors>
where
- name — the name of this selector (in this case request-parameter).
- src — the location of the PHP package for this component.
The <map:paraneter-name> tag defines a default test parameter in the query string if one is not
defined in the pipeline (in this case 'type').
We can use the selector in the pipeline in any position provided that the overall conditions for the pipeline are met: that is, a
pipeline must start with a generator and end with a serializer, or have a mount, call or reader pipeline element. For
example:
<map:match pattern="*.html">
<map:aggregate element="root" label="aggr-content">
<map:part src="cocoon:/menus.xml" element="menus" strip-root="true"/>
<map:part src="cocoon:/newsArticles.xml" element="newsArticles" strip-root="true"/>
<map:part src="cocoon:/futureConcerts.xml" element="futureConcerts" strip-root="true"/>
<map:part src="cocoon:/{1}.xml" element="content" strip-root="true"/>
</map:aggregate>
<map:select type="request-parameter">
<map:parameter name="parameter-name" value="type"/>
<map:when test="xml">
<map:transform src="context://resources/transforms/extractXML.xsl" label="page-transform">
<map:parameter name="page" value="{1}"/>
</map:transform>
<map:call resource="outputXML"/>
</map:when>
<map:when test="text">
<map:transform src="context://resources/transforms/extractXML.xsl" label="page-transform">
<map:parameter name="page" value="{1}"/>
</map:transform>
<map:transform src="context://resources/transforms/xml2text.xsl" label="text-transform">
<map:parameter name="page" value="{1}"/>
</map:transform>
<map:call resource="outputPage"/>
</map:when>
<map:otherwise>
<map:transform src="context://resources/transforms/page2html.xsl" label="page-transform">
<map:parameter name="page" value="{1}"/>
</map:transform>
<map:call resource="outputPage"/>
</map:otherwise>
</map:select>
</map:match>
The sitemap needs to have the RegexpSelector declared as a component:
<map:selectors default="browser">
<map:selector name="regexp-selector" src="resource://lib/selection/RegexpSelector"/>
</map:selectors>
where
- name — the name of this selector (in this case regexp-selector).
- src — the location of the PHP package for this component.
We can use the selector in the pipeline in any position provided that the overall conditions for the pipeline are met: that is, a
pipeline must start with a generator and end with a serializer, or have a mount, call or reader pipeline element. For example (from
an experimental Paloose CMS system):
<map:component-configurations>
<map:global-variables>
<map:variable name="themesDir" value="context://themes"/>
<map:variable name="defaultTheme" value="{ant:default-theme}"/>
<map:variable name="currentTheme" value="{cookies:theme}"/>
<map:variable name="rootDir" value="context://"/>
</map:global-variables>
</map:component-configurations>
<map:pipeline>
<map:match pattern="/(page).html/" type="regexp">
<map:act type="cookies">
<map:select type="regexp-selector">
<map:parameter name="test-value" value="{global:currentTheme}"/>
<map:when test="/.+/">
<map:generate src="context://themes/{global:currentTheme}/data/body.xml" label="raw-xml"/>
</map:when>
<map:otherwise>
<map:generate src="context://themes/astral/data/body.xml" label="raw-xml"/>
</map:otherwise>
</map:select>
...
<map:transform type="moduleWrite"/>
</map:act>
</map:match>
In the example the selector checks for a current theme (/.+/ is any character). If the string is empty then the otherwise clause
is carried out. If there is a theme declared then the appropriate theme directory is used.
The sitemap needs to have the VariableSelector declared as a component:
<map:selectors default="browser">
<map:selector name="variable-selector" src="resource://lib/selection/VariableSelector"/>
</map:selectors>
where
- name — the name of this selector (in this case variable-selector).
- src — the location of the PHP package for this component.
We can use the selector in the pipeline in any position provided that the overall conditions for the pipeline are met: that is, a
pipeline must start with a generator and end with a serializer, or have a mount, call or reader pipeline element. For example (from
an experimental Paloose CMS system):
<map:component-configurations>
<map:global-variables>
<map:variable name="themesDir" value="context://themes"/>
<map:variable name="defaultTheme" value="{ant:default-theme}"/>
<map:variable name="currentTheme" value="{cookies:theme}"/>
<map:variable name="rootDir" value="context://"/>
</map:global-variables>
</map:component-configurations>
<map:pipeline>
<map:match pattern="/(page).html/" type="regexp">
<map:act type="cookies">
<map:select type="variable-selector">
<map:parameter name="parameter-name" value="{cookies:theme}"/>
<map:when test="">
<map:generate src="context://themes/astral/data/body.xml" label="raw-xml"/>
</map:when>
<map:otherwise>
<map:generate src="context://themes/{cookies:theme}/data/body.xml" label="raw-xml"/>
</map:otherwise>
</map:select>
...
<map:transform type="moduleWrite"/>
</map:act>
</map:match>
This is almost the same as the previous example.
The sitemap needs to have the ResourceExistsSelector declared as a component:
<map:selectors default="resource-exists">
<map:selector name="resource-exists" src="resource://lib/selection/ResourceExistsSelector"/>
</map:selectors>
where
- name — the name of this selector (in this case resource-exists).
- src — the location of the PHP package for this component.
The following example shows how it can be used to select between two transforms. It is taken from an experimental
CMS system based on Paloose and shows several other selectors as well:
<map:match pattern="page.html">
<map:act type="cookies">
<map:select type="regexp-selector">
<map:parameter name="test-value" value="{global:currentTheme}"/>
<map:when test="/.+/">
<map:generate src="context://themes/{global:currentTheme}/data/body.xml" label="raw-xml"/>
</map:when>
<map:otherwise>
<map:generate src="context://themes/{global:defaultTheme}/data/body.xml" label="raw-xml"/>
</map:otherwise>
</map:select>
<map:transform src="context://system/resources/transforms/buildBody.xsl" label="buildBody-transform">
<map:parameter name="requestId" value="{request-param:reqid}"/>
<map:parameter name="siteIdent" value="{global:siteIdent}"/>
<map:parameter name="themesDir" value="{global:themesDir}"/>
<map:parameter name="theme" value="{global:currentTheme}"/>
<map:parameter name="defaultTheme" value="{global:defaultTheme}"/>
<map:parameter name="rootDir" value="{global:rootDir}"/>
<map:parameter name="queryString" value="{global:query-string}"/>
</map:transform>
<map:transform src="context://system/resources/transforms/buildPanels.xsl"
label="buildPanels-transform"/>
<map:transform src="context://sites/{global:siteIdent}/resources/transforms/buildSite.xsl"
label="buildSite-transform"/>
<map:select type="regexp-selector">
<map:parameter name="test-value" value="{request-param:reqid}"/>
<map:when test="/nb.+/">
<map:transform
src="context://sites/{global:siteIdent}/resources/transforms/widgets/buildSiteWidget-notebook.xsl"
label="buildNotebook-transform"/>
<map:select type="resource-exists">
<map:when test="context://themes/{global:currentTheme}/resources/transforms/buildTheme.xsl">
<map:transform
src="context://themes/{global:currentTheme}/resources/transforms/buildTheme.xsl"
label="buildTheme-transform"/>
</map:when>
<map:otherwise/>
</map:select>
</map:when>
<map:otherwise/>
</map:select>
<map:select type="resource-exists">
<map:when test="context://themes/{global:currentTheme}/resources/transforms/buildTheme.xsl">
<map:transform src="context://themes/{global:currentTheme}/resources/transforms/buildTheme.xsl"
label="buildTheme-transform"/>
</map:when>
<map:otherwise>
<map:transform src="context://themes/{global:parentTheme}/resources/transforms/buildTheme.xsl"
label="buildTheme-transform"/>
</map:otherwise>
</map:select>
<map:transform
src="context://system/resources/transforms/normaliseProperties.xsl"
label="normalise-transform"/>
<map:transform src="context://system/resources/transforms/page2xhtml.xsl" label="page-transform"/>
<map:transform src="context://system/resources/transforms/stripNamespaces.xsl"/>
<map:serialize type="xhtml"/>
</map:act>
</map:match>
Copyright 2006 – 2023 Hugh Field-Richards. All Rights Reserved.