Tuesday, April 07, 2009
Filed under:
xslt,
xsltsearch
- by Douglas Robar
Most of the modifications people want to make to XSLTsearch
have to do with limiting or filtering the nodes being searched.
As an example, suppose you have a blog and want to exclude blog
comments from the search results. This is easily done with a
one-line addition to the xsltsearch.xslt macro file.
Search for umbracoNaviHide and you'll find the
possibleNodes variable in the search template. This is
where most of the modifications you might ever want to make would
be made.
The search template looks like this (XSLTsearch 2.8):
<xsl:template name="search">
<!-- Perform the search on the appropriate nodeset and display the output -->
<xsl:param name="items"/>
<!-- reduce the number of nodes -->
<xsl:variable name="possibleNodes" select="$items/descendant-or-self::node[
string(data [@alias='umbracoNaviHide']) != '1'
and count(attribute::id)=1
and (umbraco.library:IsProtected(@id, @path) = false()
or umbraco.library:HasAccess(@id, @path) = true())
]"/>
...
As you can see, the search template that gets all the possible
nodes that will be searched. In our example, we want to remove from
the search any BlogPostComment nodes. We'll do
that by checking the @nodeTypeAlias.
The modified xsltsearch.xslt file that excludes blog post
comments would look like:
<!-- reduce the number of nodes -->
<xsl:variable name="possibleNodes" select="$items/descendant-or-self::node[
string(data [@alias='umbracoNaviHide']) != '1'
and @nodeTypeAlias != 'BlogPostComment'
and count(attribute::id)=1
and (umbraco.library:IsProtected(@id, @path) = false()
or umbraco.library:HasAccess(@id, @path) = true())
]"/>
...
This same technique could be used to search within certain
document types (rather than to exclude certain document types as we
did above). To search only within umbraco content nodes of homepage
and webpage document types we would modify the possibleNodes
variable like this:
<!-- reduce the number of nodes -->
<xsl:variable name="possibleNodes" select="$items/descendant-or-self::node[
string(data [@alias='umbracoNaviHide']) != '1'
and (
@nodeTypeAlias = 'homepage'
or @nodeTypeAlias = 'webpage'
)
and count(attribute::id)=1
and (umbraco.library:IsProtected(@id, @path) = false()
or umbraco.library:HasAccess(@id, @path) = true())
]"/>
...
Or perhaps you have created your own document type property
called 'searchHide' rather than assuming that any page that
does not appear in the navigation should not appear in the search
results either. If so, you would simply change the umbracoNaviHide
alias to that of your property:
<!-- reduce the number of nodes -->
<xsl:variable name="possibleNodes" select="$items/descendant-or-self::node[
string(data [@alias='searchHide']) != '1'
and count(attribute::id)=1
and (umbraco.library:IsProtected(@id, @path) = false()
or umbraco.library:HasAccess(@id, @path) = true())
]"/>
...
Though these examples are simple, more advanced modifications
can be handled in the same way.
For instance, it would be a small matter to create a custom
search form that included checkboxes for the areas or docTypes of
your site to search (such as FAQs, News, Support, Products, etc.).
You could simply add a macro parameter and pass in the
nodeTypeAlias(es) according to the user's selection rather than
hard-coding them as we've done here.
Many websites will not need to modify XSLTsearch
because of the many built-in options it provides; but it is nice to
know that it is so easy to customize XSLTsearch
to meet your site's unique needs if you need to.