Wednesday 24 February 2010

Define Site-Level Search scopes using master pages

Introduction

My client has a custom public facing Web Content Management SharePoint solution on the web. Their requirement is that within certain areas of this public site searches submitted by users only search the current area they are in.

To achieve this; a Search Scope was created specific to each site using Microsoft Office SharePoint Server, Shared Services provider. A search scope defines a subset of information in the search index. Normally used in the context of allowing a user to select a search scope when performing a search in order to restrict search results to within that search scope. Typically, search scopes encompass specific topics and content sources that are important and common to users in the organization and selection of the desired search scope is done using the standard SearchBox web part for MOSS providing a drop down to the user.

In our scenario; searches are taking place from one central input control on the Master Page of the site collection and our search scope selection is based definitively on the current area of the site in which the user performs the search.

Use Example: If a user navigates to: http://sharepointsite.com/subsite/contentsite/. Our user is in the current site “contentsite” which in this case is a site collection defaulting to the “/pages” with no document libraries, lists or additional content as it is a public facing SharePoint site. When a user submits a search from this site his returned results should be all pages and documents within the Trustees site and its subsites without returning unnecessary SharePoint content.

Defining Search Scopes for Public Facing SharePoint Site

our site is a public facing WCM (Web Content Management) version of SharePoint and configuring search on this site is more advanced than on an out-of-box Intranet or publishing solution. Standard SharePoints search results include all content of the site, its subsites and all of the resource content such ass CSS, JavaScript, XSL, Images, Administration list, User Profiles and more. For public facing site the search experience must only return relevant results based on the content and context of the web site.

Search Scope Configuration

Searches using these scopes will return anything that is in the content source “Site” AND (the content is a publishing page OR the content is a document). If you need to know more about defining content sites, click here

The logic of these rules are as follows:

  • Include = OR
  • Require = AND
  • Exclude = AND NOT

The ‘contentclass’ property specifies what type the indexed item is and will be automatically available for any content item in SharePoint. The two types that we are specifically targeting are:

  • STS_ListItem_850 (Publishing Pages)
  • STS_ListItem_DocumentLibrary (Documents)

SubsiteA

Title:

SubsiteA

Description:

Search scope specific to SubsiteA site & subsites

Rules

Behavior

Folder = http://SharePointSite.com/SubsiteA

Require

contentclass = STS_ListItem_850

Include

contentclass = STS_ListItem_DocumentLibrary

Include

ContentSource = Site

Require

Search Field Customisation

Determining which search scope is to be used is done programmatically. Search queries are inputted using a field on the master pages of the site rather than an independent control on the page or web part. This means that on the event where a user submits a search it will execute a search query against the Enterprise Search in Microsoft Office SharePoint Server 2007 service by encoding the query in a URL and posting it to the custom search page.

When doing this we are passing two parameters: http://SharepointSite.com/Utils/Pages/SearchSite.aspx?k=Keyword&s=SubsiteA

  • K=”Keywords” – The keywords submitted by our user
  • S=”Scope” – The scope which will be used to run our query against

Posting from master page

Before implementation of this solution, the search button event posted just the keyword to the search centre producing a site collection level search:

protected void ImageButtonSearch_Click(Object sender, ImageClickEventArgs e)

{
Page.Response.Redirect("/Utils/Pages/SearchSite.aspx?k=" + txt_Search.Text);
}

http://SharePointSite.com/Utils/Pages/SearchSite.aspx?k=Keyword

This has been extended to:

protected void ImageButtonSearch_Click(Object sender, ImageClickEventArgs e)

{

SPSite site = new SPSite(Page.Request.Url.AbsoluteUri);
SPWeb web = site.OpenWeb();
string strSiteTitle = web.Title;
string strParentSite = web.ParentWeb.Title;

if (strSiteTitle == "SubsiteA" || strParentSite == "SubsiteA")
{
Page.Response.Redirect("/Utils/Pages/SearchSite.aspx?k=" + txt_Search.Text + "&s=SubsiteA");
}

else

{

Page.Response.Redirect("/Utils/Pages/SearchSite.aspx?k=" + txt_Search.Text);

}

}

This code utilises the Microsoft SharePoint 2007 development API first of all opening a connection to the current site. Once the connection is open the Site Title and the Parent Site Title are stored.

The code then checks if the Site Title or Parent Site Title matches the conditions that it is one of our site level search enabled sites. At which point it passes the extended url string to the search centre including which scope to use. In our case any searches within the upper level subsite area and all of its subsites are included. A more specific rule can be created by removing the parentsite condition.

NOTE: The name of the scope being used must be identical to the Title of the search scope and case sensitive. An invalid scope title passed into the query will return zero search results with no error.

Deployment

Presently the above code is deployed by being produced on each master page used by selected pages in the scope of this implementation. For future implementations it may be more appropriate to develop and install a custom SharePoint Feature which processes all search queries across the entire site. This would be viable on a larger scale implementation where by each site (every site) had predefined processes and search scope requirements.

The scope of this implementation is focused on the above pages and does not justify the design, development, deployment and testing requirements of implementing a site wide custom search handler feature although that would probably be the best way to do it.