I'm fairly new to XSLT but the reason I can see that you get "true new pages" is that you are asking for the value of a 'binary and' condition which equates to 'true'. I'm not in a position to test this but I'd expect to see something like:
Steve is right, you ask for the value of a boolean test, so you're getting 'true' as output. Here's a simpler way to do it - note that I use variables extensively, which should make it easier for anyone reading it to grasp what's going on, but also to not be calling the extension methods more than once:
<!-- The date calculation stuff -->
<xsl:variable name="today" select="umb:CurrentDate()" />
<xsl:variable name="oneMonthAgo" select="umb:DateAdd($today, 'm', -1)" />
<!-- Grab the nodes to look at -->
<xsl:variable name="nodes" select="$currentPage/DocTypeAlias" />
<!-- Pages created within the last 30 days -->
<xsl:variable name="newPages" select="$nodes[umb:DateGreaterThanOrEqual(@createDate, $oneMonthAgo)]" />
<xsl:template match="/">
<p>
<xsl:value-of select="count($newPages)" />
<xsl:text> new page</xsl:text>
<xsl:if test="count($newPages) > 1">s</xsl:if>
</p>
</xsl:template>
I'm using it for an Image Library I'm creating, the Content structure is as follows:
Image Gallery Image Gallery Album Image Gallery Photo Image Gallery Photo Image Gallery Album Image Gallery Photo Image Gallery Photo
The Image Gallery displays a list of the child Image Gallery Albums, and displays how many Image Gallery Photo's are within each album and how many new images.
Below is the XSLT I'm using, I've copied your code but may not have it correct to allow for the split between New Images for each Image Gallery Album.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE xsl:stylesheet [ <!ENTITY nbsp " "> ]>
<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:PS.XSLTsearch="urn:PS.XSLTsearch"
exclude-result-prefixes="msxml umbraco.library Exslt.ExsltCommon Exslt.ExsltDatesAndTimes Exslt.ExsltMath Exslt.ExsltRegularExpressions Exslt.ExsltStrings Exslt.ExsltSets PS.XSLTsearch ">
<xsl:output method="xml" omit-xml-declaration="yes" />
<xsl:param name="currentPage"/>
<!-- Input the documenttype you want here -->
<xsl:variable name="documentTypeAlias" select="string('ImageGalleryAlbum')"/>
<!-- The date calculation stuff -->
<xsl:variable name="today" select="umbraco.library:CurrentDate()" />
<xsl:variable name="oneMonthAgo" select="umbraco.library:DateAdd($today, 'd', -30)" />
<!-- Grab the nodes to look at -->
<xsl:variable name="nodes" select="$currentPage/*/ImageGalleryPhoto" />
<!-- Pages created within the last 30 days -->
<xsl:variable name="newPages" select="$nodes[umbraco.library:DateGreaterThanOrEqual(@createDate, $oneMonthAgo)]" />
<xsl:template match="/">
<!-- The fun starts here -->
<div class="imageGalleryAlbum">
<ul>
<xsl:for-each select="$currentPage/* [name() = $documentTypeAlias and string(umbracoNaviHide) != '1']">
<li>
<xsl:if test="position() mod 4 > 0">
<xsl:attribute name="class">image_1_3</xsl:attribute>
</xsl:if>
<xsl:if test="position() mod 4 = 0">
<xsl:attribute name="class">image_4</xsl:attribute>
</xsl:if>
<a href="{umbraco.library:NiceUrl(@id)}">
<img src="{concat(substring-before(umbraco.library:GetMedia(./*/imageGalleryPhoto, 'false')/umbracoFile,'.'), '_thumb_150.jpg')}" />
</a>
<p>
<a href="{umbraco.library:NiceUrl(@id)}">
<xsl:value-of select="@nodeName"/>
</a>
</p>
<xsl:choose>
<xsl:when test="count(child::ImageGalleryPhoto) > 1">
<p><xsl:value-of select="count(child::ImageGalleryPhoto)"/> Images</p>
</xsl:when>
<xsl:otherwise>
<p><xsl:value-of select="count(child::ImageGalleryPhoto)"/> Image</p>
</xsl:otherwise>
</xsl:choose>
<xsl:choose>
<xsl:when test="count($newPages) > 1">
<p>
<xsl:value-of select="count($newPages)" />
<xsl:text> New Image</xsl:text>
<xsl:if test="count($newPages) > 1">s</xsl:if>
</p>
</xsl:when>
<xsl:otherwise>
</xsl:otherwise>
</xsl:choose>
</li>
</xsl:for-each>
</ul>
</div>
</xsl:template>
</xsl:stylesheet>
Yeah, you just need to filter the $newPages variable and only count the ones inside the current gallery - should be something like this:
<!-- Select ImageGalleryPhoto children that also exist in the $newPages set -->
<xsl:variable name="newImagesInHere" select="ImageGalleryPhoto[@id = $newPages/@id]" />
<xsl:when test="$newImagesInHere">
<p>
<xsl:value-of select="count($newImagesInHere)" />
<xsl:text> New Image</xsl:text>
<xsl:if test="count($newImagesInHere) > 1">s</xsl:if>
</p>
</xsl:when>
I just tried that code, and it didn't show any results.
It would only show results when I changed it to this:
<!-- Select ImageGalleryPhoto children that also exist in the $newPages set --> <xsl:variable name="newImagesInHere" select="$currentPage/*/ImageGalleryPhoto[@id = $newPages/@id]" />
Which still gives me the total for all grandchildren. e.g. 22 New Images
That seems strange, but let's get everything right then.
I rewrote this to use a couple of match templates instead, which is much easier to manage (I think) and this gives me the right values for total and new images, when I recreate the structure you describe (these replace that one "the fun starts here" template):
<xsl:template match="/">
<div class="imageGalleryAlbum">
<ul>
<!-- Process albums below current page -->
<xsl:apply-templates select="$currentPage/ImageGalleryAlbum[not(umbracoNaviHide = 1)]" />
</ul>
</div>
</xsl:template>
<xsl:template match="ImageGalleryAlbum">
<li>
<xsl:if test="position() mod 4 > 0"><xsl:attribute name="class">image_1_3</xsl:attribute></xsl:if>
<xsl:if test="position() mod 4 = 0"><xsl:attribute name="class">image_4</xsl:attribute></xsl:if>
<a href="{umbraco.library:NiceUrl(@id)}">
<!-- Create a thumbnail for the first ImageGalleryPhoto in here -->
<xsl:apply-templates select="ImageGalleryPhoto[1]/imageGalleryPhoto[normalize-space()]" mode="thumb" />
</a>
<p>
<a href="{umbraco.library:NiceUrl(@id)}">
<xsl:value-of select="@nodeName" />
</a>
</p>
<p>
<xsl:variable name="imagesInHere" select="count(ImageGalleryPhoto)" />
<xsl:value-of select="$imagesInHere" />
<xsl:text> Image</xsl:text>
<xsl:if test="$imagesInHere > 1">s</xsl:if>
</p>
<p>
<xsl:variable name="newImagesInHere" select="count(ImageGalleryPhoto[@id = $newPages/@id])" />
<xsl:value-of select="$newImagesInHere" />
<xsl:text> New Image</xsl:text>
<xsl:if test="$newImagesInHere > 1">s</xsl:if>
</p>
</li>
</xsl:template>
<xsl:template match="*" mode="thumb">
<xsl:variable name="media" select="umbraco.library:GetMedia(., false())" />
<xsl:if test="not($media[error])">
<xsl:variable name="extension" select="concat('.', $media/umbracoExtension)" />
<img src="{concat(substring-before($media/umbracoFile, $extension), '_thumb_150.jpg')}" />
</xsl:if>
</xsl:template>
How to display number of new child pages XSLT
I have two separate pieces of code I'm trying to combine.
The first counts the number of child pages and displays a number:
e.g. 8 child pages (or child page, if only 1 page)
The code detects if the page was created within the last 30 days:
I want to combine them so I can get a count of child pages and a count of the "new" pages.
e.g. 8 child pages - 2 new pages
I've tried the following but it doesn't return the correct values:
It returns: "true new pages" I don't know how to get it to display the number (2 new pages).
Can anyone help? Cheers, JV
I'm fairly new to XSLT but the reason I can see that you get "true new pages" is that you are asking for the value of a 'binary and' condition which equates to 'true'. I'm not in a position to test this but I'd expect to see something like:
<xsl:variable name="datediff" select="umbraco.library:DateDiff(umbraco.library:ShortDate(umbraco.library:CurrentDate()), umbraco.library:ShortDate(@createDate), 'm')" />
<xsl:choose>
<xsl:when test="$datediff < (1440 * 30) and count(child::DocTypeAlias) > 1">
<p><xsl:value-of select="$datediff < (1440 * 30)"><xsl:value-of select="count(child::DocTypeAlias)"/> new pages</xsl:value-of></p>
</xsl:when>
<xsl:otherwise>
<p><xsl:value-of select="$datediff < (1440 * 30)"><xsl:value-of select="count(child::DocTypeAlias)"/> new page</xsl:value-of></p>
</xsl:otherwise>
</xsl:choose>
Hi JV,
Steve is right, you ask for the value of a boolean test, so you're getting 'true' as output. Here's a simpler way to do it - note that I use variables extensively, which should make it easier for anyone reading it to grasp what's going on, but also to not be calling the extension methods more than once:
/Chriztian
Thanks Chriztian, that works really well.
How would I be able to do the same for "grandchild" nodes?
I've tried the following but it pulls in all descendants:
Hi JV,
With XPath there's usually more than one solution, depending on how specific you want to be - simplest thing would be:
/Chriztian
Hi Chriztian,
I've tried that, but it's pulling in all the descendants too.
These both result in the following example:
e.g. Section 1 - 20 pages - 22 new pages, Section 2 - 2 pages - 22 new pages
Hi JV,
If those two give you the same result, all your "DocTypeAlias" pages are placed two levels down from $currentPage - that's just how it works.
Did you use all of my code, or did you copy some of it? Note that I'm counting the $newPages variable, not the $nodes one...
Another thing could be that all the pages were in fact created within the last month?
Maybe you can share a little of the structure in Content to clear this up?
/Chriztian
Hi Chriztian,
I'm using it for an Image Library I'm creating, the Content structure is as follows:
Image Gallery
Image Gallery Album
Image Gallery Photo
Image Gallery Photo
Image Gallery Album
Image Gallery Photo
Image Gallery Photo
The Image Gallery displays a list of the child Image Gallery Albums, and displays how many Image Gallery Photo's are within each album and how many new images.
Below is the XSLT I'm using, I've copied your code but may not have it correct to allow for the split between New Images for each Image Gallery Album.
Ah yes, now I see :-)
Yeah, you just need to filter the $newPages variable and only count the ones inside the current gallery - should be something like this:
(replaces last <xsl:when> block in your code)
/Chriztian
Hi Chriztian,
I just tried that code, and it didn't show any results.
It would only show results when I changed it to this:
Which still gives me the total for all grandchildren. e.g. 22 New Images
Hi JV,
That seems strange, but let's get everything right then.
I rewrote this to use a couple of match templates instead, which is much easier to manage (I think) and this gives me the right values for total and new images, when I recreate the structure you describe (these replace that one "the fun starts here" template):
/Chriztian
Thanks very much Chriztian! That works fantastically well.
I just made one very small edit, so that "New Images" will only display if there is more than 0 "New Images":
Cheers!! JV
is working on a reply...