Making SharePoint 2010 search pages work with a proper master page

Posted by Rik Hepworth on Thursday, May 12, 2011

If you talk to those who know me about my pet hates in SharePoint, the search pages will come up every time. It’s not that I hate search itself – that’s great, but the minimal.master is just plain annoying. It makes the search centre a black hole into which you can fall but not navigate out of – there’s no navigation and the portal site connection doesn’t work.

I’ve been meaning to get search working with a real master page (step forwards, v4.master) for a while and never got around to it. However, I needed to fix it for a demo and having done so I thought I’d document the steps involved for the world.

To set the scene, here are some screenshots of the default Enterprise Search Centre pages:

default searchcentre
default searchcentre

default searchresults
default searchresults

default peopleresults
default peopleresults

If you climb into site settings and change the Site Master Page to v4.master, this is what you get:

v4 master search page
v4 master search page

That’s not very usable, is it. Moreover, if you click the breadcrumbs/portal site connection icon in the top bar you see the following:

v4 master search page with search box
v4 master search page with search box

That’s just barking mad, frankly. However, it does give us a solid clue as to how we go about fixing the page.

Step 1: Fix the layout pages

I had a rummage around the search centre’s masterpage folder and found the cause of our problems. Some bright spark decided to use the PlaceHolderTitleBreadcrumb as the content area to put the search box in. That speaks more about the structure of the minimal.master page than the search layout pages, to be fair. It is most definitely not where it should be, however.

Using SharePoint Designer, open your Search Centre SharePoint site and look in the _catalogs\masterpage folder. In there you will see three page layouts: SearchMain.aspx, SearchResults.aspx and ReopleSearchResults.aspx.

sharepoint designer masterpages highlighted
sharepoint designer masterpages highlighted

Let’s do SearchMain first – the site landing page. Right-click the file and choose Edit File in Advanced Mode

Step 1a: Move the search box to the right place

Find the line that reads:

<asp:Content ContentPlaceHolderID="PlaceHolderTitleBreadcrumb" runat="server">

You want to cut the markup that is inside that content placeholder:

