Monday, October 6, 2008

MOSS Creating Custom News Page Layouts

Update: Corrected the HTML markup in the article.



Recently I did a CMS 2002 to MOSS migration. The project had enough challenges to be a good learning experience. I will be posting snippets of that knowledge here for others to use. This article is posted by my guest writer and friend Mike Dockery.


This article refers to the need to create custom News page layouts in SharePoint 2007 and surface the news articles (or any other kind of information from a list using CBQ).





Create custom content types to attach new page layouts to be used for creating news articles on a Publishing site that will be served up with unique styles in the Content Query web part. For reference, see http://blogs.msdn.com/markarend/archive/2006/07/25/678445.aspx

1. Custom Content Type
From the site collection level site settings, click Site content types.
Browse the gallery and check that no custom content types happen to already be created under Page Layout Content Types.
Click Create for this New Site Content Type.
For Name, call it Vanguard QTC News Article
For Description, enter a variation of: This is a Content Type to create news articles for Quote to Cash that will be rolled up into Vanguard news aggregators.
For its parent type select Article Page.
Select parent content type from the Page Layout Content Types
Put this into the IHS Content group. If this is the first member of the group, then you will have to make a New group with this name.
Click OK.
Recreate the different content types as needed.

2. Custom Page Layouts
Using SharePoint Designer, open the site collection, then open the MasterPageGallery (in the _catalogs folder). Copy one or more layout files and rename the copies as in the following sample:

Existing layout file Copied layout file
ArticleLeft.aspx IHSArticle.aspx

Associate with Custom Content Type
After copying the custom layouts, associate the custom content type with each one. From the top-level Site Settings, click Master Page and Page Layout link under Galleries, and you should see the new custom layouts that were added. Edit the properties of each one to set the associated content type; select the custom type that you created.

Content Type should be set to Page Layout
Name will be the filename as copied in the previous step.
The Title property is the string that will appear on the page layout when a user edits the page to create or modify news. For example: IHS news article page with optional image at left.
The Description property is the string that appears when people are choosing the format for their news article. For example: This is an approved layout for IHS news articles.
The Associated Content Type property should be set to the custom content type that you created which will allow the news aggregator (CQWP) to find this article quickly: IHS Content
For Content Type Name, select the new site content type: IHS News Article
Click OK.
Check in and publish a major version.
Approve the page.

3. Customize the Page Layout
At this point, you don’t have to do any further customization in order for the news aggregation scenario to work. But ...

Add a Description Control
The Content Query web part that is used as a news aggregator has several different viewing formats available. Several of these show the Description property of the news article page. Unfortunately, there is not a control to enter the description on the page layout; to modify this out-of-box you have to edit the properties from the page library view. But we can easily add a control to the page layout to provide an input field for the description property, and this makes it much more useful for people writing news articles to show an abstract for the article.

The new ASPX page should still be checked out. Open the file in SharePoint Designer. Edit each of the copied layout files (if more than one) and add two items in Code view: a NoteField control for the Description field, and an EditModePanel to show instructions for the Description field.

Locate <[Start div tag] class="pageContent">. Just above this before the <[End table tag]>, insert these controls into a new row in the table containing the date and byline.

<tr>
<td align="right" valign="middle">
<PublishingWebControls:editmodepanel runat="server" id="editmodepanel2">
<div class="editModePanel" width=40% align="right">
<!-- Should be description text in resource string -->
Description--›<BR/>is shown by news aggregators (Content Query Web Parts)
with this abstract.
</div>
</PublishingWebControls:editmodepanel>
</td>
<td width="100%" class="byLine">
<SharePointWebControls:NoteField FieldName="Description" runat="server"/>
</td>
</tr>

Save the custom article page. Close SPD. Back through the interface, check the file in.
At this point, you are ready to create new pages with this layout.

Create a new page with this layout
This step is an example, it is not necessary to create the masters. Go to a site in the hierarchy of the portal that has the Publishing feature activated. By default, the Corporate Intranet Site and the Team Publishing Site have this feature, but it is easy to activate for other sites as well. Through Site Settings > Site features > Office SharePoint Server Publishing, then click Activate.
Under Site Actions, click Create Page.
Enter the Title of the article.
Leave Description blank for now.
For URL Name, the system will automatically populate it with the article title. Change it and shorten it depending on the actual title. Remove special characters.
Select the new custom layout: IHS News Article
For Page Layout, you must choose one of the following Content Types depending on the article and where you want it displayed in the roll up web parts:
IHS Colleague Announcements
IHS Engineering News
IHS Leadership Team Messages
IHS News Article
Click Create.
The new article will be in edit mode.
The Description section is important because this is what will be the short abstract shown within the Content Query Web Part. Insert meaningful text that summarizes the article. This must not exceed 255 characters.
Enter the Article Date and Byline.
In the Page Content section -- the primary content -- click Edit Content or the "Click here to add new content" link. Insert the text or else use the rich text editor to format the article.
Rollup Image will output in the Content Query Web Part as a little 50 pixel square image next to the description/abstract. Ensure the image is small and legible.
Click Publish to make the article available. If you need to edit the existing article, open the article, click Edit Page. Click Publish when finished.
4. CQWP Style Output Examples
IHSwwitTwoColumn
Title linked in blue and 'read more' in orange.



IHScomSingleCreated
Full date, Title and 'more' linked in blue


IHSNewsTwoColumn
Date, Title linked in black, arrows linked in blue, and right line between 2 articles.



NewsTwoColumnOrange
Full date in small text, Title linked in blue, 'more' linked in orange, and right line between 2 articles.






5. Customizing the ItemStyle.xsl for CQWP
From the top site of the site collection, browse All Site Content or Content and Structure. Open the Style Library. Get into the XSL Styles Sheets folder.




Click the context menu for ItemStyle to Send To and choose Download a copy and save it to your desktop. Please make a backup of the file right away! Versioning is on by default in the Style Library but it’s sometimes easier to quickly upload the original file if things go awry in the XSL editing (don’t worry, you’ll error out at some point!).
A great reference is found in “Customizing the Content Query Web Part XSL” (http://www.microsoft.com/belux/msdn/nl/community/columns/stevenvandecraen/contentquerywebpart.mspx) on MSDN.
1. Open ItemStyle.xsl in any text editor or SPD.
2. At the top alongside the other attributes, add the ddwrt namespace which will handle using dates.
xmlns:ddwrt="http://schemas.microsoft.com/WebParts/v2/DataView/runtime"
3. Scroll down in the file and copy any existing
4. Begin to edit the copied template by first changing the name and match attributes to be unique. The name will be selectable in the Item Style section when editing the CQWP.
5. Add a Created variable that will display that date in the web part for each article. This is using the internal column name. How do find out how to get the internal column names? See Heather Solomon’s blog (http://www.heathersolomon.com/blog/articles/CustomItemStyle.aspx) and this MSDN Forum (http://forums.msdn.microsoft.com/en-US/sharepointcustomization/thread/6328a12c-6c15-4c98-a997-e5e7104706c3/) for further details.
1033 refers to English. (1031 German, 1036 French,1040 Italian, 1034 Spanish, 1049 Russian, 1043 Dutch)
MM/dd/yyyy is an example of the output of the date format. Some options:
MMM dd, yyyy -- Oct 11, 2008
MMMM dd, yyyy -- October 11, 2008
MM/dd/yyyy -- 10/11/2008.
dd/MM/yyyy -- 11/10/2008
6. In our example, we will output the Date above the Title. The title will be linked to the published article page. There will be a brief article synopsis that pulls from the article's Description. Finally, a "more" link that also links to the full article.
The actual output will be contained within the
7. Wrap the Created variable in its own Div right after the being Div for "link-item". This will be the article date. (Leave the CallPresenceStatusIconTemplate).
Adjust the font styles, colors, alignment and other CSS attributes using HTML tags. Be careful in this section and test after small changes to be sure you don’t crash the page.
8. For the DisplayTitle variable, surround it with the link tag and add in the style attribute to color it any way you choose:
9. The Description will display on a new line, followed by the "more" link and lastly, the end Div tag for the "link-item" class.
10. To output the "more" link in different languages, simply get the translation for the word(s) you need, be it "read more", "full article" or whatever. If the translation has special characters you will need to use the ASCII representation. The easiest method is to paste in the translated text into Microsoft Word, save the page as an HTML page then open up that page in a text editor to get the ASCII code. For "more", the translations are listed below in the following snippets as they should appear in the XSL file:
German
sans-serif;color:#003399;">... mehr
French
sans-serif;color:#003399;">... plus
Italian
sans-serif;color:#003399;">... più
Spanish
sans-serif;color:#003399;">... más
Russian
sans-serif;color:#003399;">... подробнее
Dutch
sans-serif;color:#003399;">... meer
11. Save the file and upload it back to the Style Library, add in comments and check in the file.
12. Open up the site where you placed the imported Content Query Web Part.
13. From the Site Actions menu, click Edit Page.
14. Modify the CQWP and expand Presentation.
15. In the Styles section, leave the Group style as Default and for Item style select your new template name from the XSL file.




16. Exit Edit mode and view the final result:




Here are all the styles used for this blog post.


<xsl:template name="IHSwwitTwoColumn" match="Row[@Style='IHSwwitTwoColumn']" mode="itemstyle">
<xsl:variable name="Created">
<xsl:value-of select="ddwrt:FormatDateTime(string(@Created), 1033, 'MMMM dd, yyyy')" />
</xsl:variable>
<xsl:variable name="SafeImageUrl">
<xsl:call-template name="OuterTemplate.GetSafeStaticUrl">
<xsl:with-param name="UrlColumnName" select="'ImageUrl'"/>
</xsl:call-template>
</xsl:variable>
<xsl:variable name="SafeLinkUrl">
<xsl:call-template name="OuterTemplate.GetSafeLink">
<xsl:with-param name="UrlColumnName" select="'LinkUrl'"/>
</xsl:call-template>
</xsl:variable>
<xsl:variable name="DisplayTitle">
<xsl:call-template name="OuterTemplate.GetTitle">
<xsl:with-param name="Title" select="@Title"/>
<xsl:with-param name="UrlColumnName" select="'LinkUrl'"/>
</xsl:call-template>
</xsl:variable>
<xsl:variable name="LinkTarget">
<xsl:if test="@OpenInNewWindow = 'True'" >_blank</xsl:if>
</xsl:variable>
<div id="linkitem" class="item">
<xsl:if test="string-length($SafeImageUrl) != 0">
<div class="image-area-left">
<a href="{$SafeLinkUrl}" target="_blank">
<img border="0" width="50" src="{$SafeImageUrl}" alt="{@ImageUrlAltText}"/>
</a>
</div>
</xsl:if>
<div class="link-item">
<xsl:call-template name="OuterTemplate.CallPresenceStatusIconTemplate"/>
<a href="{$SafeLinkUrl}" title="{@LinkToolTip}" style="font:bold 12px arial,helvetica,tahoma,sans-serif;color:#003399;">
<xsl:value-of select="$DisplayTitle"/>
</a>
<div class="description" style="font:normal 12px arial,helvetica,tahoma,sans-serif;color:#000000;">
<xsl:value-of select="@Description"/>
<a href="{$SafeLinkUrl}" title="{@LinkToolTip}" style="padding-left:5px;font:normal 12px arial,helvetica,tahoma,sans-serif;color:#D27C26;">... read more</a>
</div>
</div>
</div>
</xsl:template>



<xsl:template name="IHScomSingleCreated" match="Row[@Style='IHScomSingleCreated']" mode="itemstyle">
<xsl:variable name="Created">
<xsl:value-of select="ddwrt:FormatDateTime(string(@Created), 1033, 'MMMM dd, yyyy')" />
</xsl:variable>
<xsl:variable name="SafeImageUrl">
<xsl:call-template name="OuterTemplate.GetSafeStaticUrl">
<xsl:with-param name="UrlColumnName" select="'ImageUrl'"/>
</xsl:call-template>
</xsl:variable>
<xsl:variable name="SafeLinkUrl">
<xsl:call-template name="OuterTemplate.GetSafeLink">
<xsl:with-param name="UrlColumnName" select="'LinkUrl'"/>
</xsl:call-template>
</xsl:variable>
<xsl:variable name="DisplayTitle">
<xsl:call-template name="OuterTemplate.GetTitle">
<xsl:with-param name="Title" select="@Title"/>
<xsl:with-param name="UrlColumnName" select="'LinkUrl'"/>
</xsl:call-template>
</xsl:variable>
<xsl:variable name="LinkTarget">
<xsl:if test="@OpenInNewWindow = 'True'" >_blank</xsl:if>
</xsl:variable>
<div id="linkitem" class="item">
<xsl:if test="string-length($SafeImageUrl) != 0">
<div class="image-area-left">
<a href="{$SafeLinkUrl}" target="_blank">
<img class="image-fixed-width" src="{$SafeImageUrl}" alt="{@ImageUrlAltText}"/>
</a>
</div>
</xsl:if>
<div class="link-item">
<xsl:call-template name="OuterTemplate.CallPresenceStatusIconTemplate"/>
<div style="margin:15px 0 0 0;font:normal 12px helvetica,arial,tahoma,sans-serif;color:#003399;">
<xsl:value-of select="$Created"/>
</div>
<a href="{$SafeLinkUrl}" title="{@LinkToolTip}" style="font:bold 12px helvetica,arial,tahoma,sans-serif;color:#003399;">
<xsl:value-of select="$DisplayTitle"/>
</a>
<div class="description" style="font:normal 12px helvetica,arial,tahoma,sans-serif;color:#000000;">
<xsl:value-of select="@Description"/>
<a href="{$SafeLinkUrl}" title="{@LinkToolTip}" style="padding-left:5px;font:normal 12px helvetica,arial,tahoma,sans-serif;color:#003399;">... more</a>
</div>
</div>
</div>
</xsl:template>




<xsl:template name="IHSNewsTwoColumn" match="Row[@Style='IHSNewsTwoColumn']" mode="itemstyle">
<xsl:param name="CurPos" />
<xsl:variable name="Created">
<xsl:value-of select="ddwrt:FormatDateTime(string(@Created) ,1033 ,'MM.dd.yyyy')" />
</xsl:variable>
<xsl:variable name="SafeLinkUrl">
<xsl:call-template name="OuterTemplate.GetSafeLink">
<xsl:with-param name="UrlColumnName" select="'LinkUrl'"/>
</xsl:call-template>
</xsl:variable>
<xsl:variable name="SafeImageUrl">
<xsl:call-template name="OuterTemplate.GetSafeStaticUrl">
<xsl:with-param name="UrlColumnName" select="'ImageUrl'"/>
</xsl:call-template>
</xsl:variable>
<xsl:variable name="DisplayTitle">
<xsl:call-template name="OuterTemplate.GetTitle">
<xsl:with-param name="Title" select="@Title"/>
<xsl:with-param name="UrlColumnName" select="'LinkUrl'"/>
</xsl:call-template>
</xsl:variable>
<xsl:variable name="LinkTarget">
<xsl:if test="@OpenInNewWindow = 'True'" >_blank</xsl:if>
</xsl:variable>
<div style="padding:0 10px 3px 20px;width:100%;border-left:1px solid #ffffff !important;border-left:1px solid #cccccc;">
<xsl:if test="$CurPos mod 2 &gt; 0">
<xsl:attribute name="style">
float:left;padding:0 10px 3px 3px;width:50%;
</xsl:attribute>
</xsl:if>

<xsl:if test="string-length($SafeImageUrl) != 0">
<div class="image-area-left">
<a href="{$SafeLinkUrl}" target="_blank">
<img class="image" src="{$SafeImageUrl}" alt="{@ImageUrlAltText}" />
</a>
</div>
</xsl:if>

<div class="link-item">
<xsl:call-template name="OuterTemplate.CallPresenceStatusIconTemplate"/>
<span style="font:bold 12px arial,helvetica,tahoma,verdana,sans-serif;">
<xsl:value-of select="$Created"/>
</span><br />
<a href="{$SafeLinkUrl}" target="_blank" title="{@LinkToolTip}" style="font:bold 12px arial,helvetica,tahoma,verdana,sans-serif;color:#000000;">
<xsl:value-of select="$DisplayTitle"/>
</a>
<div class="description" style="font:normal 12px arial,helvetica;color:#000000;padding-right:45px !important;padding-right:0;">
<xsl:value-of select="substring(@Description, 0, 235)" />
<a href="{$SafeLinkUrl}" target="_blank" title="{@LinkToolTip}" style="padding-left:5px;font:normal 14px arial,helvetica,tahoma,verdana,sans-serif;color:#3190D0;">&gt;&gt;</a>
</div>
</div>
</div>
</xsl:template>


<xsl:template name="NewsTwoColumnOrange" match="Row[@Style='NewsTwoColumnOrange']" mode="itemstyle">
<xsl:param name="CurPos" />
<xsl:variable name="Created">
<xsl:value-of select="ddwrt:FormatDateTime(string(@Created), 1033, 'MMMM dd, yyyy')" />
</xsl:variable>
<xsl:variable name="SafeLinkUrl">
<xsl:call-template name="OuterTemplate.GetSafeLink">
<xsl:with-param name="UrlColumnName" select="'LinkUrl'"/>
</xsl:call-template>
</xsl:variable>
<xsl:variable name="SafeImageUrl">
<xsl:call-template name="OuterTemplate.GetSafeStaticUrl">
<xsl:with-param name="UrlColumnName" select="'ImageUrl'"/>
</xsl:call-template>
</xsl:variable>
<xsl:variable name="DisplayTitle">
<xsl:call-template name="OuterTemplate.GetTitle">
<xsl:with-param name="Title" select="@Title"/>
<xsl:with-param name="UrlColumnName" select="'LinkUrl'"/>
</xsl:call-template>
</xsl:variable>
<xsl:variable name="LinkTarget">
<xsl:if test="@OpenInNewWindow = 'True'" >_blank</xsl:if>
</xsl:variable>
<div style="padding:0 10px 3px 20px;width:100%;border-left:1px solid #ffffff !important;border-left:1px solid #cccccc;">
<xsl:if test="$CurPos mod 2 &gt; 0">
<xsl:attribute name="style">
float:left;padding:0 10px 3px 3px;width:50%;
</xsl:attribute>
</xsl:if>

<xsl:if test="string-length($SafeImageUrl) != 0">
<div class="image-area-left">
<a href="{$SafeLinkUrl}" target="_blank">
<img class="image" src="{$SafeImageUrl}" alt="{@ImageUrlAltText}" />
</a>
</div>
</xsl:if>

<div class="link-item">
<xsl:call-template name="OuterTemplate.CallPresenceStatusIconTemplate"/>
<div style="margin:15px 0 0 0;font:normal 12px helvetica,arial,tahoma,sans-serif;color:#555;">
<xsl:value-of select="$Created"/>
</div>
<a href="{$SafeLinkUrl}" title="{@LinkToolTip}" style="font:bold 12px helvetica,arial,tahoma,sans-serif;color:#003399;">
<xsl:value-of select="$DisplayTitle"/>
</a>
<div class="description" style="font:normal 12px arial,helvetica;color:#000000;padding-right:45px !important;padding-right:0;">
<xsl:value-of select="@Description"/>
<a href="{$SafeLinkUrl}" title="{@LinkToolTip}" style="padding-left:5px;font:normal 12px helvetica,arial,tahoma,sans-serif;color:#D27C26;">... more</a>
</div>
</div>
</div>
</xsl:template>



8 comments:

Anonymous said...

In Customizing the ItemStyle.xsl for CQWP, step 3 seems incomplete. Also are a bunch of screenshots missing ?

Faraz said...

Thank you for the comment. I have fixed the HTML markup and added a screenshot.

tima said...

Any chance you can post the modified ItemStyle.XML. Your BLOG does not show most if this detail.

Hamza Farooq said...

Hi it will be best of you add XSLT for them below each sample image :) , Thanks in advance

Hamza Farooq said...

Thanks, a bit out of the way question but is there any way to give unique IDs to the each table or div tag generated for each item? vis xsl not like adding field in article page layout and call it there

makuwaza said...

hi, on my site News Articles doesnt appear as a parent type, under Site Content Types. Would you know how im suppose to fix this

Custom Paper Writing said...

Many institutions limit access to their online information. Making this information available will be an asset to all.

J U N D I said...

Hi Faraz,

Thank you first for the solution you posted as it was great solution and it really clarified a lot of things for me. I have a question, though. Would it be possible to add code into the custom article page to have additional commands such as "comment box", "printer friendly version", or "send to a friend" even?

Thanks for your valuable efforts