Copied to clipboard

Flag this post as spam?

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


  • jacob phillips 130 posts 372 karma points
    May 02, 2014 @ 00:30
    jacob phillips
    0

    filtering tag list by location

    I have a document type that is used in different areas of the website. On this document type is a tag group named 'default'.

    I have seen other forum posts where someone wants to list pages that contain a given tag. But what I want to do is pull a sub-list of tags based on their location under a given node.

    So for example, I might have the following content tree structure:

    -site root --sub 1 ---sub 1.1 ---sub 1.2 --sub 2 --- sub 2.1 --- sub 2.2 --- sub 2.3

    Note that sub 1.x and sub 2.x use the same document type. I want to generate and display a list of tags on sub 2 which are in use on pages under sub 2 only.

    I currently get my tag list like this:

      <xsl:for-each select="tags:getAllTagsInGroup('default')/tags/tag">
    

    I see that there is an xslt extension for tag type: getTagsFromNode(int nodeid)

    But what I want is something like getTagsUnderNode (int nodeid).

    I realize that another solution would be to just have separate document types where a different tag group could be defined. But I'm trying to avoid that.

    Is there some XSLT magic to do it using a predicate?

    Actually, I realize, that I do not need to use the extension methods for tags. I can just pull a list of nodes where the tag field is not null, like this:

    <xsl:variable name="thetags" select="umbraco.library:GetXmlNodeById($currentPage/@id)//story[tags != '']" />
    

    and then loop through them...

    <xsl:for-each select="$thetags">
       <xsl:sort select="." />
        <a href="/taglist?tag={./tags}">
          <xsl:value-of select="./tags"/>
        </a>
    </xsl:for-each>
    

    But, I quickly realize, that this is not going to work. I need to somehow create a distinct list, and take into account that some nodes will have 1 tag, and others will have more than one, separated by commas....

  • jacob phillips 130 posts 372 karma points
    May 02, 2014 @ 05:18
    jacob phillips
    100

    ...and thanks to this post, I figured it out:

    <xsl:variable name="taggednodes" select="umbraco.library:GetXmlNodeById($currentPage/@id)//story[tags != '']"/>
    
    <xsl:variable name="tagcount" select="count($taggednodes)" />
    
    <xsl:if test="$tagcount > 0">
    <xsl:variable name="thetags">
     <xsl:for-each select="$taggednodes"><xsl:value-of select="normalize-space(./tags)" />,</xsl:for-each>
    </xsl:variable>
    
    <xsl:variable name="resultSet" select="gecko:DistinctValues($thetags)"  />
    
    <div class="tag-list">
    <h3>Tag List</h3>
    <div class="content-box">
    <p class="tags">
    <xsl:for-each select="$resultSet//value">
       <xsl:sort select="." />
        <a href="/taglist?tag={.}">
          <xsl:value-of select="."/>
        </a>
    </xsl:for-each>
    </p>
    </div>
    </div>
    
    </xsl:if>
    

    ...although I think that I have heard that putting this type of C# code (the call to gecko:DistinctValues($thetags), defind in the link above) in your templates is bad practice? Or maybe it's only when such C# code queries the database (which it is not doing here).

  • Chriztian Steinmeier 2798 posts 8788 karma points MVP 7x admin c-trib
    May 02, 2014 @ 09:00
    Chriztian Steinmeier
    0

    Hi Jacob,

    Yes it's not a good idea (there are/were some serious memory issues with it). Fortunately you can just move the code into an App_Code Extension and have it work the same.

    I've never worked with the "tags" datatype so can't really offer any advice - I don't know how its stuff is stored in the XML tree...

    /Chriztian

Please Sign in or register to post replies

Write your reply to:

Draft