<SharePoint:UIVersionedContent UIVersion="3" runat="server">  
<ContentTemplate>  
<div style="height:100%; width:100%;padding-left: 18px; padding-top: 50px; padding-bottom: 10px;">  
<center>  
<div style="width: 510px">  
<SPSWC:ListBoundTabStrip ID="Tab" runat="server" PersistQueryString="true" CSSClassNamePrefix="ms-sctab" ListName="<%$Resources:Microsoft.Office.Server.Search,SearchCenterOnet_SearchCenterListName%>" ResourceIdforListName="$Resources:Microsoft.Office.Server.Search,SearchCenterOnet_SearchCenterListName" UnselectedTabTrimLength="-1"></SPSWC:ListBoundTabStrip>  
<div style="padding-top: 0px">  
</ContentTemplate>  
</SharePoint:UIVersionedContent>  
<SharePoint:UIVersionedContent UIVersion="4" runat="server">  
<ContentTemplate>  
<div class="srch-sb-main">  
<div class="srch-sb-results4">  
<div>  
<SPSWC:ListBoundTabStrip ID="Tab1" runat="server" CSSFileName="Themable/search.css" PersistQueryString="true" CSSClassNamePrefix="ms-sctab" ListName="<%$Resources:Microsoft.Office.Server.Search,SearchCenterOnet_SearchCenterListName%>" ResourceIdforListName="$Resources:Microsoft.Office.Server.Search,SearchCenterOnet_SearchCenterListName" UnselectedTabTrimLength="-1"></SPSWC:ListBoundTabStrip>  
</div>  
<div class="srch-sb-results6">  
</ContentTemplate>  
</SharePoint:UIVersionedContent>  
<WebPartPages:WebPartZone runat="server" AllowPersonalization="false" FrameType="TitleBarOnly" Title="<%$Resources:Microsoft.Office.Server.Search,LayoutPageZone_TopZone%>" ID="TopZone" Orientation="Vertical" QuickAdd-GroupNames="Search" QuickAdd-ShowListsAndLibraries="false"><ZoneTemplate>  
<WpNs0:SearchBoxEx runat="server" __MarkupType="xmlmarkup" WebPart="true" __WebPartId="{C00D0719-CF8A-47A2-9E31-FA3F6A38948F}" >  
<WebPart xmlns:xsi="[http://www.w3.org/2001/XMLSchema-instance"](http://www.w3.org/2001/XMLSchema-instance") xmlns:xsd="[http://www.w3.org/2001/XMLSchema"](http://www.w3.org/2001/XMLSchema") xmlns="[http://schemas.microsoft.com/WebPart/v2"](http://schemas.microsoft.com/WebPart/v2")>  
  <Title>Search Box</Title>  
  <FrameType>None</FrameType>  
  <Description>Displays a search box that allows users to search for information.</Description>  
  <IsIncluded>true</IsIncluded>  
  <ZoneID>TopZone</ZoneID>  
  <PartOrder>1</PartOrder>  
  <FrameState>Normal</FrameState>  
  <Height />  
  <Width>800px</Width>  
  <AllowRemove>true</AllowRemove>  
  <AllowZoneChange>true</AllowZoneChange>  
  <AllowMinimize>true</AllowMinimize>  
  <AllowConnect>true</AllowConnect>  
  <AllowEdit>true</AllowEdit>  
  <AllowHide>true</AllowHide>  
  <IsVisible>true</IsVisible>  
  <DetailLink />  
  <HelpLink />  
  <HelpMode>Modeless</HelpMode>  
  <Dir>Default</Dir>  
  <PartImageSmall />  
  <MissingAssembly>Cannot import this Web Part.</MissingAssembly>  
  <PartImageLarge />  
  <IsIncludedFilter />  
  <ExportControlledProperties>true</ExportControlledProperties>  
  <ConnectionID>00000000-0000-0000-0000-000000000000</ConnectionID>  
  <ID>g_c00d0719_cf8a_47a2_9e31_fa3f6a38948f</ID>  
  <GoImageUrl xmlns="urn:schemas-microsoft-com:SearchBoxEx">/_layouts/images/gosearch30.png</GoImageUrl>  
  <GoImageUrlRTL xmlns="urn:schemas-microsoft-com:SearchBoxEx">/_layouts/images/gosearchrtl30.png</GoImageUrlRTL>  
  <GoImageActiveUrl xmlns="urn:schemas-microsoft-com:SearchBoxEx">/_layouts/images/gosearchhover30.png</GoImageActiveUrl>  
  <GoImageActiveUrlRTL xmlns="urn:schemas-microsoft-com:SearchBoxEx">/_layouts/images/gosearchrtlhover30.png</GoImageActiveUrlRTL>  
  <ShowAdvancedSearch xmlns="urn:schemas-microsoft-com:SearchBoxEx">true</ShowAdvancedSearch>  
  <DropDownModeEx xmlns="urn:schemas-microsoft-com:SearchBoxEx">HideScopeDD</DropDownModeEx>  
  <IsMysiteSearchBox xmlns="urn:schemas-microsoft-com:SearchBoxEx">false</IsMysiteSearchBox>  
  <TextBoxWidth xmlns="urn:schemas-microsoft-com:SearchBoxEx">368</TextBoxWidth>  
  <ShowPerferenceLink xmlns="urn:schemas-microsoft-com:SearchBoxEx">true</ShowPerferenceLink>  
  <ShowQuerySuggestions xmlns="urn:schemas-microsoft-com:SearchBoxEx">true</ShowQuerySuggestions>  
  <SearchBoxVisual xmlns="urn:schemas-microsoft-com:SearchBoxEx">SearchCenterDefault</SearchBoxVisual>  
  <AdvancedSearchPageURL xmlns="urn:schemas-microsoft-com:SearchBoxEx">/searchcentre/Pages/advanced.aspx</AdvancedSearchPageURL>  
  <SearchResultPageURL xmlns="urn:schemas-microsoft-com:SearchBoxEx">results.aspx</SearchResultPageURL>  
  <RegisterStyles xmlns="urn:schemas-microsoft-com:SearchBoxEx">true</RegisterStyles>  
  <ShouldTakeFocusIfEmpty xmlns="urn:schemas-microsoft-com:SearchBoxEx">true</ShouldTakeFocusIfEmpty>  
</WebPart>  
</WpNs0:SearchBoxEx>  
</ZoneTemplate></WebPartPages:WebPartZone>  
</div>  
</div>  
<SharePoint:UIVersionedContent UIVersion="3" runat="server">  
<ContentTemplate>  
</center>  
</ContentTemplate>  
</SharePoint:UIVersionedContent>  
</div>  

That code needs to be pasted into the PlaceHolderMain content area, just after the markup to open the content area:

<asp:Content ContentPlaceHolderID="PlaceHolderMain" runat="server">

Save the file and take a look, and you should see this:

edited search centre 1
edited search centre 1

It’s not quite right – everything’s shifted to the left. We’ll come back to that because it’s not fixable by editing the layout pages.

You’ll also notice that there are no breadcrumbs at all so no portal connection.

Step 1b: Fix the breadcrumbs

We’ll need to get the correct code for the breadcrumbs from another layout page. I grabbed it from the article page layout. It needs to go inside the PlacholderTitleBreadcrumb content area markup.

<SharePointWebControls:VersionedPlaceHolder UIVersion="3" runat="server">  
<ContentTemplate>  
<asp:SiteMapPath ID="siteMapPath" runat="server" SiteMapProvider="CurrentNavigation" RenderCurrentNodeAsLink="false" SkipLinkText="" CurrentNodeStyle-CssClass="current" NodeStyle-CssClass="ms-sitemapdirectional"/>  
</ContentTemplate>  
</SharePointWebControls:VersionedPlaceHolder>  
<SharePointWebControls:UIVersionedContent UIVersion="4" runat="server">  
<ContentTemplate>  
<SharePointWebControls:ListSiteMapPath runat="server" SiteMapProviders="CurrentNavigation" RenderCurrentNodeAsLink="false" PathSeparator="" CssClass="s4-breadcrumb" NodeStyle-CssClass="s4-breadcrumbNode" CurrentNodeStyle-CssClass="s4-breadcrumbCurrentNode" RootNodeStyle-CssClass="s4-breadcrumbRootNode" NodeImageOffsetX=0 NodeImageOffsetY=353 NodeImageWidth=16 NodeImageHeight=16 NodeImageUrl="/_layouts/images/fgimg.png" HideInteriorRootNodes="true" SkipLinkText="" />  
</ContentTemplate>  
</SharePointWebControls:UIVersionedContent>  

However, if you save the page and view it now you’ll get an error, because that markup references controls that the page doesn’t know about. In order to register them, we need to add a line into the section at the top of the page code that registers tag prefixes:

<%@ Register Tagprefix="SharePointWebControls" Namespace="Microsoft.SharePoint.WebControls" Assembly="Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>

The SearchMain.aspx layout page will  now work with the v4.master selected.

You’ll notice, however, that the ribbon isn’t quite right. That’s because it’s actually in twice – one in the v4.master and once in SearchMain.

Step 1c: Fix the ribbon

Find the following markup:

<asp:Content ContentPlaceHolderID="SPNavigation" runat="server">

After that line you’ll see another that reads:

<SharePoint:UIVersionedContent UIVersion="4" runat="server">

Right-click the tag and choose ‘select Tag’ from the context menu. Remove the highlighted code and you should be left with an empty SPNavigation content area. If you look at the page now, the ribbon works as it should.

Run through the same steps with the other search pages. I’m a bit paranoid, so whilst I’m pretty sure the content of the PlaceHolderTitleBreadcrumb is the same for all the layout pages, I always copy and paste the code within the page itself, then add the breadcrumb code afterwards.

You should now have a Search Centre that looks like this:

edited search centre 2
edited search centre 2

edited searchresults
edited searchresults

edited peopleresults
edited peopleresults

Step 2: Fix the master page

I said that the annoying shift to the right couldn’t be fixed in the layout pages. We need to edit the master page for that (and/or the styles if you like, but the master page is quicker for just one site).

Remember: Editing the v4.master page will prevent it being updated if Microsoft release SharePoint patches that include a new version, as we’ve modified the local copy in the site. If you want to be a good SharePoint admin, create a new master page for the search site!

This bit’s easy. Search for the line:

<div class="s4-ca s4-ca-dlgNoRibbon" id="MSO_ContentTable">

Edit it to read:

<div class="s4-ca s4-ca-dlgNoRibbon" id="MSO_ContentTable"  style="margin-left:0;">

All we’ve done is added a local styling rule to override the ones in the main stylesheets and set the left margin on that element to zero.

Save the master page and you should now get pages that look like this:

edited search centre 3
edited search centre 3

[

edited searchresults 2
edited searchresults 2

[

edited peopleresults 2
edited peopleresults 2

Still to do…

Before you all shout at me, I know that the breadcrumbs don’t display like they ought to. I need to look into that – I remember reading somewhere that they work differently on pages in a page library than elsewhere. I need to do some research and see if I can fix that. Hey – isn’t ditching the minimal.master enough for you?

Next on the hit list – Access Services sites using minimal.master!