Navigation

Monday 12 July 2010

RCWP Part 1 – SPRetreat and the Related Content Web Part

I’m sat on the train after a great day of SPRetreat (followed by SharePint of course!), superbly organised by Andrew Woodward (21Apps) and Ben Robb (CScape). It was a really good day of innovative ideas, problem solving, chewing the fat (and the occasional dirty joke... you know who you are!).

The core challenge thrown down for the day involved trying to provide cross-site (collection) “related information”, effectively a “cross-pollination” function, using SharePoint 2010. There were some great ideas and a lot of top effort into involving the Managed Metadata Service, Custom Search API work and some cracking Scrum / Agile design processes.

We had 5 sessions of 1 hour each, and my efforts for the day mostly revolved around delivering a “Related Content Web Part”, which could use Search to show other content from any data source which is in some way related to the information on the current page.

In this post I’m going to walk through how my efforts of the day culminated in the “Related Content Web Part” but ended up being a generic “Dynamic Field Driven Search” web part, basically allowing a set of search results to be displayed based on the value of a field that is stored in the publishing page (i.e. content type) that contains the web part (which derived from the Search CoreResultsWebPart).

In the final sessions we though about how to improve this, and ended up building a custom contextual ribbon interface to surface SP Modal Dialogs to allow easy updating of core web part properties.
Core Functionality

The functionality is really split into 3 major sections:
(Full source code for the solution will be published in Part 3)

RCWP Part 1 - Extending the Core Results Web Part
This is one of the nicest new “features” of SharePoint 2010. They have stopped sealing all of the Web Parts (and Web Part Connections)that are used for the results pages in SharePoint Search solutions. This means it is now much easier for you to extend and add-value to these web parts without having to throw out all of the OOB functionality.
The reason for using the CoreResultsWebPart was simple;
  • Using search is fast, efficient, cross farm and highly configurable.
  • The core results web part using XSLT for rendering, so easy to design the output.
  • Leveraging an OOB web part means we get loads of added functionality for free! (like specifying which scope we want to use).
In this solution, we extended the CoreResultsWebPart to create our own Web Part. Simple create a new Visual Studio 2010 “Web Part” item and set it to inherit from “CoreResultsWebPart” (you will need to add a reference to Microsoft.Office.Server.Search.dll).
[ToolboxItemAttribute(false)]
public class RelatedContentWebPart : CoreResultsWebPart
{
}
In terms of functionality we need to do 1 thing:
Override the Query programmatically, based on the metadata of the current page.
This involved a few steps. First off, we need to identify which field we want to be “targeting”. For this we created a simple string field, exposed as a Web Part Property.
private string fieldName = "Title";
///<summary>
/// The field on the current page we want to use for filtering
///</summary>
[WebBrowsable(true)]
[Personalizable(PersonalizationScope.Shared)]
[WebDisplayName("Field Name")]
[SPWebCategoryName("Filter SPR")]
[WebPartStorage(Storage.Shared)]
[Description("Which field on the current page do you want to use for filtering?")]
public string FieldName
{ get { return fieldName; } set { fieldName = value; } }
Then we needed to override the query itself. This is simply done by setting the “FixedQuery” property of the CoreResultsWebPart. The trick here is you need to set this in the “OnInit” event, otherwise it won’t take effect (if you try to place it in OnLoad, CreateChildControls or any other later method then it won’t have any effect!).
protected override void OnInit(EventArgs e)
{
    this.FixedQuery = “keyword string value”;
    base.OnInit(e);
}
Finally, we need to make sure we are pulling out the field value of the current list item, based on our custom field. For this we used a simple set of SPContext combined with some defensive programming to make sure we don’t get any NullReferenceException errors. So change the “OnInit” event to the following:
protected override void OnInit(EventArgs e)
{
    if (!string.IsNullOrEmpty(fieldName))
    {
        if(SPContext.Current.ListItem.Fields.
            ContainsFieldWithStaticName(fieldName))
        {
            this.FixedQuery =
                SPContext.Current.ListItem[fieldName].ToString();
        }
    }
    base.OnInit(e);
}
After that … Build / Deploy and the web part was working!



The code could obviously be re-factored a little bit, but on the whole it’s all working :)
Make sure you check back for:


  • RCWP Part 2 – Web Part with Ribbon Contextual-Tab
  • RCWP Part 3 – Edit Web Part using a Ribbon modal dialog


  • (Full source code for the solution will be published in Part 3)

    1 comment:

    1. Hey,

      I am using Fast search for sharepoint 2010. when I add a webpart with extending CoreResultsWebPart in "Fast Search Center" site, It shows a empty page.
      But the other refinement web part and pagination webpart show the appropriate results. Is there any configuration I need to do in my side to get those results appear ??

      ReplyDelete

    This blog has been moved to www.martinhatch.com

    Note: only a member of this blog may post a comment.