Copied to clipboard

Flag this post as spam?

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


  • FarmFreshCode 225 posts 422 karma points
    Jun 11, 2013 @ 21:27
    FarmFreshCode
    0

    Build an XML variable with filters based on TAGS

    I have the following XSLT script which works great... however I need to access TAGS and not just a standard property value.

    <!-- Build an XML variable with all the filters available -->
    <xsl:variable name="filterProxy">
           
    <filter id="6624" property="facultyBuilding" value="HPA I" />
           
    <filter id="3385" property="facultyDepartment" value="Social Work" />
           
    <!-- HOW DO I CALL VALUES FROM TAGS???? -->
    </xsl:variable>

    <!-- Grab the filter that applies to the current page -->
    <xsl:variable name="facultyFilter" select="msxml:node-set($filterProxy)/filter[@id = $currentPage/@id]" />

    <!-- Grab the root node to do lookups under -->
    <xsl:variable name="rootNode" select="umbraco.library:GetXmlNodeById(6394)" />

    <!-- Filter the FacultyProfile nodes using the filter (or return all of them if no filter matched) -->
    <xsl:for-each select="$rootNode/FacultyProfile[*[name() = $facultyFilter/@property] = $facultyFilter/@value] | $rootNode/FacultyProfile[not($facultyFilter)]">
           
    <p>
                   
    <xsl:value-of select="@nodeName" />
                   
    <!-- ETC. -->
           
    </p>
    </xsl:for-each>

    I was hoping that it would be simple and follow the same format:

    <filter id="3385" property="facultyAffiliations" value="Tech Committee" />

    Where "facultyAffiliations" is the alias of the TAG dataType and "Tech Committe" would be one of the TAGS selected. But it doesn't quite work out that easy.

    Any suggestions how I can make this work?

    Thanks in advance

  • Chriztian Steinmeier 2798 posts 8787 karma points MVP 7x admin c-trib
    Jun 15, 2013 @ 22:13
    Chriztian Steinmeier
    0

    Hi FarmFreshCode,

    I guess you're using the built-in "Tags" DataType, which saves the tags as a comma-separated string (e.g.: "Code,XSLT,JavaScript") - and this means a little more work... but I think we'll need just a little more info on how you're expecting this to work – i.e., can you describe the scenario you're trying to match?

    Will you only ever be matching against a single tag at a time or could there maybe be several?

    /Chriztian

  • Niels Kristiansen 166 posts 382 karma points
    Jun 15, 2013 @ 22:24
    Niels Kristiansen
    2

    Hi FarmFreshCode,

    I just build a version, not so many days ago for built-in tags and masonry, with filters in Umbraco 6.1 and Bootstrap 2.3.x:

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE xsl:stylesheet [ <!ENTITY nbsp "&#x00A0;"> ]>
    <xsl:stylesheet 
        version="1.0" 
        xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
        xmlns:msxml="urn:schemas-microsoft-com:xslt" 
        xmlns:umbraco.library="urn:umbraco.library" xmlns:Exslt.ExsltCommon="urn:Exslt.ExsltCommon" xmlns:Exslt.ExsltDatesAndTimes="urn:Exslt.ExsltDatesAndTimes" xmlns:Exslt.ExsltMath="urn:Exslt.ExsltMath" xmlns:Exslt.ExsltRegularExpressions="urn:Exslt.ExsltRegularExpressions" xmlns:Exslt.ExsltStrings="urn:Exslt.ExsltStrings" xmlns:Exslt.ExsltSets="urn:Exslt.ExsltSets" xmlns:ucomponents.cms="urn:ucomponents.cms" xmlns:ucomponents.dates="urn:ucomponents.dates" xmlns:ucomponents.email="urn:ucomponents.email" xmlns:ucomponents.io="urn:ucomponents.io" xmlns:ucomponents.media="urn:ucomponents.media" xmlns:ucomponents.members="urn:ucomponents.members" xmlns:ucomponents.nodes="urn:ucomponents.nodes" xmlns:ucomponents.random="urn:ucomponents.random" xmlns:ucomponents.request="urn:ucomponents.request" xmlns:ucomponents.search="urn:ucomponents.search" xmlns:ucomponents.strings="urn:ucomponents.strings" xmlns:ucomponents.urls="urn:ucomponents.urls" xmlns:ucomponents.xml="urn:ucomponents.xml" xmlns:TagsLib="urn:TagsLib" 
        exclude-result-prefixes="msxml umbraco.library Exslt.ExsltCommon Exslt.ExsltDatesAndTimes Exslt.ExsltMath Exslt.ExsltRegularExpressions Exslt.ExsltStrings Exslt.ExsltSets ucomponents.cms ucomponents.dates ucomponents.email ucomponents.io ucomponents.media ucomponents.members ucomponents.nodes ucomponents.random ucomponents.request ucomponents.search ucomponents.strings ucomponents.urls ucomponents.xml TagsLib ">
    
    
    <xsl:output method="xml" omit-xml-declaration="yes"/>
    
    <xsl:param name="currentPage"/>
    
    <xsl:template match="/">
    
    <!-- Portfolio filters -->
        <xsl:variable name="NewsGroupTags" select="TagsLib:getAllTagsInGroup('arbejdsomraade')/tags"/>
        <xsl:if test="count($NewsGroupTags) > 0">   
            <ul id="portfolio_filters">  
                <li><a href="#" data-filter="*">Show all</a></li>
                <xsl:for-each select="$NewsGroupTags/tag">
                <xsl:variable name="tagsSmall" select="Exslt.ExsltStrings:lowercase(current())" />
                    <li>
                        <a href="#" data-filter=".cat_{$tagsSmall}"><xsl:value-of select="current()"/></a>
                    </li>
                </xsl:for-each>
            </ul>    
        </xsl:if>
    
    <div id="portfolio_container" class="portfolio_strict row">   
    <xsl:for-each select="$currentPage/* [@isDoc and string(umbracoNaviHide) != '1']">
    
        <!-- <textarea><xsl:copy-of select="." /></textarea> -->
        <div>
            <xsl:if test="string-length(tagsArticle) > 0">  
                <xsl:variable name="items" select="umbraco.library:Split(tagsArticle,',')" />   
                <xsl:attribute name="class">
                    <xsl:for-each select="$items//value">
                        <xsl:text>cat_</xsl:text><xsl:value-of select="Exslt.ExsltStrings:lowercase(current())"/><xsl:text> </xsl:text>
                    </xsl:for-each><xsl:text>portfolio_item span4</xsl:text>
                </xsl:attribute>    
            </xsl:if>
            <div class="portfolio_photo">
                <xsl:if test="./articleImages != ''">
    
                    <xsl:attribute name="style"><xsl:text>background-image:url(</xsl:text><xsl:value-of select="umbraco.library:GetMedia(./articleImages/MultiNodePicker/nodeId, 0)/umbracoFile" /><xsl:text>)</xsl:text></xsl:attribute>
    
                </xsl:if>
                <a href="{umbraco.library:NiceUrl(@id)}">
                    <i class="icon-2x icon-external-link"><xsl:text> </xsl:text></i>
                    <p><xsl:value-of select="@nodeName"/></p>
                </a>
            </div>
            <div class="portfolio_description">
                <h3><a href="{umbraco.library:NiceUrl(@id)}"><xsl:value-of select="@nodeName"/></a></h3>
                <p><xsl:value-of select="tagsArticle"/></p>
            </div>
        </div>
    
    </xsl:for-each>
    </div>
    </xsl:template>
    
    </xsl:stylesheet>

    Hope this can help you out for the matter of filters as well :)

    Remember to register the following to your /config/xsltExtensions.config:

    <ext assembly="umbraco.editorControls" type="umbraco.editorControls.tags.library" alias="TagsLib" />

    Kind regards,

    Niels

  • FarmFreshCode 225 posts 422 karma points
    Jun 16, 2013 @ 17:21
    FarmFreshCode
    0

    Hello Chriztian,

    Yes, I am using the built in Tags DataType.

    As for the senerio, I use the Tags DataType for a section called "Affiliations". Which allows the faculty members to quickly list any Committees or Oraganizations that they might be connected to. So for example, I might be on the Diversity Committee, Technology Committee and in the Social Media Managers Group. So I would add those tags to my profile. Now as the web developer I might want to create a page for the Technology Committee and pull out and list all the faculty members that are on that Committee. Which is where I had hoped....

    <filterid="3385"property="facultyAffiliations"value="Tech Committee"/>

    would have worked.. however tags are a little tricker than just that.

    So far, I can only see the need to create a list based on one tag at a time, however I guess it's always nice to have the option should I need to call a combination if that was something that could be done.

  • Chriztian Steinmeier 2798 posts 8787 karma points MVP 7x admin c-trib
    Jun 17, 2013 @ 00:51
    Chriztian Steinmeier
    1

    Hi FarmFreshCode,

    Okay - Niels's code has a lot of what you need, actually - but this is the point where I'd normally get someone to write an extension for me - the logic needed to do all the things you want is much better encapsulated in a C# extension, so your "view" code can do what it's supposed to. Just think about it - what you really want to do is something like this:

    <!-- Build an XML variable with all the filters available -->
    <xsl:variable name="filterProxy">
            <filter id="6624" property="facultyBuilding" value="HPA I" />
            <filter id="3385" property="facultyDepartment" value="Social Work" />
    
            <filter id="4490" property="facultyAffiliations" tags="Tech Committee" />
            <filter id="4492" property="facultyAffiliations" tags="Tech Committee,Other Tag" />
    </xsl:variable>
    
    <!-- Grab the filter that applies to the current page -->
    <xsl:variable name="facultyFilter" select="msxml:node-set($filterProxy)/filter[@id = $currentPage/@id]" />
    
    <!-- Grab the root node to do lookups under -->
    <xsl:variable name="rootNode" select="umbraco.library:GetXmlNodeById(6394)" />
    
    <xsl:template match="/">
        <!-- Process the <filter> with the appropriate template -->
        <xsl:apply-templates select="$facultyFilter" />
    </xsl:template>
    
    <!-- Template for a VALUE filter -->
    <xsl:template match="filter[@value]">
        <xsl:variable name="nodes" select="ffc:FilterNodesByValue($rootNode/FacultyProfile, @value)" />
        <xsl:apply-templates select="$nodes | $rootNode/FacultyProfile[not($facultyFilter)]" />
    </xsl:template>
    
    <!-- Template for a TAGS filter -->
    <xsl:template match="filter[@tags]">
        <xsl:variable name="nodes" select="ffc:FilterNodesByTags($rootNode/FacultyProfile, @tags)" />
        <xsl:apply-templates select="$nodes | $rootNode/FacultyProfile[not($facultyFilter)]" />
    </xsl:template>
    
    <!-- Actual output template -->
    <xsl:template match="FacultyProfile">
        <p>
            <xsl:value-of select="@nodeName" />
        </p>
    </xsl:template>

    Where the ffc: prefix of course is bound to your extension - see this guide for how to build it yourself...

    You *can* do the filtering in XSLT but the code needed to do bulletproof tag-matching in CSV strings will vastly degrade the readability of the actual view code. Hope I'm not too discouraging by answering this way :-)

    /Chriztian

  • FarmFreshCode 225 posts 422 karma points
    Jun 17, 2013 @ 19:00
    FarmFreshCode
    0

    Hmmm, well it's certainly helpful to know the most optimized way to do it.. I sure do seem to play in the deep in a lot. ;) thanks for your help thus far.

Please Sign in or register to post replies

Write your reply to:

Draft