Customizing the Display of a SharePoint 2010 Blog

I’ve changed pages countless times in SharePoint Designer, but this case, where I wanted to make a relatively small change to the home page of a Blog site, proved especially onerous.

In most cases, overriding the default XSL is as simply as editing what’s there and saving your changes.

It would seem that the team that works on blogs doesn’t chat with the rest of the product group, because blogs work differently. Blog pages use an XSL file called blog.xsl, which live in the _layouts folder on the Web Front Ends (WFEs).

On the home page of a blog site (default.aspx), there are several XLV Web Parts, but the main one is the one which displays the most recent posts. All I wanted to do in this case was display a different column instead of Created By (@Author) . Because in many organizations someone different that the author is the person who types the post, we had added a Written By column to the Posts list. The logic was simple: if the Written By column had a value, show it, otherwise show the Created By column as usual.

I wanted to keep the XLV Web Part in place in case we needed to work with it in the future, plus the markup it emits is a bit crufty and I didn’t want to have to replicate it all with a custom DVWP. (In retrospect, this *may* have been easier.)

It should have been pretty easy to make the change, but I went down some rat holes. I don’t want *you* to go down those rat holes, so here’s what ended up working.

Open the page in SharePoint Designer, position your cursor on the XLV Web Part which displays the posts and in the List View Tools section of the ribbon, choose Customize XSLT / Customize Entire View.

image

This pulls the XSL from blog.xsl into the page, in theory so that we can customize it. However, don’t go down that path; there be monsters. Instead, find the line:

<xsl:include href="/_layouts/xsl/blog.xsl"/>

and Ctrl-Click on the href link to the blog.xsl file. This will open the blog.xsl file in a different SharePoint Designer window for the root of the Site Collection. This is handy, because you now want to save a copy of blog.xsl in a Document Library in the root site of the Site Collection. I usually create a Document Library called XSL anyway to hold frequently-used XSL templates, like the ones I have in my SPXSLT Codeplex Project. I named my copy BlogWrittenBy.xsl.

Close the default.aspx page you opened in the blog site now WITHOUT saving it. Remember? Monsters. Open it again. See, no monsters.

Since we had added a new custom column called Written By, I needed to add it to the ViewFields section so that the XLV Web Part would retrieve values for it:

<ViewFields>
  <FieldRef Name="Title"/>
  <FieldRef Name="Body"/>
  <FieldRef Name="Author"/>
  <FieldRef Name="PostedByWithDate"/>
  <FieldRef Name="CategoryWithLink"/>
  <FieldRef Name="Permalink"/>
  <FieldRef Name="EmailPostLink"/>
  <FieldRef Name="NumCommentsWithLink"/>
  <FieldRef Name="PublishedDate"/>
  <FieldRef Name="PostCategory"/>
  <FieldRef Name="Written_x0020_By"/>
</ViewFields>

Then I saved the file. Yes, that customizes (or unghosts) the file. I’m OK with that.

Back to the BlogWrittenBy.xsl file I saved above. I found the section of the XSL where Created By (@Author) is emitted:

<xsl:when test="@Name='Author'"><span class="ms-postfootercolor"><xsl:value-of select="'by '"/></span><xsl:text disable-output-escaping="yes" ddwrt:nbsp-preserve="yes">&amp;nbsp;</xsl:text><xsl:value-of select="$thisNode/@Author.span" disable-output-escaping="yes" /></xsl:when>

and replaced it with this:

<xsl:when test="@Name='Author'">
  <xsl:variable name="ShowPerson">
    <xsl:choose>
      <xsl:when test="string-length($thisNode/@Written_x0020_By.id) &gt; 0">
        <xsl:value-of select="$thisNode/@Written_x0020_By.span" disable-output-escaping="yes"/>
      </xsl:when>
      <xsl:otherwise>
        <xsl:value-of select="$thisNode/@Author.span" disable-output-escaping="yes"/>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:variable>
  <span class="ms-postfootercolor"><xsl:value-of select="$thisNode/../@resource.wss.ByPrefix"/></span><xsl:text disable-output-escaping="yes" ddwrt:nbsp-preserve="yes">&amp;nbsp;</xsl:text><xsl:value-of select="$ShowPerson" disable-output-escaping="yes" />
</xsl:when>

This added the conditional logic we wanted.

