Copied to clipboard

Flag this post as spam?

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


  • Cameron 23 posts 42 karma points
    Sep 13, 2012 @ 13:47
    Cameron
    0

    Using Key grouping to show docs based on the date they were published

    Hi folks,

    I have a strange issue here (strange issues everywhere really, but ony this one matters!)

    After much googling and searching the forums I produced the following code last week to show a list of years that a document may have been published for, and then the list of documents for the selected year following it.

    Whilst this code seemed to work for a while, it now fails to render the year links properly anymore. I seem to only get the first one, and only if the year is 2012. Even stranger, I have one page with documents underneath it that still works fine. Renders all tabs correctly.

    For your reference, this is an example of the output, working fine. 

    <ul class="tabs">
       <li class="selected"><a href="?year=2011">2011</a></li>
       <li><a href="?year=2010">2010</a></li>
       <li><a href="?year=2009">2009</a></li>
       <li><a href="?year=2008">2008</a></li>
       <li><a href="?year=2007">2007</a></li>
       <li><a href="?year=2002">2002</a></li>
    </ul>
    <div id="tab-content">
       <table id="data">
       <tr><td class="date">30 Dec 2011</td><td class="doc"><a target="_blank" href="aDoc.pdf" title="Annual Report for 31 December 2011">Annual Report, 2011 December</a></td><td class="size">827KB</td></tr>
       <tr><td class="date">30 Jun 2011</td><td class="doc"><a target="_blank" href="anotherDoc.pdf" title="Interim Financial Report for 30 June 2011">Interim Financial Report, June 2011</a></td><td class="size">576KB</td></tr>
       </table>
    </div>

    And this is the code.

    <?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.dates="urn:ucomponents.dates" xmlns:ucomponents.nodes="urn:ucomponents.nodes" xmlns:ucomponents.random="urn:ucomponents.random" xmlns:ucomponents.email="urn:ucomponents.email" 
      exclude-result-prefixes="msxml umbraco.library Exslt.ExsltCommon Exslt.ExsltDatesAndTimes Exslt.ExsltMath Exslt.ExsltRegularExpressions Exslt.ExsltStrings Exslt.ExsltSets ucomponents.dates ucomponents.nodes ucomponents.random ucomponents.email ">


    <xsl:output method="xml" omit-xml-declaration="yes"/>

    <xsl:param name="currentPage"/>

    <xsl:variable name="documentTypeAlias" select="string('GenericDocument')"/>
    <xsl:variable name="data" select="$currentPage/* [name() = $documentTypeAlias and string(umbracoNaviHide) != '1']"/>    
    <xsl:key name="Docs-by-Year" match="GenericDocument" use="substring(newsDate, 1, 4)" />
        
    <xsl:variable name="yearPage" >
    <xsl:choose>
    <!-- first page -->
    <xsl:when test="umbraco.library:RequestQueryString('year') &lt;= 0 or string(umbraco.library:RequestQueryString('year')) = '' or string(umbraco.library:RequestQueryString('year')) = 'NaN'">
      <xsl:for-each select="$data">
          <xsl:sort select="newsDate" order="descending" />
        <xsl:if test="position() = 1" >
          <xsl:value-of select="substring(newsDate, 1, 4)"/>
        </xsl:if>  
      </xsl:for-each>
    </xsl:when>
    <!-- or what was passed in -->
    <xsl:otherwise>
    <xsl:value-of select="umbraco.library:RequestQueryString('year')"/>
    </xsl:otherwise>
    </xsl:choose>
     
    </xsl:variable>    
        
    <xsl:template match="/">
      <!-- Build the TABS first -->
      <ul class="tabs">
      <xsl:for-each select="$data[count(. | key('Docs-by-Year', substring(newsDate, 1, 4))[1]) = 1]">
        <xsl:sort select="substring(newsDate, 1, 4)" order="descending" />
        <xsl:variable name="theYear" select="substring(newsDate, 1, 4)" />    
          <li>
            <xsl:if test="$theYear = $yearPage">
              <xsl:attribute name="class">selected</xsl:attribute>   
            </xsl:if>    
            <href="?year={$theYear}"><xsl:value-of select="$theYear" /></a>
          </li>      
      </xsl:for-each>
      </ul
     <!-- Now build doc list for page selected--> 
    <div id="tab-content">
          <table id="data">  
      <xsl:for-each select="$data">
                    <xsl:sort select="newsDate" order="descending" />
        <xsl:if test="substring(newsDate, 1, 4) = $yearPage">
          <xsl:variable name="size" select="umbracoBytes" />
          <xsl:variable name="sizeAndSuffix">
            <xsl:choose>
                    <xsl:when test="$size &gt;= 1073741824">
                            <xsl:value-of select="format-number($size div 1073741824,'#,###')"/>
                            <xsl:text>GB</xsl:text>
                    </xsl:when>
                    <xsl:when test="$size &gt;= 1048576">
                            <xsl:value-of select="format-number($size div 1048576,'#,###')"/>
                            <xsl:text>MB</xsl:text>
                    </xsl:when>
                    <xsl:when test="$size &gt;= 1024">
                            <xsl:value-of select="format-number($size div 1024,'#,###')"/>
                            <xsl:text>KB</xsl:text>
                    </xsl:when>
                    <xsl:when test="$size &gt; 0 and $size &lt; 1024">
                            <xsl:value-of select="format-number($size div 0,'#,###')"/>
                            <xsl:textBytes</xsl:text>
                    </xsl:when>
                    <xsl:otherwise>
                            <xsl:text>0 Bytes</xsl:text>
                    </xsl:otherwise>
            </xsl:choose>
    </xsl:variable>      
            <tr>
              <td class="date"><xsl:value-of select="umbraco.library:FormatDateTime(newsDate, 'dd MMM yyyy')"/></td>
              <td class="doc">
                <target="_blank">
                  <xsl:attribute name="href">
                    <xsl:value-of select='umbracoFile' />
                  </xsl:attribute>
                  <xsl:attribute name="title">
                    <xsl:value-of select="fileDescription"/>
                  </xsl:attribute>
                  <xsl:value-of select="@nodeName"/>
                </a>
              </td>
              <td class="size"><xsl:value-of select="$sizeAndSuffix"/></td>
            </tr>        
        </xsl:if>
        </xsl:for-each>
      </table>
    </div>
        
    </xsl:template>


    </xsl:stylesheet>

     

    Can anyone with a better XSLT head on their shoulder than me see anything potentially wrong with what I have done and point me in the right direction?

    Like with everything, this will stop hurting me when I can stop hitting my head against this proverbial brick wall.

    Cheers,

     

    Cameron

     

  • Cameron 23 posts 42 karma points
    Sep 17, 2012 @ 01:59
    Cameron
    0

    Was really hoping there would be someone out there who would be able to help...

    Please?

  • Chriztian Steinmeier 2798 posts 8788 karma points MVP 8x admin c-trib
    Sep 17, 2012 @ 08:59
    Chriztian Steinmeier
    0

    Hi Cameron,

    It's always a little hard to help with something that used to work but now doesn't - simply because we don't know nearly as much about what has or has not changed between "before" and "after"...

    That said, from looking at the code, I can see that if your links don't render, the problem could be that the $data variable only collects nodes that are direct children of $currentPage, thus they're the only ones being iterated (even though the key() may return more "valid" pages).

    Could that be part of the problem?

    /Chriztian

  • Cameron 23 posts 42 karma points
    Sep 18, 2012 @ 01:01
    Cameron
    0

    Hi Chriztian,

    thanks for taking the time to reply. 

    Unfortunately, the problem is not related to not rendering the doc links, it's the tabs at the top. It is defintely the Key grouping code that seems to be at fault.

    Strangely, I have one place where the code is working fine, and another where it only renders one tab, and that is only if it's the current year. It is very strange.

    End story for me, I cracked it and rewrote the code as a Razor script in C# after spending 4 hours trying to debug it. 

    For everyones reference, here is the attached razor code, which of course works.

    I'm sure it could be improved, but it works. Feel free to take it and do whatever you wish with it.

    @using umbraco.MacroEngines
    @inherits umbraco.MacroEngines.DynamicNodeContext
    @{
      var pagesToList @Model.Children.OrderBy("newsDate desc");
      
      var yearParam HttpContext.Current.Request.QueryString["year"];
      var theYear "0";
      var selClass "";
      var xBytes "";

      var yearToDisplay String.IsNullOrEmpty(yearParam
        pagesToList.First().GetProperty("newsDate").Value.Substring(0,4:  
        yearParam;

      @Build Tabs first *@
      <ul class="tabs">
          @foreach(var aDoc in pagesToList)
          {
          if (theYear != aDoc.GetProperty("newsDate").Value.Substring(0,4))
            theYear aDoc.GetProperty("newsDate").Value.Substring(0,4);
            if (theYear == yearToDisplay)selClass "class=\"selected\"";  else {selClass "";}
          <li @Html.Raw(selClass)>
            <href="?year=@theYear">@theYear</a>
          </li>      
            }
          
      </ul>   
    @Now build doc list for page selected  *@
    <div id="tab-content">
      <table id="data"
      @foreach (var aDoc in pagesToList)
      {
        if (aDoc.GetProperty("newsDate").Value.Substring(0,4== yearToDisplay)
       {
        <tr>
          <td class="date">@DateTime.Parse(aDoc.GetProperty("newsDate").Value).ToString("dd MMM yyyy")</td>
              <td class="doc">
                <target="_blank" href="@aDoc.GetProperty("umbracoFile")" title="@aDoc.GetProperty("fileDescription")">
                  @aDoc.Name
                </a>
              </td>
            
            @try{
            if (Convert.ToUInt64(aDoc.umbracoBytes1048576)
            xBytes ((Math.Round(Convert.ToDecimal(aDoc.umbracoBytes10240)).ToString(" KB")
            else {
              xBytes ((Math.Round(Convert.ToDecimal(aDoc.umbracoBytes10485762)).ToString(" MB")}
             }catch{xBytes"0 bytes";}  
              <td class="size">@xBytes</td>
      
            </tr>        
       }
    }
      </table>
    </div>
     
    }

    Cheers,

    Cameron

     

Please Sign in or register to post replies

Write your reply to:

Draft