Which format is the PostDate property? Could it be cased wrong? (E.g.: Usually, if you enter "Post Date" as the property name, the alias will be "postDate").
The problem is not there, that part of the code works fine.
The problem is that the posts get filtered for a unique author before they are being sorted by the post date. The very first posts of the authors make it through the filter and THEN, they are being sorted - which is not very helpful.
I need to first sort ALL posts by the date and THEN filter out the posts with distinct authors.
Looks good, it works. But when new posts appear, they don't go on top of the page, they just replace the previous post from that author. I shall try something out...
Yeah - I was going to put a line in about the way you'd sort the authors at first, but didn't bother - e.g., when you have 10 unique authors, but only showing a max. of 5 posts - that wouldn't go on right...
I think you need to build an intermediate result of all the authors' latest post, and then display the latest X of those:
<xsl:key name="CreatorByName" match="@creatorName" use="." />
<xsl:key name="PostByCreator" match="umbBlogPost" use="@creatorName" />
<xsl:variable name="blogRoot" select="$currentPage/ancestor-or-self::umbBlog" />
<!-- Collect the latest post by each individual author -->
<xsl:variable name="latestPostByCreatorProxy">
<xsl:for-each select="$blogRoot//umbBlogPost/@creatorName[generate-id() = generate-id(key('CreatorByName', .)[1])]">
<xsl:for-each select="key('PostByCreator', .)">
<xsl:sort select="PostDate" data-type="text" order="descending" />
<!-- Store a reference to the latest post by this author -->
<xsl:if test="position() = 1">
<post id="{@id}" creatorName="{@creatorName}" postDate="{PostDate}" />
</xsl:if>
</xsl:for-each>
</xsl:for-each>
</xsl:variable>
<xsl:variable name="latestPostByCreator" select="msxsl:node-set($latestPostByCreatorProxy)" />
<!-- Display the posts by grabbing the real nodes by id -->
<xsl:for-each select="$latestPostByCreator/post">
<xsl:sort select="@postDate" data-type="text" order="descending" />
<xsl:call-template name="showpost">
<xsl:with-param name="post" select="$blogRoot//umbBlogPost[@id = current()/@id]" />
</xsl:call-template>
</xsl:for-each>
I have gone over it many times by now and I can not find any outer circumstances that affect it.
The code you showed definitely makes sense but I have no idea why it would not work. I have tried making changes to it, but anything I do leads to nonsense display on the homepage which is nowhere near what I want to display.
Tthis is the closest I have got so far... The correct posts show but they repeat just as many times as the number of posts from that author.
I have 3 authors at the moment (A1 has 10 posts, A2 has 2 posts and A3 has 1 post) and right now my homapage looks like this:
- 10x latest post from A1
- 2x latest post from A2
- 3x latest post from A3
I think the inner foreach loop from the proxy should only loop once but I have no idea how to make it do that... Alo, all posts have some javascript, however, whichever post I click, it triggers the script from the first one.
Please help me out a bit on this, I can feel I am so close...
At the point where you say "MAKE IT LOOP ONLY ONCE" it actually needs to take all the creator's posts, because we need to sort them to be able to get the 1st one (i.e., the latest).
Could you try to dump the contents of the $latestPostByCreator variable after its created? Like this:
I can see the <for-each> just above the "MAKE IT LOOP..." comment has been changed from my example - that's where you need to do the key() + generate-id() thing, to make sure we only run through unique @creatorName attributes...
I dumped it all in a textarea and it shows many copies of the latest post, just like my homepage currently does.
I had fiddled with your example, yes trying to figure out where could the problem be. If I use the example exactly as you gave it, i would only get only the post from the author that has one post.
This is how your example looks like with the variable dumped into a textarea:
Also, I get the same post 3 times on 3 different pages - as you can see I swap to pages with older posts where the same post shows up. I have done it so you can only swap to older posts IF there are more than 5 posts on the page.
So we found a solution - the problem was that selecting attributes with a key() and using generate-id() for those didn't produce predictable results.
Changing to use the PostByCreator key instead (which selects elements instead of attributes) made it work as intended - so here's the final changed section that creates an XML variable with the latest post by each individual author (only lines 2 + 3 were changed):
Using a key
Hello,
I am trying to use a key in order to only display posts from distinct authors on the homepage of my blog.
This is how I do it and it works peorperly:
The problem is: I would like to display the LATEST posts from the authors, not the oldest ones.
Any suggestions?
Hi Alexandru,
Which format is the PostDate property? Could it be cased wrong? (E.g.: Usually, if you enter "Post Date" as the property name, the alias will be "postDate").
/Chriztian
The problem is not there, that part of the code works fine.
The problem is that the posts get filtered for a unique author before they are being sorted by the post date. The very first posts of the authors make it through the filter and THEN, they are being sorted - which is not very helpful.
I need to first sort ALL posts by the date and THEN filter out the posts with distinct authors.
Do I make sense?
Ha - yes, of course :-)
Okay - that's a good challenge... I'd say something like this should do it:
/Chriztian
Looks good, it works. But when new posts appear, they don't go on top of the page, they just replace the previous post from that author. I shall try something out...
For example:
I have 3 authors.
Your solution would have their latest posts printed out this order:
When author 1 writes a new post, the order on the homepage will still be like this:
I need it to be like this:
Makes sense? :)
Hi Alexandru,
Yeah - I was going to put a line in about the way you'd sort the authors at first, but didn't bother - e.g., when you have 10 unique authors, but only showing a max. of 5 posts - that wouldn't go on right...
I think you need to build an intermediate result of all the authors' latest post, and then display the latest X of those:
Let me know id it works at all :-)
/Chriztian
Hi, thanks for this, I shall try it out now as I have been away from the office yesterday. I'll get back to you with a result!
I seem to be getting only one post from one author so far...
I can't figure out where it goes wrong. I think it only loops once through the first for-each loop
Hmm - I have this (isolated example) working correct here, so would maybe need to check if outer circumstances could be affecting it?
/Chriztian
I have gone over it many times by now and I can not find any outer circumstances that affect it.
The code you showed definitely makes sense but I have no idea why it would not work. I have tried making changes to it, but anything I do leads to nonsense display on the homepage which is nowhere near what I want to display.
Is there any other way around this?
Tthis is the closest I have got so far... The correct posts show but they repeat just as many times as the number of posts from that author.
I have 3 authors at the moment (A1 has 10 posts, A2 has 2 posts and A3 has 1 post) and right now my homapage looks like this: - 10x latest post from A1 - 2x latest post from A2 - 3x latest post from A3
This is the code:
I think the inner foreach loop from the proxy should only loop once but I have no idea how to make it do that... Alo, all posts have some javascript, however, whichever post I click, it triggers the script from the first one.
Please help me out a bit on this, I can feel I am so close...
Hi Alexandru,
At the point where you say "MAKE IT LOOP ONLY ONCE" it actually needs to take all the creator's posts, because we need to sort them to be able to get the 1st one (i.e., the latest).
Could you try to dump the contents of the $latestPostByCreator variable after its created? Like this:
This should hold a single
<post>
element for each creator.../Chriztian
I can see the
<for-each>
just above the "MAKE IT LOOP..." comment has been changed from my example - that's where you need to do thekey()
+generate-id()
thing, to make sure we only run through unique@creatorName
attributes...I dumped it all in a textarea and it shows many copies of the latest post, just like my homepage currently does.
I had fiddled with your example, yes trying to figure out where could the problem be. If I use the example exactly as you gave it, i would only get only the post from the author that has one post.
This is how your example looks like with the variable dumped into a textarea:
Also, I get the same post 3 times on 3 different pages - as you can see I swap to pages with older posts where the same post shows up. I have done it so you can only swap to older posts IF there are more than 5 posts on the page.
Alright,
I'd love to help you out - but I think I need to look at the full XSLT file now, to get an idea.
Feel free to email me at chriztian @ steinmeier [dot] dk, if it's not super-sensitive client stuff that you've signed several NDA's for :-)
We can post the final solution(s) here again when finished so others don't get here in vain...
/Chriztian
Okay, I have sent you an email :)
So we found a solution - the problem was that selecting attributes with a
key()
and usinggenerate-id()
for those didn't produce predictable results.Changing to use the PostByCreator key instead (which selects elements instead of attributes) made it work as intended - so here's the final changed section that creates an XML variable with the latest post by each individual author (only lines 2 + 3 were changed):
/Chriztian
Thank you so much for this!
Have a good day!
Chriztian,
I have come across a new issue with this and I was hoping I could get your help again as I can't seem to fix it myself.
My blog now supports scheduled posts which means that you can publish posts with a future date and this messes up the way my homepage works.
What I need to do is add a filter that only looks through posts that fit this condition:
I have tried adding this condition to the first foreach predicate in the above code but it didn't work. Any ideas why?
Hi Alexandru,
You would want to add that condition where you're running through each author's posts, i.e. in the second for-each of the variable:
/Chriztian
Aye, thanks!
is working on a reply...