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 2800 posts 8791 karma points MVP 9x 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 2800 posts 8791 karma points MVP 9x 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.

  • This forum is in read-only mode while we transition to the new forum.

    You can continue this topic on the new forum by tapping the "Continue discussion" link below.

Please Sign in or register to post replies