|
|
 Rank: Enthusiast
Joined: 6/7/2007 Posts: 18 Location: Copenhagen, Denmark
|
Could anyone help me with best practice on “how to” create an xslt that gets news items, no matter where they are in the node structure, as long as the conditions for being displayed on the front page is meet.
On the front page, I want to show latest 16 news items. The news items on the front page comes from all sections/subsections news items, order by create date and priority. When a section creates a news item, the section decides, by true/false, if the news item are to be shown on the front page. The property is showOnFrontpage.
Alias for the document type is newsItem. There are no limits for sections or subsections.
How can I create the xslt, so it gets the news items only for the front page?
Example of structure:
Frontpage -- Section 1 -- News area -- News item 1 -- News item 2 (priority) (showOnFrontpage) -- News item 3 (showOnFrontpage) -- Another area -- Another item 1 -- Section 2 -- News area -- News item 1 (priority) -- News item 2 (showOnFrontpage) -- News item 3 (priority) (showOnFrontpage) -- Subsection 2 -- News area -- News item 1 (priority) (showOnFrontpage) -- News item 2 -- News item 3 -- Another area -- Another item 1 -- Section 3 -- News area -- News item 1 (showOnFrontpage) -- News item 2 -- News item 3 (priority) (showOnFrontpage) -- Another area -- Another item 1 etc…
Thanks in advance.
/Finn
|
|
 Rank: Enthusiast
Joined: 6/7/2007 Posts: 18 Location: Copenhagen, Denmark
|
Sorry for the double posting. Hopefully the formatting stays this time!
Could anyone help me with best practice on “how to” create an xslt that gets news items, no matter where they are in the node structure, as long as the conditions for being displayed on the front page is meet.
On the front page, I want to show latest 16 news items. The news items on the front page comes from all sections/subsections news items, order by create date and priority. When a section creates a news item, the section decides, by true/false, if the news item is to be shown on the front page. The property is showOnFrontpage.
Alias for the document type is newsItem. There are no limits for sections or subsections.
How can I create the xslt, so it gets the news items only for the front page?
Example of structure:
Frontpage ---- Section 1 --------- News area ---------- News item1 ---------- News item 2 (priority) (showOnFrontpage) ---------- News item 3 (showOnFrontpage) -------- Another area ------------ Another item1 ---- Section 2 -------- News area ------------ News item1 (priority) ------------ News item 2 (showOnFrontpage) ------------ News item 3 (priority) (showOnFrontpage) ---------------- Subsection 2 -------------------- News area ------------------------- News item1 (priority) (showOnFrontpage) ------------------------- News item 2 ------------------------- News item 3 -------- Another area ------------ Another item1 ---- Section 3 -------- News area ------------ News item1 (showOnFrontpage) ------------ News item 2 ------------ News item 3 (priority) (showOnFrontpage) -------- Another area ------------ Another item1 Etc…
Thanks in advance.
/Finn
|
|
 Rank: Umbracoholic
Joined: 9/8/2006 Posts: 1,698 Location: KY, USA
|
Hi, Finn, Let me be sure I understand what you want to do. Basically, you want to select all the nodes of nodeTypeAlias='newsItem' where data[@alias='showOnFrontpage'] = '1' You then want to select the "best" ones to display by sorting the results by @createDate and then by data[@alias='priority']. Then, you want to show the first 16 news items. Is that correct? cheers, doug.
MVP 2007-2009 - Official Umbraco Trainer for North America - Percipient Studios
|
|
 Rank: Enthusiast
Joined: 6/7/2007 Posts: 18 Location: Copenhagen, Denmark
|
Hi Douglas
The 16 news items is sorted by create date and priority, meaning that for at given date the ones with priority is first.
Example:
news item 2 for 2008.02.05 10:22 (priority) news item 4 for 2008.02.05 14:32 news item 3 for 2008.02.05 10:22 news item 1 for 2008.02.05 08:14 news item 2 for 2008.02.04 14:22 (priority) news item 1 for 2008.02.04 10:32 (priority) news item 3 for 2008.02.04 12:22 news item 2 for 2008.02.04 08:14
Hope it makes sense.
/Finn
|
|
 Rank: Enthusiast
Joined: 6/7/2007 Posts: 18 Location: Copenhagen, Denmark
|
Hi again Douglas
I was a little quick on the reply button!
Besides the clarifying on sort order, you are correct on what I want to accomplish.
/Finn
|
|
 Rank: Umbracoholic
Joined: 9/8/2006 Posts: 1,698 Location: KY, USA
|
That's very clear, thanks. I'll work on it later tonight unless someone else gets to it first. cheers, doug.
MVP 2007-2009 - Official Umbraco Trainer for North America - Percipient Studios
|
|
 Rank: Umbracoholic
