Tuesday, September 28, 2010

Customizing the Search Action Links in SharePoint 2010

The SharePoint 2010 Search Action Links web-part is really just the Search Core Results web-part with the 'Show search results' settings set to false. Some of the action links have configurable captions such as the 'Show more results' link, while the 'Alert me' and 'RSS feed' link captions are not exposed in the web-part settings. However, it is quite easy to customize the layout, styling, links and content of the Search Action Links web-part - you can even add custom action links.

This example shows a searchable site directory built from customized standard SharePoint 2010 search web-parts:


Customizing the Search Action Links web-part is done exactly like for the Search Core Results web-part: you customize the embedded XSL or provide a custom XSL file using the hidden XslLink setting in the .webpart file. The following example shows how to customize the caption of the alerts and RSS links:


The example XSL shows how to set an <xsl:variable> field based on different conditions using <xsl:choose>. XSL don't have variables like in programming languages; they behave like C# const or read-only fields, they cannot be changed when first set.

The example XSL also shows how to fix an error with the RSS feed link when using a 'Fixed query' in your search page, or when using a specific search 'Scope' and no user query keyword by default, to show all results from that scope. The RSS link do not pick up these settings from the web-part, and the query RSS feed will generate the "Search RSS feed generation failed" error message. This error is caused by there being no keyword, which is fixed by adding a keyword to the URL using the k= querystring key. Just add the fixed query or the scope as the keyword:

/_layouts/srchrss.aspx?k=scope:"Puzzlepart"

Note that the 'Alert me' link don't have the k= RSS feed issue, rather it uses JavaScript and the hidden <input name="P_Query"> field on the page. This field is emitted by the Search Core Result web-part and contains the complete keyword query including the user query and the Scope, FixedQuery and AppendedQuery property settings.

Add custom parameters to the XSL when you need to have extra web-part configuration options beyond the provided standard parameters. For example, to simulate the P_Query mechanism, pass the query keywords as custom parameters. The example XSL shows how to use the custom parameter, along with the standard parameters. Use the 'Parameters Editor' in the web-part tool pane to configure your custom web-part setting:

<ParameterBinding Name="AppendedFilter" Location="None" DefaultValue="scope:&qout;Puzzlepart&qout;" />

Pass your configuration value using the DefaultValue attribute, using "None" as the Location. You can of course also set the 'alert me' and 'RSS feed' link captions using parameters.

I use code like this in a FeatureActivated event receiver to configure and add the customized web-part to our custom web part pages:

private static void AddWebPartResultsActionLinks(SPLimitedWebPartManager lwpm, string title, string siteTemplate)
{
    string xslParams = "";
    if(!String.IsNullOrEmpty(siteTemplate))
        xslParams = String.Format("<ParameterBinding Name='AppendedFilter' Location='None' DefaultValue='SiteInfoSiteTemplate:\"{0}\"' />", siteTemplate);

    CoreResultsWebPart ralwp = new CoreResultsWebPart()
    {
        Title = title,
        ChromeType = PartChromeType.None,
        QueryNumber = QueryId.Query1, //must be UserQuery because user can search the SiteInfoScope
        ShowActionLinks = true,
        ShowSearchResults = false, //this makes it an "action links" web-part
        ShowWindowsSearch = false,
        DisplayRSSLink = true,
        DisplayAlertMeLink = true,
        XslLink = "/CenterPages/XSL/SearchActionLinks.xsl",
        ParameterBindings = xslParams,
        UseLocationVisualization = false,
        ShowMessages = false
    };
    lwpm.AddWebPart(ralwp, "MiddleRightZone", 1);
}


You can of course export the customized Search Action Links web-part and use <AllUsersWebPart> in a file module to provision the web-part to a page, but the elements.xml file quickly gets huge and unmanageable. In addition, you'll have to encode any CDATA sections embedded in the exported web-part XML, as CDATA sections cannot be nested. That's why I recommend using XslLink rather than embedded XSL, and then code to provision the customized web-parts.

Wednesday, September 22, 2010

Missing "I Like It" in SharePoint 2010

The social tagging capability in SharePoint 2010 takes several dependencies on different service applications: the Managed Metadata Service application (MMS) for storing and providing tag definitions, the User Profile Service application (UPA) for storing the actual tagging and notes, and the Search Service for several tag-based web-parts to show tagging information such as those on the tag profile page. The identity used to run your SharePoint 2010 solutions and the content crawler identity needs to have access to the service applications that manage and store your social tagging data.

I recently added a new web-application to my development farm, and today to my surprise I noticed that the "I Like It" button in the global area was missing. In addition, the button was disabled in the item "Tags and Notes" ribbon.


The Tags & Notes buttons worked as expected in other sites in the farm, so the "Social Tags and Note Board Ribbon Controls" farm feature was activated, enabling these buttons for all sites in the farm.

I first verified that I had the "Use Social Feaures" permissions in the User Profile Service application, and did some tagging in another SharePoint site in the farm, ruling out that this had something to do with my SharePoint user. So I knew it had to be something related to my newly added web-application identity, having had problems with the search-driven tag cloud and tag profile pages in the past.

The solution is to grant the identity running the SharePoint web-applicaiton the correct connection permissions to the two service applications. My new web-application lacked permissions on the Managed Metadata Service application. Go to "Central Administration > Manage Service Applications", select the MMS application row in the list, and click "Permissions" in the ribbon to configure the connection permissions.


Add the managed account used as the service account for the web-application, and assign it permissions to read and add new terms to the MMS term store. Write access is required to allow users to apply tags never used before. Full access is not required. This will show and enable the "I Like It" button and the "Tags" tab in the popup dialog for "Tags & Notes" as expected.

Revoking the service application connection permissions for a web-application identity can be used to remove the social tagging and note board tools from contained sites. However, while the "I Like It" button is hidden when revoking access to MMS, the "Tags & Notes" button is not hidden when revoking access to UPA, rather a non-functional popup dialog is shown - not the best user experience. The following figure shows the effect of having access to MMS but not to UPA:


So, if there is something strange with the social tagging and related web-parts in your SharePoint 2010 solution, always make sure that web-applications identities and content crawler identity have applicable MMS and UPA service application connection permissions.

If you use the Note Board web-part, and it suddenly stopped working by not showing any existing notes and you cannot even add new ones - and only the web-part title is shown, then make sure that your Search Service Application (SSA) indexing is crawling properly. This can happen after applying e.g. a cumulative update. Remember that you can always check if the tags and notes database is operational using the UPA.