Copied to clipboard

Flag this post as spam?

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


  • Andrew Blackmore 84 posts 127 karma points
    Mar 04, 2010 @ 20:56
    Andrew Blackmore
    0

    xPath Issue - Getting date from previous post

    Everything in this works (or at least seems to) except for one vital thing.

    To give you a little background, I am displaying the create date (for blog entries) and I don't want the create date to show if the previously displayed (newer) post has the same date. I set it up like this:

     

              <xsl:variable name="previousDate" select="$currentPage/node [@nodeTypeAlias = 'Blog']//preceding-sibling::node [@nodeTypeAlias = 'BlogPost']//@createDate" />
              <xsl:variable name="currentDate" select="$currentPage/node [@nodeTypeAlias = 'Blog']//self::node [@nodeTypeAlias = 'BlogPost']//@createDate" />
              <xsl:variable name="currentDateFormat" select="umbraco.library:FormatDateTime($currentDate, 'MMM d')"/>
              <xsl:variable name="previousDateFormat" select="umbraco.library:FormatDateTime($previousDate, 'MMM d')"/>
              <xsl:choose>
              <xsl:when test="$currentDateFormat != $previousDateFormat">
                <xsl:value-of select="$currentDateFormat" disable-output-escaping="yes"/>
                <xsl:value-of select="$previousDateFormat" disable-output-escaping="yes"/>
              </xsl:when>
                <xsl:otherwise>
                  <xsl:value-of select="umbraco.library:FormatDateTime($post/@createDate, 'MMM d')"/>
                </xsl:otherwise>
              </xsl:choose>

    The choose/when/otherwise is working fine as is all of the date formatting but i am not getting the correct date returned. I figured preceding-sibling might work in this case, but I am getting the current date with preceding-sibling and a very old date by using self.

    As soon as I thought the XSLT side of things was making sense, the pathing is confusing me. I hope I'm just being confused a bit. I spent some time digging through the wiki and didn't find anything that made this more clear to me.

  • Douglas Robar 3570 posts 4711 karma points MVP ∞ admin c-trib
    Mar 04, 2010 @ 21:09
    Douglas Robar
    2

    The hardest part of XSLT is getting the xpath to return what you want.

    This page may help you understand why you're getting what you are, and how to get what you want. http://umbraco.org/documentation/books/xslt-basics/xpath-axes-and-their-shortcuts

    Otherwise, give us a sense of your content tree structure so we can help more specifically.

    cheers,
    doug.

  • Chriztian Steinmeier 2798 posts 8788 karma points MVP 8x admin c-trib
    Mar 04, 2010 @ 21:20
    Chriztian Steinmeier
    1

    I see two things right away:

    1. You're using the descendant:: axis (//) where you should probably use the child:: axis (/) a couple of places
    2. When using preceding-sibling:: (and following-sibling::) you tend to think of the single node before or after, but those axes return all the preceding/following siblings, so you need to tack on a [1] to the XPath to get only the one node, like this:
              <xsl:variable name="previousDate" select="$currentPage/node [@nodeTypeAlias = 'Blog']/preceding-sibling::node[@nodeTypeAlias = 'BlogPost'][1]/@createDate" />
             
    <xsl:variable name="currentDate" select="$currentPage/node [@nodeTypeAlias = 'Blog']//node[@nodeTypeAlias = 'BlogPost'][1]/@createDate" />

    But as Douglas says - give us a sample of the Content structure and we'll help you nail those XPaths.

    /Chriztian

  • Andrew Blackmore 84 posts 127 karma points
    Mar 04, 2010 @ 21:25
    Andrew Blackmore
    0

    See, that diagram is what had me so confident this was going to work in the first place. The structure is set up as so:

    Home

    --Blog

    ----Blogpost

    ----Blogpost

     

    --Blog

    ----Blogpost

    ----Blogpost

    and the createDate is just a standard attribute of the Blogpost document type. I'm trying a bunch of new combinations, but I have the feeling that this should work at least as far as posts within the same blog. Maybe I'm running into issues because this page displays entries from multiple blog nodes.

  • Chriztian Steinmeier 2798 posts 8788 karma points MVP 8x admin c-trib
    Mar 04, 2010 @ 21:38
    Chriztian Steinmeier
    0

    Hi Andrew,

    If the BlogPost node you're currently rendering is the post variable, then your XPaths would be as follows:

    <xsl:variable name="previousDate" select="$post/preceding-sibling::node[@nodeTypeAlias = 'BlogPost'][1]/@createDate" />
    <xsl:variable name="currentDate" select="$post/@createDate" />

    This will work inside the same Blog section - are you rendering multiple Blogs to the same stream? 

    /Chriztian

  • Andrew Blackmore 84 posts 127 karma points
    Mar 04, 2010 @ 21:42
    Andrew Blackmore
    0

    Hi Chriztian,

    I am rendering multiple blogs on the same stream for a homepage of a multi-blog network. Let me take this and see what it does and what I can do from here. Thanks to both you and Doug for your very very fast and helpful responses.

     

    Andrew

  • Andrew Blackmore 84 posts 127 karma points
    Mar 05, 2010 @ 15:25
    Andrew Blackmore
    0

    Update::

    Almost there! This help has been invaluable.

    @Chriztian - I took the code you provided and had to alter it a bit. I had mixed things up a bit so following-sibling was what I needed. The following code posts exactly what I need it to...minus one aspect. The first post does not post the date. I tried using position()=1 but the issue is that every time I print the position for posts that do not show the date, it is 1. I'm taking a look at this with fresh eyes this morning and will post if I find anything but if you have any ideas I'd love to hear them. Here is the code I have.

     

    I'm printing out position() for every post that doesn't post a date just for my own reference.

     <xsl:for-each select="$post">
                <xsl:variable name="previousDate" select="$post/following-sibling::node[@nodeTypeAlias = 'BlogPost'][1]/@createDate" />
                <xsl:variable name="currentDate" select="$post/@createDate" />
                <xsl:variable name="currentDateFormat" select="umbraco.library:ShortDate($currentDate)"/>
                <xsl:variable name="previousDateFormat" select="umbraco.library:ShortDate($previousDate)"/>
                <xsl:choose>
                  <xsl:when test="$previousDateFormat != $currentDateFormat">
                    <xsl:value-of select="umbraco.library:FormatDateTime($currentDateFormat, 'MMM d')"/>
                  </xsl:when>
                  <xsl:otherwise>
                    <xsl:value-of select="position()"/>
                  </xsl:otherwise>
                </xsl:choose>
              </xsl:for-each>
  • Andrew Blackmore 84 posts 127 karma points
    Mar 05, 2010 @ 15:41
    Andrew Blackmore
    0

    I love it. I walked away for the night and it was so obvious with fresh eyes. I needed to use position() outside of the for-each

    <xsl:if test="position()=1">
                <xsl:value-of select="umbraco.library:FormatDateTime(@createDate, 'MMM d')"/>           
              </xsl:if>
              <xsl:if test="position()&gt;= 2">
              <xsl:for-each select="$post">
                <xsl:variable name="previousDate" select="$post/following-sibling::node[@nodeTypeAlias = 'BlogPost'][1]/@createDate" />
                <xsl:variable name="currentDate" select="$post/@createDate" />
                <xsl:variable name="currentDateFormat" select="umbraco.library:ShortDate($currentDate)"/>
                <xsl:variable name="previousDateFormat" select="umbraco.library:ShortDate($previousDate)"/>
                <xsl:choose>
                  <xsl:when test="$previousDateFormat != $currentDateFormat">
                    <xsl:value-of select="umbraco.library:FormatDateTime($currentDateFormat, 'MMM d')"/>
                  </xsl:when>
                  <xsl:otherwise>
                    <xsl:value-of select="position()"/>
                  </xsl:otherwise>
                </xsl:choose>
              </xsl:for-each>
              </xsl:if>

    works like a charm now!


    thanks again for everybody's help

Please Sign in or register to post replies

Write your reply to:

Draft