Copied to clipboard

Flag this post as spam?

This post will be reported to the moderators as potential spam to be looked at


  • Niels Kristiansen 166 posts 382 karma points
    Nov 29, 2013 @ 12:23
    Niels Kristiansen
    0

    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:

    • 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 :)
    Hope someone can help me out :)
    /Niels

  • Hundebol 167 posts 314 karma points
    Nov 29, 2013 @ 13:25
    Hundebol
    0

    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

  • Chriztian Steinmeier 2800 posts 8790 karma points MVP 8x admin c-trib
    Nov 29, 2013 @ 14:03
    Chriztian Steinmeier
    0

    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:

    <?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>
    

    /Chriztian

  • Niels Kristiansen 166 posts 382 karma points
    Nov 29, 2013 @ 23:48
    Niels Kristiansen
    0

    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

Please Sign in or register to post replies

Write your reply to:

Draft