Next, off to the browser, where I opened the page for editing. In the Tool Pane for the List View Web Part which shows the blog posts, I went to the Miscellaneous section and added a link to my XSL file in the Xsl Link field. In my case, since it was stored in the root of my Site Collection, the link was /XSL/BlogWrittenBy.xsl.

Then I saved the change and voila! Exactly what I wanted.

There are other ways to accomplish what I did here with a deployable feature and managed code, etc. In this case, it was a small farm with only a production environment and a single blog where we wanted to make the change. All you enterprise types just gasped, but this is the reality in many organizations.

Obviously it wasn’t all as simple as what I outline above. Here are some of the things I found:

  • If I edited the XSL in SharePoint Designer (after the Customize Entire View step), my changes worked great in SharePoint Designer,. However, when I went to the browser, I saw the page the same way it had looked before. I believe this is because the blog.xsl file was pulled in anyway, and no amount of jiggling things could get me past that.
  • If I tried to add the XSLLink in SharePoint Designer, which ought to work, it always stripped off the leading / in the link to the XSL file. This meant that the link was invalid and blog.xsl was used again.
  • The sequence I ran through above seems to be the only reliable way to make this work. It’s pretty quick (after 47 tries) and I did it twice as I was writing this. Of course, I had a copy of the original default.aspx file to work with. Never edit the default files without making a copy.

Here are two threads from the MSDN Forums that helped a bit. I didn’t have any luck with the ddwrt:ghost="hide" approach.

http://social.technet.microsoft.com/Forums/en-ZA/sharepoint2010customization/thread/669d7d94-45ad-4fa0-8fe9-069d44ba07fa

http://social.technet.microsoft.com/Forums/en-ZA/sharepoint2010customization/thread/9e5862b2-5271-47b8-8c9c-7742b7af55eb

35 Comments

  1. Thanks for suffering so we don’t have to, Marc. I tell people that I hate SharePoint at least once a day – except on payday.

    Reply
  2. We also had the same requirements to pull the correct post author out.

    How did you solve the issue with the actual article page. It will also display the Created By field?

    I’m on SharePoint Online, so I am not able to open the Post.aspx page layout. Do you have any idea how one may solve it through XSL?

    Reply
    • Martin:

      By changing blog.xsl and making the changes I outline in the individual pages, all of the pages which display the blog entries were “fixed”. You should be able to open the Post.aspx page on SharePoint Online. It’s one of the pages in the context of the Posts list in the Blog Site.

      M.

      Reply
  3. Hi Marc – is there a way to disable the Author of a Topic or Comment’s hyperlink using methods described in your article?

    I’ve been trying to do it with styles but the nearest I got was hiding the Author.

    Any help will be appreciated.

    Reply
    • Phil:

      If you want to hide what is displayed by the out of the box Blog Site, then it should be possible with CSS. The trick will be to get the right CSS selectors to do what you want without hiding other things in places you don’t expect.

      M.

      Reply
  4. Did anyone else have trouble getting this to work? I tried 3-4 times and could not get it to work either time. I also tried just changing the publisheddate to Author to try and display auther twice and that didnt do anything either.

    Thanks in advance

    Reply
    • Zach:

      SharePoint was pretty finicky through this whole process, but it does indeed work as I spell it out. When you say it didn’t work, what were the issues or symptoms?

      M.

      Reply
  5. Hello Marc,

    Great post as always. I was able to add new custom fields to my blog post and was able to redesign it the way I wanted it to look. The issue that I am running into though is I put straight HTML in there that if the field shows up, I wanted it to display the HTML. Unfortunately though, the HTML is always there.

    I created a new field called Other Items, so that if the field was populated, the header for Other Items would show up and then whatever was put into the field. When the field is blank, I don’t want it to show the header. I know I’m missing something, and hopefully it is something simple. Any ideas?

    Other Items:

    Reply
  6. Hi,
    I have created a content query web part which is showing me posts from subsite. I got the title, body and basic structure but

    1. No Author’s Name(Created By)

    2. Author’s Picture

    3. Number Of comments,

    4.Category.
    How could i get it. I am customizing the xslt.

    Reply
  7. Hi Marc,

    I’m so glad to have found this article, now here’s a question for you from a non XSL person, I need to limit the display of each post to 250 characters with a “more” link to the actual post. This can be done in MOSS 2007 however I am having difficulty finding a way to do this in SharePoint 2010.

    Thanks

    Chet

    Reply

Leave a Reply