Better way to get the 8 or so most recent blog posts?
Perf on this stinks. Looking at it, no wonder why. The xslt iterates through all the blog posts (I currently have over 500) just to get the most recent 8. Is there a better way to do this?
<!-- This is super brittle. I hate having the ID in here. Need to find another way. Get the ID from the Blog node properties on the content page --> <xsl:variable name="blogPosts" select="umbraco.library:GetXmlNodeById(1163)/descendant-or-self::node [@nodeTypeAlias = 'Blog']//node [@nodeTypeAlias = 'BlogPost']" />
If you know you are doing more than 8 posts per month (or week/day etc) then you could further reduce your blogposts variable by only getting posts for the last month by createdate.
It's not the most subtle solution but I don't believe there is any way to break out of the for-each loop like you would in c#.
That works, but breaks down when you're near the start of the month (you'd need to add in the previous month too), and then the odd slow months etc. Good idea though.
I'm thinking I should just go write a utility lib function in C# and have it do some sql to handle this.
This site was down, so I posted my solution to the codeplex forums. Interested in validation on the sql as well as if there's a nice generic way to get the right document type (or if hard-coding it is correct). Here's the post:
public static XPathNodeIterator GetLatestPosts(int count) { // get the blog doctype. Hard coding this is probably not a good idea, but will work for my blog umbraco.cms.businesslogic.web.DocumentType docType = umbraco.cms.businesslogic.web.DocumentType.GetByAlias("BlogPost");
if (docType == null) throw new Exception("Unable to find document type for BlogPost alias");
As addition to this, you can easily extend your variable to check against the createDate as well. You can either use the Exslt or the date functions in the umbraco.library. This will help reduce the number of nodes you get in your variable.
For example:
Add this to the top of the xslt: xmlns:date="urn:Exslt.ExsltDatesAndTimes"
the variable startdate gets filled with (today minus 2 months). You can adjust the -P2M parameter to suit your needs if you need a smaller or wider timeframe
Wait, so, when umbraco starts up, it loads all the documents into memory? That explains why I have such a long startup time -- and my site is only half-populated.
Has anyone tried this with hundreds or thousands of documents?
In the devloper section, open the "macros" tree and select the macro that relates to this piece of xslt. It is from here that you can control cache options such as "cache time", "cache per page" etc. With a piece of xslt like this you could afford a long cache time.
As for large sites, conde naste use umbraco for some fairly large sites (wired.co.uk being the most notable). The biggest we've used has well over 10000 nodes with no real slowdown. Once the xml is loaded into memory it should be fairly snappy.
I can't for the life of me figure out how to get the Blog folder that sits off the root. The xpath doesn't work because the Blog folder is not a child of the home page, it's a sibling under Content. Here's how my tree looks:
Content
|- Home (the macro is run from here - the xpath returns this node)
|- Blog (can't figure out the xpath to return this node)
|--- 2010
|-----2
|-------24
|--------- Blog Post 1
|--------- Blog Post 2
|-------25
|--------- Blog Post 3
|--------- Blog Post 4
|--------- Blog Post 5
I don't count xpath/xslt among my strong skills, so I may have missed something obvious, but is there a way to get to a sibling og the home page to find the Blogs folder? Searching on the forums here and in general xslt sites isn't yielding anything useful.
Looking at other posts here, I think that's er... the root of my problem. I'm going to change the structure of my site a bit so I really end up with a single "site" root with everything under it.
Send ninjas to my house if I'm going about this the wrong way :)
That just didn't work, as the home page was not the parent of the blog folder (the query always came back empty). I've changed the structure of the site so now it is the root and it's working.
Better way to get the 8 or so most recent blog posts?
Perf on this stinks. Looking at it, no wonder why. The xslt iterates through all the blog posts (I currently have over 500) just to get the most recent 8. Is there a better way to do this?
If you know you are doing more than 8 posts per month (or week/day etc) then you could further reduce your blogposts variable by only getting posts for the last month by createdate.
It's not the most subtle solution but I don't believe there is any way to break out of the for-each loop like you would in c#.
Cheers
Paul
Thanks.
That works, but breaks down when you're near the start of the month (you'd need to add in the previous month too), and then the odd slow months etc. Good idea though.
I'm thinking I should just go write a utility lib function in C# and have it do some sql to handle this.
Pete
This site was down, so I posted my solution to the codeplex forums. Interested in validation on the sql as well as if there's a nice generic way to get the right document type (or if hard-coding it is correct). Here's the post:
http://blog4umbraco.codeplex.com/Thread/View.aspx?ThreadId=178688
And here's the code I added to BlogLibrary.cs
It appears to work fine (and is pretty fast).
Pete
I am very surprised that it would be faster to go to the db instead of working directly with xslt since alle the xml is in memory.
What happens if you change this
with this
You may need to cange the @level = '1' to match your needs.
This would avoid the GetXmlNodeById() call.
Also, you can move the position() inside the initial selector, instead of testing within the loop, e.g.
Not sure how much of a performance boost that may be tbh...
With a macro like this, you could also get away with caching it pretty aggressively. That should help massively with any speed problems.
Dan
As addition to this, you can easily extend your variable to check against the createDate as well. You can either use the Exslt or the date functions in the umbraco.library. This will help reduce the number of nodes you get in your variable.
For example:
Add this to the top of the xslt: xmlns:date="urn:Exslt.ExsltDatesAndTimes"
Then:
the variable startdate gets filled with (today minus 2 months). You can adjust the -P2M parameter to suit your needs if you need a smaller or wider timeframe
HTH,
Peter
Wait, so, when umbraco starts up, it loads all the documents into memory? That explains why I have such a long startup time -- and my site is only half-populated.
Has anyone tried this with hundreds or thousands of documents?
@Dan how can I control caching for this xslt?
Pete
In the devloper section, open the "macros" tree and select the macro that relates to this piece of xslt. It is from here that you can control cache options such as "cache time", "cache per page" etc. With a piece of xslt like this you could afford a long cache time.
As for large sites, conde naste use umbraco for some fairly large sites (wired.co.uk being the most notable). The biggest we've used has well over 10000 nodes with no real slowdown. Once the xml is loaded into memory it should be fairly snappy.
Dan
@dan
excellent, thanks.
Pete
@Morten
I can't for the life of me figure out how to get the Blog folder that sits off the root. The xpath doesn't work because the Blog folder is not a child of the home page, it's a sibling under Content. Here's how my tree looks:
Content
|- Home (the macro is run from here - the xpath returns this node)
|- Blog (can't figure out the xpath to return this node)
|--- 2010
|-----2
|-------24
|--------- Blog Post 1
|--------- Blog Post 2
|-------25
|--------- Blog Post 3
|--------- Blog Post 4
|--------- Blog Post 5
I don't count xpath/xslt among my strong skills, so I may have missed something obvious, but is there a way to get to a sibling og the home page to find the Blogs folder? Searching on the forums here and in general xslt sites isn't yielding anything useful.
Thanks.
Pete
Looking at other posts here, I think that's er... the root of my problem. I'm going to change the structure of my site a bit so I really end up with a single "site" root with everything under it.
Send ninjas to my house if I'm going about this the wrong way :)
Pete
No need to. Have you checked my post?
Here's a full working example:
The variable holds todays-date minus 2 months (if you have few posts per months, you could extend this, change the -P2M into -P3M for 3 months)
HTH,
Peter
Also, you might want to read this page about xpaths:
http://our.umbraco.org/wiki/reference/xslt/xpath-axes-and-their-shortcuts
I saw a different one yesterday, but was unable to find it right now :(
Moving my site to a better structure (with the root folder being the "home page") has made this and some other things just work.
I'm still not satisfied with perf on generating that list of blog posts, but I'll work on it some more, plus add in caching once perf is acceptable.
Pete
@peter
That just didn't work, as the home page was not the parent of the blog folder (the query always came back empty). I've changed the structure of the site so now it is the root and it's working.
Pete
Hm, I created a similar setup to yours:
Content
-Home
-Blog
Worked fine on my site, it showed the blog-items on the homepage.
Glad you have it working though.
Just for reference, it is possible to get to the root by doing this:
The xml we are parsing looks like this:
And you can always see that xml in your /data/umbraco.config file
is working on a reply...