Joined: 9/8/2006 Posts: 1,698 Location: KY, USA
|
Hi, Finn, I believe this will do what you want. Code: <?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" exclude-result-prefixes="msxml umbraco.library"> <xsl:output method="xml" omit-xml-declaration="yes"/>
<xsl:param name="currentPage"/>
<xsl:variable name="documentTypeAlias" select="string('newsItem')"/> <xsl:variable name="numberOfItems" select="16"/>
<xsl:template match="/"> <ul> <xsl:for-each select="umbraco.library:GetXmlAll()/descendant-or-self::node [ @nodeTypeAlias=$documentTypeAlias and string(data[@alias='showOnFrontpage'] = '1') and string(data[@alias='umbracoNaviHide'] != '1') ]"> <xsl:sort select="umbraco.library:FormatDateTime(@createDate, 'yyy.MM.dd')" order="descending"/> <xsl:sort select="data[@alias='priority']" order="descending"/> <xsl:sort select="@createDate" order="descending"/>
<xsl:if test="position() <= $numberOfItems"> <li> <a href="{umbraco.library:NiceUrl(@id)}"> <xsl:value-of select="@nodeName"/> <br /> <xsl:value-of select="@nodeTypeAlias"/> for <xsl:value-of select="umbraco.library:FormatDateTime(@createDate, 'yyyy.MM.dd H:m')"/> (<xsl:value-of select="data[@alias='priority']"/>) </a> </li> </xsl:if> </xsl:for-each> </ul> </xsl:template>
</xsl:stylesheet>
If you're not overly familiar with XSLT then I'll point you to the GetAllXml() function built into umbraco, which gets all the nodes in your content tree. Then we narrow down the nodes to just those that interest us (they have the right nodeTypeAlias, they are flagged for showOnFrontpage, and they aren't hidden). Once we've got all the relevant nodes, it is time to sort them. This is where XSLT's syntax is a bit peculiar. You can only sort nodes when doing a for-each loop. That's fine, because we do want to cycle through all the nodes. The odd thing is that the sort command looks like it is "inside" the for-each, but really it is simply "after" the for-each and modifies the for-each itself. We sort first on the createDate, looking only at the year.month.day to organize the nodes by date. Then we sort by priority to put those flagged as priority at the top of the list of nodes for a given year.month.day. And finally, we sort them by the full createDate which includes the timestamp. Then it is a simple matter of showing the output in a ul/li list. I hope this makes sense and works well for you. cheers, doug.
MVP 2007-2009 - Official Umbraco Trainer for North America - Percipient Studios
|
|
 Rank: Enthusiast
Joined: 6/7/2007 Posts: 18 Location: Copenhagen, Denmark
|
Douglas, The force is definitely with you!
I’m amazed by the simplicity of your code and your remarks about how it all works and why. It’s easy to understand at manipulate further.
Thank you.
|
|
 Rank: Devotee
Joined: 1/10/2008 Posts: 75 Location: London
|
Yep, great example, thanks Doug ! I wish I had seen this GetAllXml function in use before :( Probably worth to add it in a book/wiki somewhere ? seb http://www.be-k.net
|
|
 Rank: Fanatic
Joined: 10/9/2006 Posts: 419
|
yeah, i don't think i have ever used GetXMLAll() before either...hmmmm Doug, once again... you show your amazing abilities to not only understand, but to teach the knowledge you possess to others... there really needs to be a permanent spot for you on the umbraco team... minister of information or something :)
bootnumlock - aka bob baty-barr [ http://www.baty-barr.com] Level 1 Certified!
|
|
Rank: Devotee
Joined: 10/25/2007 Posts: 59
|
You can also use an XPath expression to retrive all the elements, instead of using the umbraco.library:GetXmlAll() method. I don't know which performs best, or how umbraco is structured, but as far as I know XPath is the fastest way to access data on an XML document. I have reused Doug's example and only altered the select statement, which should look something like this. Code: <xsl:for-each select="$currentPage/ancestor-or-self::root/descendant-or-self::node [ @nodeTypeAlias=$documentTypeAlias and string(data[@alias='showOnFrontpage'] = '1') and string(data[@alias='umbracoNaviHide'] != '1') ]"> <xsl:sort select="umbraco.library:FormatDateTime(@createDate, 'yyy.MM.dd')" order="descending"/> <xsl:sort select="data[@alias='priority']" order="descending"/> <xsl:sort select="@createDate" order="descending"/> <xsl:if test="position() <= $numberOfItems"> <li> <a href="{umbraco.library:NiceUrl(@id)}"> <xsl:value-of select="@nodeName"/> <br /> <xsl:value-of select="@nodeTypeAlias"/> for <xsl:value-of select="umbraco.library:FormatDateTime(@createDate, 'yyyy.MM.dd H:m')"/> (<xsl:value-of select="data[@alias='priority']"/>) </a> </li> </xsl:if> </xsl:for-each> You can read more about this on w3schools.com. Hope you can use it :o) Cheers, Kim
|
|
|
Guest |