I have a website that show some services filtered/layered navigation based on it's tags and document type properties, but I have no idea how to "attack" this matter or start in XSLT. It will almost be as a standard e-commerce layered filter navigation, but it is not a webshop, so it will be overkill to implement one of those, only to "harvest" the filtered navigaiton.
Here is an example:
A service has the following:
Language (choose the language in a dropdown)
Time (How long will the service take) - used with ex. a slider
Type of service, used with ex. the tag manager in Umbraco, where you in the layered navigation can pick the tag with a checkbox
All of this should filter the content with AJAX so the user can see the result instantly. On that part I have an idea how to do :)
I usually do this by creating a page that takes the filters as QueryString parameters and then slowly "react" to each filter while building the page.
The AJAX thing would be the last thing (and probably handled with an alternate template) I'd do - sounds like you're thinking like that too.
The tricky stuff is all the filtering in XSLT which is hard to get right — and you could easily argue that it's not really the right place for it - e.g. in an MVC application (whether it'd be Rails .NET) you would have handled that before you got to the View, so...
Some filters would be better to have someone write an XSLT extension for...
That said, I've done this a couple of times - so here's a single filter version to filter nodes by their name's starting letter, to get you started:
<?xml version="1.0" encoding="utf-8" ?>
<xsl:stylesheet
version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:umbraco.library="urn:umbraco.library"
exclude-result-prefixes="umbraco.library"
>
<xsl:output method="xml" indent="yes" omit-xml-declaration="yes" />
<xsl:param name="currentPage" />
<!-- Index all nodes by their 1st letter -->
<xsl:key name="nodesByFirstLetter" match="*[@isDoc][not(umbracoNaviHide = 1)]" use="substring(@nodeName, 1, 1)" />
<!-- Collect all possible nodes -->
<xsl:variable name="nodes" select="$currentPage/*[@isDoc][not(umbracoNaviHide = 1)]" />
<!-- Get the picked starting letter -->
<xsl:variable name="letter" select="umbraco.library:RequestQueryString('letter')" />
<!-- Boolean flag to know if a letter was selected -->
<xsl:variable name="noLetterPicked" select="not(normalize-space($letter))" />
<xsl:template match="/">
<!-- Render the filters -->
<xsl:call-template name="outputFilters" />
<!-- Render the filtered nodes (the for-each is just to get the right context document for the key() function)-->
<xsl:for-each select="$currentPage">
<xsl:variable name="filteredNodes" select="key('nodesByFirstLetter', $letter)" />
<!-- Render all nodes starting with the selected letter OR, if no letter was picked, all of them -->
<xsl:apply-templates select="$filteredNodes | $nodes[$noLetterPicked]" />
</xsl:for-each>
</xsl:template>
<!-- Generic output template for a node -->
<xsl:template match="*[@isDoc]">
<p>
Hey, I'm the <xsl:value-of select="@nodeName" /> node.
</p>
</xsl:template>
<!-- Template to render the filter(s) -->
<xsl:template name="outputFilters">
<section class="filters">
<xsl:for-each select="umbraco.library:Split('ABCDEFGHIJKLMNOPQRSTUVWXYZÆØÅ', '')//value">
<a href="?letter={.}">
<xsl:if test=". = $letter">
<xsl:attribute name="class">selected</xsl:attribute>
</xsl:if>
<xsl:value-of select="." />
</a>
</xsl:for-each>
</section>
</xsl:template>
</xsl:stylesheet>
Hundebøl: It's more "advanced" than the isotope or mosaic and more in Chriztians direction, but thanks very much for the feedback.
Chriztian: Looking really good, and absolutly a thing I will keep in my favorite on other projects :).
I have talked with another guy from our.umbraco.org, that was giving me a good idea about how to build the thing up. He said that I should try to make an Attribute set -> Attributes in the content area, where the Content user can place the settings on any service.
So I ex. have a attributes for the Languages (Danish, English, German), make a dynamic dropdown as a Datatype, combine with Document Type and hereafter using XSLT to filter on the services where the checkboxes is activated (ex. only showing services with Danish & English), or maybe use angularjs or jQuery up aginst JSON/XML instead? On that part I can diffently use elements from the code you send Chriztian.
A good idea to make "Layered navigation" i XSLT?
Hi,
I have a website that show some services filtered/layered navigation based on it's tags and document type properties, but I have no idea how to "attack" this matter or start in XSLT. It will almost be as a standard e-commerce layered filter navigation, but it is not a webshop, so it will be overkill to implement one of those, only to "harvest" the filtered navigaiton.
Here is an example:
A service has the following:
Hi Niels,
Not entirely sure I know what problem you are facing, but as I understand it, you would like to filter your services by tags?
This is easily done with for instance Isotope http://isotope.metafizzy.co/demos/filtering.html
This filtes the objects based on class-names on the html-object. You can output your tags to be used as class-names.
Let me know if this is what you need - then I might have some code snippets lying around you can use
best regards
Hundebøl
Hi Niels,
I usually do this by creating a page that takes the filters as QueryString parameters and then slowly "react" to each filter while building the page.
The AJAX thing would be the last thing (and probably handled with an alternate template) I'd do - sounds like you're thinking like that too.
The tricky stuff is all the filtering in XSLT which is hard to get right — and you could easily argue that it's not really the right place for it - e.g. in an MVC application (whether it'd be Rails .NET) you would have handled that before you got to the View, so...
Some filters would be better to have someone write an XSLT extension for...
That said, I've done this a couple of times - so here's a single filter version to filter nodes by their name's starting letter, to get you started:
/Chriztian
Hi Hundebøl and Chriztian,
Thanks for answers :)
Hundebøl: It's more "advanced" than the isotope or mosaic and more in Chriztians direction, but thanks very much for the feedback.
Chriztian: Looking really good, and absolutly a thing I will keep in my favorite on other projects :).
I have talked with another guy from our.umbraco.org, that was giving me a good idea about how to build the thing up. He said that I should try to make an Attribute set -> Attributes in the content area, where the Content user can place the settings on any service.
So I ex. have a attributes for the Languages (Danish, English, German), make a dynamic dropdown as a Datatype, combine with Document Type and hereafter using XSLT to filter on the services where the checkboxes is activated (ex. only showing services with Danish & English), or maybe use angularjs or jQuery up aginst JSON/XML instead? On that part I can diffently use elements from the code you send Chriztian.
Does it sounds like it's possible?
/Niels
is working on a reply...