Creating a latest blog posts web part

One of the great site templates that comes with SharePoint 2010 is the blog template. For a lot of organisations that are looking to encourage knowledge sharing an internal blogging initiative is often seen as a great first step. Blogs are a concept that many users are familiar with from regular use on the internet and are a great channel for employees to share information without having it feel ‘too corporate’. However, one of the challenges that can exist with a large number of bloggers within a SharePoint solution is how to surface the latest blog posts from around the environment.

On our company intranet we had a similar challenge with our own blogs. The first thought is to aggregate all the posts via the Content Query Web Part, however as many blogs are often created at an individual’s My Site, which is its own site collection, that approach will not work (I’ve discussed approaches to cross site collection aggregation previously). We therefore went with a search based solution to display the latest posts and I have updated the solution for SharePoint 2010.

I’m using an optimised version of the 2010 Information Worker Demonstration and Evaluation Virtual Machine (optimised by Tristan Watkins) from which to work on. The main thing I need really is a site with some blog posts that have been indexed by the search service application, and the demo IW machine comes with a load of pre-created content.

Although the fantastic new Activity Feed in SharePoint 2010 will alert you to new blog posts (in addition to many other activities) it is not quite as detailed as I’d like. It is also restricted to only show updates from people you have identified as colleagues which may or may not be what you’re looking for. Here’s a screenshot of the new post notification in the activity feed, which I’d like to expand on:

Activity Feed New Blog Post

So what should it look like? Well, taking a look at the out of the box home page of a blog site there is a nice presentation of the latest posts on that particular blog. If the latest blog posts web part could look like similar to this then it would have the advantage of being familiar to the user and also cut down on the amount of CSS required from me (good news for everyone!).

SharePoint 2010 Blog Site Template

The end result then is to achieve a similar listing for all blog posts in the environment. The steps to do this are:

  • Perform a full crawl of a content source which has at least one blog post and a comment
  • Add a Managed Property for the number of comments and name it something appropriate, e.g. NumComments
  • Add a Search Core Results web part to the page you wish to display the latest blog posts web part on:
    • I’ve chosen the My Newsfeed page so that it can display alongside the Activity Feed
    • It may be necessary to activate the Search Server Web Parts site collection feature if the web parts are not immediately available
  • Configure the Search Core Results web part:
    • Add a column mapping for the new managed property NumComments
    • Add in customised XSL to display the results
    • Provide a Fixed Keyword Query of “contenttype:post
    • Limit the amount of items returned (I’ve gone for 5 in this example)
    • Modify to sort the results by modified date

After doing the above we then see something like the below – a latest blog posts web part from all blogs currently indexed by the SharePoint search.

Latest Blog Posts Web Part

The XSL I’ve used for the web part can be found below (edited a bit for neatness but hopefully still functional!):

