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 22, 2014 @ 22:49
    jacob phillips

    get latest n items, by n locations, sorted by latest representative node type, best practice approach?

    In the content tree, there are several programs. These programs have shows (showDocType). Some shows are daily, some are weekly. Sometimes there is no regular interval.

    I want to build a custom node set, such that, the XSLT will look through the entire content tree for shows, then using a parameter, get the latest 1 (or 2,...,or n) shows. Then I want to sort this list such that the latest representative from each show comes first in the list.

    Geez, this is already getting complicated.

    I can easily get a large node set of all the "showDocTypes". I think the challenge here, is the sorting I want to do. Especially since I don't ONLY want the latest one (necessarily) by the show's unique program name (or perhaps parent location).

    Instead of trying to make it so automatic (i.e. a new program with shows gets created in the content tree, and its shows will automatically show up in this list), maybe I should just define variables in my XSLT, one for each Program that I want in the list.

    That approach seems a lot more straight forward. Then, each program variable node set could be manually configured in the macro (i.e. not via parameter) to have the 1, or 2, ..., or n latest items. Then when I merge all of these separate variables containing shows, sort them.

    I guess the disadvantage is that a new variable will have to be added the macro for a new show. It doesn't happen that often. But I guess it would be nice. We often use a null archivedate as a way of NOT including items in lists, for all of our macros. So that provides an overriding control to keep any item out of a list.

    SO over all, I would ask the expert(s):

    1) Should I ditch the idea of trying to make the whole macro automatic, that is, search for all shows, restrict the latest "n items" feature to be the same for all. And pull out the latest "n" representatives of each program by display date...


    2) Construct the components of the node set (i.e. 1 or n shows from each program) separately, and just deal with new shows by editing the macro.

    I guess I'm leaning towards 2) because 1) seems like it could get out of hand or be difficult to address exceptions.

    And I guess I haven't thought too much about this question:

    a) Once you have your merged list, how to sort by latest representative of each program first (which do not occur at regular intervals amongst one another), and then, by display date?

  • Chriztian Steinmeier 2798 posts 8788 karma points MVP 8x admin c-trib
    May 22, 2014 @ 23:40
    Chriztian Steinmeier

    Hi Jacob,

    A couple of quick thoughts:

    • If all show types have some kind of wrapper doctype, you could put the "Show # of items in list" as a property on that.. ? (So the XSLT could just look it up for each of the separate types)
    • I would seriously consider writing an extension to do the filtering - it gets messy really fast; it's not impossible, but it's really the wrong place to do it, I think.

    Main problem is that the only way to get "the first X nodes" of a set that's also being sorted, is this pattern:

    <xsl:for-each select="$nodes">
        <xsl:sort select="dateProperty" data-type="text" order="descending" />
        <xsl:if test="position() &lt;= 2">
            <!-- Do something -->

    - so writing an extension to do the sorting, would make it a lot simpler - e.g.:

    <xsl:apply-templates select="$sortedNodes[position() &lt;= 2]" />


  • jacob phillips 130 posts 372 karma points
    May 23, 2014 @ 00:00
    jacob phillips

    Hi Chriztian,

    Yeah, all the show doctypes have a great-great-great-great-grandparent of doctype program (shows are in date folders).

    Hmmm, that's interesting. A property on the program docType....

    When you refer to extension, do you mean like this?

    Here's what I got so far..a little tedious as have to create a variable for each program that I want in my list. But I can control the number of items individually.

        <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE xsl:stylesheet [ <!ENTITY nbsp "&#x00A0;"> ]>
        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:SqlHelper="urn:SqlHelper" xmlns:umbraco.contour="urn:umbraco.contour" xmlns:tags="urn:tags" 
        exclude-result-prefixes="msxml umbraco.library Exslt.ExsltCommon Exslt.ExsltDatesAndTimes Exslt.ExsltMath Exslt.ExsltRegularExpressions Exslt.ExsltStrings Exslt.ExsltSets SqlHelper umbraco.contour tags ">
    <xsl:output method="xml" omit-xml-declaration="yes"/>
    <xsl:include href="cprGetPrimaryImage.xslt" />
    <xsl:param name="currentPage"/>
        <!-- MMBP --> 
        <xsl:variable name="MMBP" select="umbraco.library:GetXmlNodeById(1265)//show[archiveDate != '']" />
        <!-- BDJ --> 
        <xsl:variable name="BDJ" select="umbraco.library:GetXmlNodeById(1266)//show[archiveDate != '']" />
        <xsl:variable name="latestProxy">
            <!-- Loop taglists defined above, -->
            <xsl:for-each select="$MMBP" >
                    <!-- sorted by displayDate (latest first) -->
                    <xsl:sort select="@displayDate" data-type="text" order="descending" />
                    <!-- grab the first one's `@id` -->
                    <xsl:if test="position() = 1">
                    <node id="{@id}" />
            <xsl:for-each select="$BDJ" >
                    <!-- sorted by displayDate (latest first) -->
                    <xsl:sort select="@displayDate" data-type="text" order="descending" />
                    <!-- grab the first one's `@id` -->
                    <xsl:if test="position() = 1">
                <node id="{@id}" />
        <!-- Create an XPath-navigable version of that set -->
        <xsl:variable name="latest" select="make:node-set($latestProxy)" />
    <xsl:template match="/">
        <xsl:for-each select="$latest/node">
            <xsl:variable name="taggedNode" select="umbraco.library:GetXmlNodeById(@id)" />
            <div class="col-xs-12 col-sm-6 latest-story-by-tag">
            <div class="image-content-box">
            <!-- Related Image --> 
            <a class="image" href="{umbraco.library:NiceUrl($taggedNode/@id)}">
            <xsl:call-template name="getprimaryimage">
               <xsl:with-param name="nodeid" select="$taggedNode/@id" />
               <xsl:with-param name="imagetype" select="'imageRStoryRelated'" />
            <div class="post-text">
            <!-- Link To Show With Program Name Link Text --> 
            <a><xsl:attribute name="href"><xsl:value-of select="umbraco.library:NiceUrl($taggedNode/@id)" /></xsl:attribute>
            <h1><xsl:value-of select="$taggedNode/../../../../@nodeName" /></h1>
            <!-- Show Date -->
            <p><xsl:value-of select="umbraco.library:FormatDateTime($taggedNode/displayDate, 'dddd, MMMM dd, yyyy')" /></p>
            </div> <!--/.post-text -->
Please Sign in or register to post replies

Write your reply to: