|
Source: http://www.bluedoglimited.com/SharePointThoughts/ViewPost.aspx?ID=90
Update 9/29:
- Updated steps to include using a custom form for new comments instead of simply editing the default new item form for the Blog list.
- Added info on how to get method LoadID to fire
- Corrected method LoadID
---
Keep in mind one thing - building and maintaining a blog is a labor of love. You will always find something that needs tweaking. If you don’t have the patience or desire to learn what needs to be done so that you can create and/or tweak your blog, then it’s best you stop reading now. :)
The purpose of this weekend’s exercise is to help folks understand what is required to build their own blog. There are a lot of little pieces that I won’t be able to cover, but I will try my best to cover the basics. At the end, I’ll point you to a couple of templates that you can use as a shortcut to help you get started without having to worry about starting from scratch.
Both blog models have a few things in common.
- Data is stored in custom lists.
- Custom display is generated by the DataViewWebPart. You will need to know a little bit about xsl to really make the DVWP come to life.
- Users will need permissions to read all items.
- Users should be allowed to edit only their own items.
- You will need to create a few pages which are designed for particular tasks (i.e. view post+comments, summary view).
The first thing that may come to your mind is "Geez, the DVWP? That means that I have to use FrontPage 2003! Argh!"
Not true – If you have FP, your life will be considerably easier. The main advantage of using FP is that it allows for rapid configuration a DWVP. However, it’s not necessary. Everything that is presented in this series of posts can be done using nothing more than Notepad, property tool panes, and the browser ui.
Now let’s cover the core differences between the two models:
Model #1
- Based on only one list – let’s call it Blog
- Moderation is turned ON. If you don’t do this, then everyone can post as the blog author.
- The Blog list has at a minimum the following columns
- Title – single line of text
- Body – multiple lines of text
- Type – Choice column with “Post” and “Comment” options
- Related To – Lookup column which references the ID column in the Blog list
Model #2
- Based on two lists – let’s call them Blog and Comments
- Only the admin has access to create/edit posts within the Blog list
- Everyone has create/edit rights to the Comments list
- The Blog list has at a minimum the following columns:
- Title – single line of text
- Body – multiple lines of text
- The Comments list has at a minimum the following columns:
- Title
- Body
- RelatedTo – Lookup column which references the ID column in the Blog list
Once you’ve the chosen the operational model and built the required list(s), the majority of the work will be centered on building the display. At this point in time, the DataViewWebPart will become your best friend.
Building and modifying views is probably a simple task for many folks. The trick (if you were to call it that) is making the pages link and reference each other so that you have a complete user experience: view summary --> view individual post + related comments --> add comment.
On my site, I basically have 3 custom views on 2 different pages:
- Summary view with links to view individual posts (on default.aspx)
- Invidual view (on viewpost.aspx)
- Comment view, designed to show items related to the specified post (on viewpost.aspx)
You can tie your pages together by using the two methods – web part cross page connections or "simplistic" links (e.g. viewpost.aspx?id=88). How you tie the pages together is up to you. For my site, I chose simplistic links because I find urls generated by cross page connections to be quite ugly (and hard to maintain).
As you play with the DVWP and its xsl, you will find that most of your modifications will occur in the "dvt_1.body" template. If you search for "<xsl:template name="dvt_1.body">", you will notice that this xsl template contains the markup used to display each item in your list. FrontPage will allow you make modification to most of the display, but there are some things you will have to manually add to the xsl in order to get the desired output.
Let’s piece together a couple of pages so that you can see how a fully operational blog can be built. We’ll build two pages for model #1:
- Default.aspx: A default view page where only posts are displayed and a button with “View comments”
- ViewPost.aspx: The page displays both posts and comments.
Instructions for Default.aspx:
- Create a new web part page, call it "Default.aspx"
- Add a list view part for the Blog list.
- Modify the web part...
- Select Edit the View, display only Title and Body
- Set Toolbar Type to No Toolbar
- Open FrontPage, convert the web part to a DVWP.
- Adjust the display to your liking. This provides a basic structure. Note that your view is currently displaying both posts and comments.
Now add a display time filter to limit the view to only posts ...
Again, in FP and viewing the source, search for "<xsl:template name="dvt_1.body">"
Find the for-each block which is used to iterate through all items in your list (look for "<xsl:for-each select="$Rows">").
Add a display time filter to limit the view to only posts by wrapping the entire contents of the for-each section in an "if" block. Thus, add the filtered view would look like...
<xsl:for-each select="$Rows">
<xsl:if test="@Type='Post'">
… original content …
</xsl:if>
</xsl:for-each>
The next thing to do is to add a link to your view page. Let’s say we wanted to create a link that looks like...
View comments (0)
- Search "<xsl:value-of disable-output-escaping="yes" select="@Body"/>".
- Insert the following text immediately after the <xsl:value-of> tag:
<div>
<a style="text-decoration: none;"><xsl:attribute name="href">ViewPost.aspx?ID=<xsl:value-of select="@ID"/></xsl:attribute>View comments (<xsl:variable name="commentCount" select="@ID"/><xsl:value-of select="count(//@RelatedTo[.=$commentCount])"/>)</a>
</div>
The first page is complete. It now displays a filtered view of the Blog list in which only Posts are shown, a comments counter is available, and a link to ViewPost.aspx is included.
Now, let’s build a page which will display a single post and all of the associated comments. For simplicity sake, these instructions will simply call out the specialized steps.
Instructions for ViewPost.aspx:
- Create a page called ViewPost.aspx
- Add a DataViewWebPart for the Blog, filtered to show only Posts. Let’s call this web part "Posts".
- Add a DataViewWebPart for the Blog, filtered to show only Comments. Let’s call this web part "Comments".
- Create a WebPart connection between "Posts" and "Comments". Starting from the "Posts" web part...
- Provide Data Values to "Comments"
- Target action = Filter View Using Data Values From "Posts" column ID to "Comments" column RelatedTo.
- In the "Posts" web part, supply an additional filterParam binding so that the web part will be able to filter the display based on the query string parameter "?ID=x". You will need to follow the directions posted at http://support.microsoft.com?id=831093. The parameter name for this example is "ID"; thus, the complete string will be "QueryString(ID)".
Now let's add a "Post a New Comment" button in the "Posts" web part.
- View the xsl data, find the area where the Body is pumped out (search for "<xsl:value-of disable-output-escaping="yes" select="@Body"/>")
- Insert the following markup after the Body section (note: the display format is not really important, but the onclick handler GetID is crucial)...
<table border="0" width="140" cellspacing="0" height="8" cellpadding="0" >
<tr>
<td class="ms-navframe" bordercolor="#798073" style="border-style: solid; border-width: 1px; background-image:url('/_layouts/images/partgrad.gif')">
<p align="center">
<span style="cursor:hand" onclick="GetID()">
<font style="font-size: 0.68em">Post a New Comment</font></span>
</td>
</tr>
</table>
Now add the GetID javascript method to the page source. This is the onclick event handler that will redirect the user to the appropriate new item form for the Blogs list.
View the page source.
In the <head> of the page, add the definition for the "GetID" javascript function.
function GetID () {
var regex = new RegExp("(?:(\\?|\\&)id=|FilterValue1%3d)", "gi");
var logID = document.location.href.split(regex);
var pageURL = "Lists/Blog/NewForm.aspx";
var returnURL = "ViewPost.aspx?id=" + logID[1];
window.location = pageURL + "?Source=" + returnURL + "&LogID=" + logID[1];
}
Finally, copy "/Lists/Blog/NewForm.aspx" to "/NewComment.aspx". Open the new file and add a javascript method which will associate IDs taken from the query string with requisite list column so that when comments are created the RelatedTo field is automatically populated. Four modifications are needed in newcomment.aspx:
- First, add the following script toward the top of the page (e.g. in the <head>)...
function LoadID () {
var RegX = new RegExp("LogID=", "gi");
var Log_ID = document.location.href.split(RegX);
document.forms[0]["urn:schemas-microsoft-com:office:office#RelatedTo"].value=Log_ID[1];
document.forms[0]["urn:schemas-microsoft-com:office:office#Type"].value="Comment"
}
- Add input tags after the <form> tag:
<input type="hidden" name="urn:schemas-microsoft-com:office:office#RelatedTo" value=""/>
<input type="hidden" name="urn:schemas-microsoft-com:office:office#Type" value=""/>
- then toward the bottom of the page markup (before the closing <form> tag), add the following:
<img border="0" alt="" onload=LoadID() src="/images/spacer.gif" width="1" height="1">
(Note: the src should point to an image on your system - in the templates listed in post 3/3, spacer.gif is a 1x1 transparent image)
finally, update the input display. This is done by right-clicking on the ListFormWebPart and selecting "Customize SharePoint List Form". Highlight and delete the two table rows which contain the RelatedTo and Type dropdowns. This is done so that users will not have to mess with those fields.
You've now built three custom pages to enable the desired user experience described at the beginning of the article (user experience: view summary --> view individual post+comments --> add comment).
The process for model #2 is basically the same - the only difference is that you will be working with 2 lists and therefore your xsl code will need to change to account for differences in the list structures.
This is without a doubt a whirlwind of information… the key thing to keep in mind is your pages need to carry some information forward as the user moves from page to page so that the end user experience is seamless.
My final article will briefly touch on how you can edit/create your DVWP outside of FP, additional blog "features", and finally include links to a template or two...
Series articles:
Post 1/3 - http://www.bluedoglimited.com/SharePointThoughts/ViewPost.aspx?ID=89
Post 2/3 - you're reading it!
Post 3/3 - http://www.bluedoglimited.com/SharePointThoughts/ViewPost.aspx?ID=91 |
|