<xsl:stylesheet xmlns:x= "http://www.w3.org/2001/XMLSchema"
	xmlns:d= "http://schemas.microsoft.com/sharepoint/dsp"
	version= "1.0"
	exclude-result-prefixes= "d xsl msxsl ddwrt xmlns x __designer WebControls asp ddwrt2"
	xmlns:ddwrt= "http://schemas.microsoft.com/WebParts/v2/DataView/runtime"
	xmlns:asp= "http://schemas.microsoft.com/ASPNET/20"
	xmlns:__designer= "http://schemas.microsoft.com/WebParts/v2/DataView/designer"
	xmlns:xsl= "http://www.w3.org/1999/XSL/Transform"
	xmlns:msxsl= "urn:schemas-microsoft-com:xslt"
	xmlns:WebControls= "Microsoft.Sharepoint.WebControls"
	xmlns:ddwrt2= "urn:frontpage:internal">
  <xsl:output method="html" indent="no"/>

  <xsl:template match="Result">
    <xsl:variable name="blogPath">
      <xsl:call-template name="getblogpath">
        <xsl:with-param name="encodedPath" select="url" />
      </xsl:call-template>
    </xsl:variable>

    <li class="blogListPost">
      <!-- date box -->
      <div class="blogListPostDate">
        <div class="ms-postcalendardateboxtop" id="PostDateTopBox"/>
        <div class="ms-postcalendardateboxbottom" id="PostDateBottomBox">
          <div>
            <xsl:value-of select="ddwrt:FormatDateTime(string(write),1033, 'MMMM dd')" />
          </div>
        </div>
      </div>
      <div class="blogListPostBlock">
        <!-- Title -->
        <h4>
          <a style="color: #295AC6;">
            <xsl:attribute name="href">
              <xsl:value-of select="url"/>
            </xsl:attribute>
            <xsl:value-of select="title" />
          </a>
        </h4>
        <!-- Date and Summary -->
        <div class="blogListPostPostedDateAndSummary">
          <span class="ms-PostFooter blogListPostPostedBy">
            Posted by
            <xsl:value-of select="author" disable-output-escaping="yes" />
            on
            <xsl:value-of select="ddwrt:FormatDate(string(write),1027, 1)" />
          </span>
          <p class="ms-PostBody blogListPostBody">
            <xsl:value-of select="hithighlightedsummary" disable-output-escaping="yes" />...
          </p>
        </div>
        <!-- Blog links -->
        <ol class="blogListPostLinks">
          <!-- Permalink -->
          <li class="blogListPostLinksItem">
            <span style="vertical-align:middle;">
              <span style="position: relative; width: 16px; display: inline-block; height: 16px; overflow: hidden;">
                <a style="width: 16px; display: inline-block; height: 16px;">
                  <xsl:attribute name="href">
                    <xsl:value-of select="url"/>
                  </xsl:attribute>
                    <img longdesc="Permanent Link to Post" class="imglink" title="Permanent Link to Post" style="left: 0px ! important; top: -412px ! important; position: absolute;" alt="Permanent Link to Post" src="/_layouts/images/fgimg.png" />
                </a>
              </span>
            </span>
          </li>
          <!-- Email link -->
          <li class="blogListPostLinksItem">
            <span style="vertical-align: middle;">
              <span style="position: relative; width: 16px; display: inline-block; height: 16px; overflow: hidden;">
                <a style="width: 16px; display: inline-block; height: 16px;">
                  <xsl:attribute name="href">
                    javascript:navigateMailToLink('
                    <xsl:value-of select="url"/>
                    ')
                  </xsl:attribute>
                  <img longdesc="Email Post Link" class="imglink" title="Email Post Link" style="left: 0px ! important; top: -267px ! important; position: absolute;" alt="Email Post Link" src="/_layouts/images/fgimg.png" />
                </a>
              </span>
            </span>
          </li>
          <!-- Comments -->
          <li class="blogListPostLinksItem last">
            <span style="vertical-align: middle;">
              <span style="position: relative; width: 16px; display: inline-block; height: 16px; overflow: hidden;">
                <a style="width: 16px; display: inline-block; height: 16px;">
                  <xsl:attribute name="href">
                    <xsl:value-of select="url"/>
                  </xsl:attribute>
                  <img longdesc="Number of Comments" class="imglink" title="Number of Comments" style="left: 0px ! important; top: -396px ! important; position: absolute;" alt="Number of Comments" src="/_layouts/images/fgimg.png" />
                </a>
              </span>
              <span>
                <a>
                  <xsl:attribute name="href">
                    <xsl:value-of select="url"/>
                  </xsl:attribute>
                  <xsl:text>
								</xsl:text>
                  <xsl:value-of select="numcomments"/>
                  Comment(s)
                </a>
              </span>
            </span>
          </li>
        </ol>
      </div>
    </li>
  </xsl:template>

  <xsl:template match="TotalResults">
  </xsl:template>
  <xsl:template match="NumberOfResults">
  </xsl:template>

  <xsl:template name="getblogpath">
    <xsl:param name="encodedPath"/>
    <xsl:choose>
      <xsl:when test="contains($encodedPath, '/')">
        <xsl:value-of select="substring-before($encodedPath, '/')"/>/<xsl:call-template name="getblogpath">
          <xsl:with-param name="encodedPath" select="substring-after($encodedPath, '/')" />
        </xsl:call-template>
      </xsl:when>
      <xsl:otherwise>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>

  <xsl:template match="/">
    <link rel="stylesheet" type="text/css">
      <xsl:attribute name="href">
        /_layouts/1033/styles/Themable/blog.css
      </xsl:attribute>
    </link>
    <style type="text/css">
      .s4-ca {width:100%;}
      .blogList {list-style-type: none; padding:0;margin:0;}
      .blogListPost {border-bottom:1px dashed #CCCCCC;padding:10px 0;margin:0;}
      .blogListPost:hover {background-color:#F5F5F5;}
      .blogListPostDate {float:left;width:90px;padding-left:20px;}
      .blogListPostBlock {margin-left:110px;}
      .blogListPostBlock h4 {padding:0;margin:0;}
      .blogListPostPostedDateAndSummary {display:block;}
      .blogListPostPostedBy { }
      .blogListPostBody {padding-top:0px;padding-bottom:0;}
      .blogListPostLinks {list-style-type:none;padding:0;}
      .blogListPostLinksItem {display:inline;padding:0 10px 0 10px;border-right:Solid 1px #999999;}
      .blogListPostLinksItem.last {border:none;}
    </style>
    <ol class="blogList">
      <xsl:apply-templates/>
    </ol>
  </xsl:template>

  <!-- End of Stylesheet -->
</xsl:stylesheet>

A few things to note with this solution are:

  1. Some CSS is hardcoded into the XSL, which should probably be referenced in an external file
  2. The results are sorted based upon the Modified Date, which is not necessarily the same as the Published Date of a blog article
  3. The number of comments field is only updated by the search after a full crawl, whereas new posts are returned after an incremental crawl

[In fact, the Products Department at Content and Code liked this idea so much that they wrapped it up into a product for both SharePoint 2010 and SharePoint 2007 – called the Blog Roll. This product addresses some of the above shortfalls and wraps everything up into a production ready install.]

share and enjoy
  • Print
  • Twitter
  • Digg
  • del.icio.us
  • StumbleUpon
  • Yahoo! Buzz
  • Google Bookmarks
  • Facebook

36 comments to Creating a latest blog posts web part

  • Knuppel

    Help…
    I’ve got the XLS working in SSE2010, have removed the comments part since SSE2010 does not allow managed property searches.
    But now I have another problem, the date is wrong.
    On the blog itself it says 11-10-2010 (11th of oktober). In the webpart it says 10-11-2010 (10th of november). How can I correct this? I’ve looked at all the regional site settings, and they’re all correct (Dutch regional, gregorian calendar)?

  • Hi Knuppel,

    I’m glad you’ve had some success recreating this! I think the issue with the date format displaying in the wrong format can be corrected in the XSL where it outputs the ‘posted by’ section.

    If you look the for the bit that outputs the date:

    Knuppel

    Thanks for the quick response. Changing the locale didn’t work.
    In the end, resetting crawled content did the trick! Sharepoint somehow saves the regional date/time in it’s search database.

  • Knuppel

    Loving this webpart btw!

  • Nick

    Thank you for XSL! It rocks!

  • […] view web part Friday, November 5th, 2010 | SharePoint 2010 | Glyn Clough After seeing my post on displaying recent blog posts from around a SharePoint site a pal (@andrewjolly) got in touch and asked me if it would be […]

  • Glasspinne

    Looks great
    Any tips how to actually deploy this webpart?

    • Hi Glasspinne,

      There is actually nothing to deploy with this solution – it’s using the out of the box search core results web part (you may need to activate the search site collection feature to make the web part available) – and then the custom XSL is added by editing the web part properties. I hope that helps!

  • Pankaj

    Hi Glyn,

    Your article is very use full.Thanks
    can I try same thing with Moss 2007
    Is it possible,actually I tried this
    but its not working for me.
    so any idea how can i do this.
    Pleas tell me in detail,because
    i am new in SharePoint.
    and sorry for my English.

  • Hi Pankaj – the same approach should work with MOSS 2007. I haven’t used this particular XSL though I have used search to return blog post items in 2007. The structure of a blog post is very similar in 2010 as in 2007 though so I don’t see any reason why it wouldn’t work.

    I’m afraid I’m unable to give you any more detail than what I’ve added in the post already as to how to set it up. However, note that you will need access to Central Administration in order to configure search to crawl the necessary properties you need for this to work. Once you have that configured then the rest is simply dropping a search results web part onto the page with a couple of property edits. Thanks

  • Anurag

    Hi!

    I am trying to fetch Date Created and Last Modified property of List library for every item but not getting the way to implement this. I added “write” manage data property in “fetching column” and trying to access using xslt like

    I am stuck on this from last 2 days. Please help?

  • Terje AT

    Thank you, helped me alot!

    But I would like to have a version without the Datebox, I have tried to remove the code for the datebox (line 22 to 31) but it still shows up. What do I need to remove in order to get rid of it?
    Thanks for any help!
    – Terjeat

    • Hi Terjeat, I’m glad you’ve found it useful.

      Unfortunately I don’t have this on an environment any more where I can quickly test it. From looking at the XSL though, I think you’re modifying the right bit. As with all XSL changes I find it best to make many small changes rathe than one large one – so I’d suggest just modifying line 27 (which outputs the date/month for the Date Box) and seeing if you can get that change to ‘stick’. Then work your way in increments to remove the whole div.

      HTH

  • Anthony

    First of all, Thank you very much for this blog! I am trying to build a “Facebook” like MySites and this has helped a lot.

    I have formatted the CSS and the XSL in order to match the look and feel of both other built and out of the box WPs. But I am looking to refine the query. I was curious if it was possible to only show posts from colleagues? Perhaps you can guide me to where the query is being built? Thanks again man.

    A

    • Hi Anthony, I’m glad you’ve found it useful.

      As to restricting the results to only show posts from your colleagues then I can’t actually think of a way to do that. The search query is created just from regular search syntax, i.e. you could enter it directly into a search box on your SharePoint site and get the same results back. I don’t know of any syntax unfortunately to restrict the results to just your colleagues.

      The OOB activity feed is designed/ built for this purpose – so if you’re a developer (or have any on your team) then you could perhaps ask them to look at extending the activity feed web part to work for you?

      Thanks,

  • Anthony

    Glyn,

    Thanks for the quick response. As it stands, I am also looking for a solution to include posts on subsite blogs in the activity feed for that user instead of just posts from their personal blog so I guess these go hand in hand. Ill keep searching. Thanks again for you help.

  • audunms

    Hi, thanks for a nice guide!

    I am having the same problem as Knuppel, the date is not output correct. It is not just the order, the date is actually wrong. The date box says “May 04” for a blog posted on April 5th.. if viewing the actual blog post on the blog site, the date is correct. I have checked that the regional settings under site settings are set to my region. I have also changed the locale both places in the xsl to 1044, but the date box still shows the wrong date, and the date itself after “posted by xx on..” is also displayed wrong (e.g. mm dd yyyy instead of dd mm yyyy). Did you do anything more than you have described knuppel to fix this?

    Also, I can not get the number of comments to show. I have created the managed property NumComments and mapped this to ows_NumComments(Text). I have also added Column Name=”NumComments” in the web part properties. Even after full crawl and resetting the index the number of comments do not show.

    • Hi @audunms – I think the issue with your date display may be because the web part is using the Created Date and not the Post Date. These are actually two separate fields. It would be worth checking what the created date of your post items are to see if this is indeed the case.

      Re the numcomments field it really does sound like you’ve done everything correctly! The only thing I can suggest is that when you add a new managed property it needs to crawl an item before it becomes ‘available’ – i.e. you need to actually have comments on your posts. (Although I imagine you have already!) Sorry I can’t be of further help.

      Glyn

  • audunms

    Hi, I am having the same problem as Knuppel, but the solutions suggested does not work for me. A blog post posted on the 5th of April shows May 4th in the datebox also.

    I cannot get the number of comments to show either. I have created a managed property and mapped it to the ows number of comments (text), and added a column name=NumComments in the web part properties. Resetting index and full crawl does not make a difference.

  • audunms

    Ok thanks. Sorry for double posting, didn’t look like my post was registered. The post date and created date should be the same (it’s difficult to create something on the 4th of May 2011 since we’re still in April;))

  • PeterK

    I have a strange issue, if I first save a post as draft and then publish it, it will not show? If I publish directly it shows as wanted..

    • Hi Peter, that does seem a bit strange. This solution simply runs off the regular search functionality – so the first thing I’d check is that the post is being returned in the regular results. If it isn’t then perhaps this is a scenario that isn’t picked up in the incremental crawl, and a full crawl is required?

      Sorry I can’t be of more help.

  • Logesh

    can i use this XSL in Blog site home page.. ie replacing the existing xslt of recent post view in blog site default.aspx

    • Hi,

      Sorry, this XSL is explicitly for the search results web part. You’d have to write new XSL for the XSLT List View Web Part on a blog site home page. However the XSL above was written to mimic the look and feel of what is already on the blog site home page, so I’m not sure why you’d want/ need to do that.

      Thanks,

  • Jay

    This works great but I have one small question regarding the ManualRefresh function… I can’t seem to get the Search Core Results to display the manualrefresh.gif and associated functionality. Any idea why?

    Thanks.

    • Glad you like it Jay. I’ve never tried the manual refresh option on the Search Core Results web part to be honest – however I expect the reason that it is not displaying is because we have used custom XSL to display the results. We would need to have the necessary processing in the XSL to output the right HTML in order for it to display.

      If you want to pursue that then I’d suggest adding an OOB Search Core Results web part to the page and then taking a look at the XSL that’s in that by default. If that displays the manual refresh image then you’ll need to find the corresponding XSL that is outputing it and include it in the latest blogs XSL. Having worked with the search XSL a little, I can tell you that I don’t think this will be a quick task!

      Also, keep in mind that this whole solution is based off search results – so a manual refresh of the results may still not show up newly added blog posts; it will be completely dependent upon the frequency of your search crawl.

      HTH

  • ravi

    Hi i am working on sharepoint 2007, i facing one issue with blog site.our requirement is among form all blog posts the latest one should display complete post and rest of blog post should display only 2 to 3 line in the default.aspx please help to do this

    • Hi Ravi – to do that you’ll need to customise the XSL; basically editing the Result template to recognise when it is the first result and to display the whole post. This is a fairly specific bit of XSL and will likely take a little while, so I’m afraid it’s not something I can offer you in full here.

      Good luck!

  • ravi

    Hi Glyn,
    How to write the if condition to filter the latest blog post id in xslt code,based on this i need to display complete body of latest post, rest of posts should be display 2-3 lines

    i will wait for your reply

  • Works great but one question. Is there any way to limit the search scope to just one level deep, ie we have some blogs as subsites of main site, and I would like to limit scope to just that next level. I think now its pulling from all subsites. I checked webpart configuration options and scanned XLS but nothing jumped out at me. Thanks in advance for any help.

    • Hi Mark – as this is a solution based on search then you should be able to do this by creating a new scope for ‘1st level’ only and then using this scope in your results web part.

      I can’t think exactly what the rule is that you’ll need to do this in your scope but I’m sure a bit of creative thinking will get you there!

  • Andrew

    Thnaks alot this solution helpt me alot!

    Is there an option to display the posts by current user ?

    tnx

    Andrew

  • […] You can use search based solution like in this post Creating a latest blog posts web part […]

Leave a Reply

You can use these HTML tags

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>