Building SharePoint 2016 development environment – Part 14 – Enterprise Search Centre


A few years ago I wrote “Build your SharePoint 2013 development machine on Windows Server 2012” series, I mainly work in the cloud now, but as the blogs was so popular, I thought I would create a new series for the newer version of SharePoint.

You can access other parts of this post below.

Creating a vanity name

  • Log into your domain controller. In Start type DNS and open the DNS Manager.
  • In the left hand pane, expand Forward Lookup Zones and click on cfcode2016.com
  • Right click on cfcode2016.com and select New Host (A or AAAA)…
  • Put in the name search, put the IP address point to the SharePoint Server. 192.168.137.200. Click Add Host

Search Centre Web application

We are now going to create a new Web Application for our Search center site. We are going to create a path-based site collection.

  1. From the start menu, type SharePoint 2016 Central Administration and open the site.
  2. Select Application Management > Manage Web Applications.
  3. In the ribbon click the New icon
  4. In the Create New Web Application dialog leave Create a new IIS web site selected and set up the following
    1. Name: SharePoint Search – 33333,
    2. Port:33333
    3. Host Header: <Leave Blank>
    4. Path: <Leave as default>
    5. Allow Anonymous: No
    6. Use Secure Sockets Layer (SSL): Yes
    7. Claims authentication Types: Leave as is, enabled, integrated, NTLM
    8. Application Pool: Search – 33333
    9. Select Security Account: CFCODE2016\SP_Search
    10. Database Name: SP_SearchDB
  5. Click OK.
  6. After Web Application created, click OK.

IIS Bindings and AAMs.

  • . In Start type IIS and open IIS Manager
  • Navigate to SharePoint Search -33333 and then on the right hand panel, click Bindings…
  • On the Bindings dialog, select the bindings for port 33333 and click Edit
  • Leave the host name blank, but select your certificate. Click Ok
  • Click Add
  • In the Add Site Binding page, select https from the Type dropdown, leave the IP address as All Unassigned, the Port should say 443. Ensure you tick Require Server Name Indication. Enter the Host name as search.cfcode2016.com then select your certificate. Click OK
  • Open SharePoint 2016 Central Administration and select Application Management then Configure alternative access mappings.
  • On the right of the screen, change the Alternate Access Mapping Collection to SharePoint Search -33333
  • Click on the only entry https://cfsp2016:33333 and edit it to say https://search.cfcode2016.com, click OK.
  • Click Add Internal URLs enter https://cfsp2016:33333 click Save.
  • Click Add Internal URLs enter https://cfsp2016.cfcode2016.com:33333 click Save.

Create Search Centre Site Collection

  1. From Central Administration landing page, select Application Management then select Create site collections
  2. Ensure the Web Application is https://search.cfcode2016.com then enter the following information:
    1. Title: Enterprise Search
    2. URL: /
    3. Template Selection: Enterprise > Enterprise Search Center
    4. Primary Site Collection Admin: SP_Setup
  3. Click OK.
  4. Once site is created, just click OK.

Give All users visitors access to Search.

  1. Once the site has been created, navigate to https://search.cfcode2016.com
  2. Go to Site Settings. Click the Cog icon at the top right of the page, then select Site Settings.
  3. Under Users and Permissions, click Site Permissions
  4. Click on Enterprise Search Visitors.
  5. On the menu bar, click New > Add Users
  6. Type and select Everyone. Click Share.

Configure Search Service Settings

  1. Back in Central Administration, select Application Management then Manage service applications.
  2. Click on Search Service Application.
  3. On the Search Service Application page, the top of the screen is already asking you Where should user’s searches go? Click on the location link.
  4. Enter the URL as https://search.cfcode2016.com. Click OK.

Note: At this point I uploaded a document to my intranet.cfcode2016.com site.

Search Content Sources

Here we are going to configure the Content Sources so that it searches and brings back the correct content.

  1. Open SharePoint 2016 Central Administration.
  2. Open Application Management > Manage Service application > Search Service Application
  3. In the Quick Launch menu on the left, under Crawling click Content Sources
  4. Click on Local SharePoint Sites.
  5. In the Start Address remove everything apart from the following :
    1. https://hnsc.cfcode2016.com
    2. https://hnsc.cfcode2016.com:11111
  6. Under Crawl Schedules we are going to set it up to run full crawl once a week and incremental once day. You may configure this differently or not at all for you environment. It really depends how much you need search to be up to date. It is quite an intensive resource process, and we are running everything on one box. Under Incremental Crawl,
    click on Create Schedule
  7. Set the Type as Daily. Accept the defaults and click OK.
  8. Under Full Crawl, click on Edit schedule. Set the Type as Weekly. Accept the defaults and click OK.
  9. Click OK
  10. Back on the Manage Content Source page, click New Content Source in the menu and fill out the following:
    1. Name: People
    2. Content Source Type: SharePoint Sites
    3. Start Addresses: https://my.cfcode2016.com
      sps3s://my.cfcode2016.com
    4. Crawl Settings: Crawl everything under the hostname for each start address
    5. Crawl Schedule: (Same as Local SharePoint Sites, use the dropdown)

Setting the Super User and Super Reader account

  1. Back in SharePoint 2016 Central Administration, select Application Management > Manage Web Applications.
  2. Select SharePoint HNSC Web Application and then click User Policy from the ribbon.
  3. On the Policy for Web Application dialog, click the Add Users on the menu.
  4. Accept (All Zones) then click Next.
  5. Add the user cfcode2016\SP_SuperUser and tick Full Control. Click Finish
  6. Repeat steps 3-5 for cfcode2016\SP_SuperReader and give Full Read rights.
  7. Click OK and close Policy for Web Application.

Kick off a full crawl

  1. Head back to the Search Service Application Service (Application Management > Manage Service Applications > Search Service Application.
  2. On the quick launch menu area, look for Content Sources under Crawling and click it.
  3. On the Manage Content Source page, click Start all crawls. This will kick of search crawling on your server.
  4. After crawling had finished, I headed to https://search.cfcode2016.com and searched for my document I uploaded earlier called “typescript”

Issue with People Search.

If you go to your People Search and type * but find no results come back, and you have followed everything correctly, I would ask you to check one thing.

  1. In SharePoint 2016 Central Administration, go to Application Management > Manage Service Applications. Then highlight the SharePoint User Profile Service Application.
  2. Click Administrator from the ribbon. Ensure that SP_Search is in there and has the permission Retrieve People Data for Search Crawlers, and ensure that SP_Farm is in there with Full Control.
  3. After updating this, run another full crawl, then try People search again.

We are almost at the end of the blog series on building a SharePoint 2016 development machine. Two more posts to go. Setting up workflows and setting up Visual Studio. Shut down your machines, take a checkpoint.

 

SharePoint 2013 Search not bring back all my results


As a developer sometimes you will be creating pages as demo content and use the helpful website Lorem Ipsum http://www.lipsum.com/ or Bacon Ipsum http://baconipsum.com/ or if you are into your pirates http://pirateipsum.me/ to help you generate your text.

Select the number of paragraphs you want, or the number of words, hit a button and then you get a clipboard full of text.

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce pellentesque quam eu metus hendrerit, vel venenatis augue tempus. Aliquam a libero et quam pellentesque venenatis ac sed odio. Morbi at velit ligula. Ut mattis nec lacus ut rhoncus. Fusce ac convallis mi. Pellentesque varius at purus et congue. Mauris commodo feugiat eros non bibendum. Maecenas scelerisque tortor eu purus sodales, ut lacinia ligula tempor.

Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Sed vulputate eget dui non accumsan. Donec non neque non ante vulputate fermentum. Quisque a magna at dolor adipiscing feugiat et sit amet mi. Morbi at consectetur est, eget auctor velit. Vestibulum rhoncus eros eu est elementum faucibus. Aenean tortor erat, aliquam hendrerit tincidunt nec, eleifend sit amet lorem. Nunc scelerisque ante commodo mauris facilisis, vel feugiat orci vehicula. Integer molestie tincidunt nisi, vitae ultricies sapien convallis ut. Quisque tincidunt, turpis in sagittis egestas, libero risus gravida turpis, id lacinia dolor ligula et diam. Suspendisse nec aliquam neque, rutrum hendrerit augue. Aenean id ipsum venenatis, iaculis ipsum et, volutpat tortor.

So I’ve created 10 different publishing pages (all with different page names, and different images in the publishing Image) and filled them all with 5 paragraphs each of Lorem Ipsum, and set off a full index crawl of the content. Using the Content Search Query webpart, the preview (with the right query) brings back all 10 pages. However once I have saved the query in the webpart, it only returns 1 result. The same with SharePoint Search, I know all my pages are based on the same content type, so in the search box I type ContentType:”Cann0nF0dder Page” but yet only one result comes back. However putting the name of the page in the search the individual pages do come back, so they are within the search index.

So what is happening? SharePoint is getting too clever for its own good. It’s seeing that the content on the pages are the same, and assuming they are duplicates. Therefore the search doesn’t show multiple results. With the Content Search Webpart, you can export the webpart, change the “ShowViewDuplicates” property, then re-import it.

I’d recommend that when you are using Lorem Ipsum, paste different paragraphs in your pages.

Debugging Display Templates


Display Template Series

Last in my series of Display Templates, I’m going to show you how to debug the JavaScript within a Display Template.

There is more than one way to skin a cat, so the saying goes, and this way I’m showing below isn’t the only way.

  1. Once your Display Template is uploaded to your Master Page Gallery, and you have assigned it to your Content Search WebPart, load the page in the browser and then hit F12 to load up the IE developer toolbar. (Obviously you can use Firebug in Firefox if that’s your preferred choice of browser).
  2. Switch the tab to Script. In the drop down list of scripts currently running on your page, find the corresponding .js file to your Display Template.
  3. After selecting it, insert your breakpoint where you wish, and then click the Start debugging link at the menu bar area.
  4. The page will refresh, and when your JavaScript breakpoint is reached, you can then step through the code, and add Watch where needed.

Display Templates and the ManagedPropertyMapping Custom Element.


Display Template Series

Following on from my previous blog Content Search WebPart and Display Templates, I wish to take this further and show how to obtain the properties returned in the search.

In the Header properties of a Display Template, there is a Custom Element called ManagedPropertyMapping. This element Maps fields exposed by search result items into properties available for JavaScript. Used only in item templates.

According to Microsoft the property is comma-delimited list of values that use the following format:

‘property display name'{property name}:’managed property’
example: ‘Known As'{knownas}:’PreferredName’

However while testing to ensure this blog is correct, I’m finding that the property display name and property name is actually the other way round. The examples Microsoft uses always has the property display name and the property name the same. The below picture is setting the ManagedPropertyMapping to the example above.

The below picture is if I swap the property display name and property name around. ( ‘property name'{property display name}:’managed property’ )
example: ‘knownas'{Known As}:’PreferredName’

As you can see from the above pictures, I believe property name and property display name are the opposite way round to what Microsoft have stated.

Property display name
is the property name that shows in the Web Part editing pane when the display template is selected.

Property name is the identifier, in script when obtaining the value of the managed property use would use the property name to call it.

Managed property is a string of one or more managed properties, separated by semicolons. Only in the display template you can map multiple managed properties, when you override using the WebPart edit pane, you can only select one managed property. When multiple properties are selected, they are read in order, and the first value that matches the name of a managed property of the current search item will have its value mapped.

Once a property has been mapped, you can then call it within the JavaScript of the DIV tag section. To obtain a value you would call $getItemValue() passing in current context and the property name. (‘property Name‘{property display name}:’managed property’)

var knownAsValue = $getItemValue(ctx, "knownas");

To use the above variable within the HTML

<div class="cbs-KnownAs ms-nowrap">_#= knownAsValue =#_</div>
 


Content Search WebPart and Display Templates


Display Template Series

In my previous post Brief Introduction into Display Templates I gave an overview of what a Display Template is. In this post I hope to delve a little deeper and show how they are used with Content Search WebParts.

When you add a Content Search WebPart or a Search Result WebPart when you configure the Web Part, you have to select a control and an item display template.

A Control Template is used to show how the results are presented, an HTML structure of the overall layout. The surrounding area that will contain all items returned. For example it could be the heading and footer. The control template is only rendered once within the WebPart.

An Item Template provides the HTML display for an item in the search results. This template will be called for each item in the result set. This allows you to define the layout of the item.

So when the WebPart uses them together it creates a rendered piece of HTML for the webpart.

A display template structure is made up of four main sections. Title, Header properties, Script Block and a DIV block.

Title

Very simply this is the display name that is found in the Display Template sections of the WebPart edit pane.

 <title> My Display Name </title>
 

Header Properties

Following on from the title tag, there is a set of custom elements which provide information about the display template to SharePoint. These elements are surrounded by the following XML markup:

<!--[if gte mso 9]><xml>
<mso:CustomDocumentProperties>
…
</mso:CustomDocumentProperties>
</xml><![endif]-->

An example of an element would be;

<mso:TemplateHidden msdt:dt="string">0</mso:TemplateHidden>
<mso:MasterPageDescription msdt:dt="string">Displays a result tailored for a picture.</mso:MasterPageDescription>

The different properties and descriptions are described here (Taken directly from the Microsoft Website):

Property Description
TemplateHidden Boolean value that indicates whether to hide the display template from the list of available templates in the Web Part. This value can be changed in the display template file properties.
ManagedPropertyMapping Maps fields exposed by search result items into properties available for JavaScript. Used only in item templates.
MasterpageDescription Provides a friendly description of the display template. This is shown to users in the SharePoint editing environment. This value can be changed in the display template file properties.
ContentTypeId The ID of the content type associated with the display template
TargetControlType Indicates the context in which the display template is used. This value can be changed in the display template file properties.
HtmlDesignAssociated Boolean value that indicates whether a display template HTML file has a .js file associated with it.
HtmlDesignConversionSucceeded Indicates whether the conversion process was successful. This value is automatically added to the file by SharePoint, and is used only in custom display templates.
HtmlDesignStatusAndPreview Contains the URL to the HTML file and the text for the Status column (either Conversion successful or Warnings and Errors). This value is automatically added to the file by SharePoint, and is used only in custom display templates.

Script block

The script block is an area where you can add links to include internal, external JavaScript of CSS. You can use SharePoint tokens such as ~sitecollection to obtain URLs. An example shown below:

<script>
   $includeScript(this.url, <a href="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js">http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js</a>);
   $includeCSS(this.url, "style library/Slider/css/MySearchWebPartStyle.css");
 </script>

DIV block

The final part is a DIV block with an ID that matches the name of the HTML file. All HTML and code that you want the display template to use must be written within this DIV tag. Please note that this DIV tag is not rendered on the webpage at runtime. As I stated in previous blog, JavaScript code sits within comment blocks that start with <!–#_ and ends with _#–>. HTML sits outside these blocks. You can also uses these blocks control the HTML with conditional statements. Inside HTML attributes that are making script calls or using JavaScript variables need to start with _#= and end with =#_ comment blocks.

Example below taken from the Control_List.html file.

<div id="Control_List">
 <!--#_
 if (!$isNull(ctx.ClientControl) &&
 !$isNull(ctx.ClientControl.shouldRenderControl) &&
 !ctx.ClientControl.shouldRenderControl())
 {
 return "";
 }
 ctx.ListDataJSONGroupsKey = "ResultTables";
 var $noResults = Srch.ContentBySearch.getControlTemplateEncodedNoResultsMessage(ctx.ClientControl);

var noResultsClassName = "ms-srch-result-noResults";

var ListRenderRenderWrapper = function(itemRenderResult, inCtx, tpl)
 {
 var iStr = [];
 iStr.push('<li>');
 iStr.push(itemRenderResult);
 iStr.push('</li>');
 return iStr.join('');
 }

ctx['ItemRenderWrapper'] = ListRenderRenderWrapper;
 _#-->
 <ul class="cbs-List">
 _#= ctx.RenderGroups(ctx) =#_
 </ul>
 <!--#_
 if (ctx.ClientControl.get_shouldShowNoResultMessage())
 {
 _#-->
 <div class="_#= noResultsClassName =#_">_#= $noResults =#_</div>
 <!--#_
 }

_#-->
 </div>
 

You can use jQuery within your display templates, you must include the jQuery library in your Script Block. Also because jQuery is used to using the # symbol, which is also required in the templates, to reference an ID Selector using jquery it is recommend to use the following code;

var containerQueryId = ‘#’ + ‘_#= containerId =#_’;
$(‘_#= containerQueryId =#_’);

Display Template for Content Search WebPart.

When creating a Display Template it is recommend to copy an existing HTML display template that is similar to the one you wish to create. Once you have copied it and renamed, and reconfigured it, and saved it back to the Master Page Gallery, you will find a corresponding .js file automatically created for you.

By browsing to your publishing site, in the upper right corner of the page, choose Settings, and then choose Design Manager.

In Design Manager, in the left panel area, choose Edit Display Templtes. Your HTML file will now appear with a Status column that will either show “Warnings and Errors” or “Conversion successful”. Please note that Approval Status is set to “Draft” and you need to publish any files added to the Master Page Gallery from within the Master Page Gallery. Once you have converted the template successfully, but going to your web page with eth Content Search Web Part on, when editing you will now see your new template in the corresponding Display Template Control or item.

Brief Introduction into Display Templates


Display Template Series

In SharePoint 2013, for search result Web Part you have the ability to customise your search results. Yes in 2010 you could customise the content query Web Part and search results, but you had to use XSLT to do this. Something I never got round to learning.

In 2013 you have the feature of display templates. Display templates are the combination of html and generated JavaScript which enable the customisation of search results. Used in Search WebParts, Display templates control which managed properties are shown in the search results, and how they appear in the Web Part. You can find the display templates on the site by navigating to;

Site Settings > Master Page Gallery > Display Templates

The Search folder is where the files relevant for the Search Results Web Part are kept. The Content Web Parts folder is where the files relevant for the Content Search Web part are kept.  Now this is the gotcha that made me spend half my morning getting nowhere. If you only see just the .js files within any folder underneath Display Templates, it means you do not have the site collection feature “SharePoint server Publishing Infrastructure” activated. Once this feature is activated, you will see all HTML and corresponding .js files.

Create your own Display Template

I was going to write a step by step guide on how to create your own Display Template, but I believe a simple example by Erik Swenson is a good walkthrough video. http://erikswenson.blogspot.co.uk/2013/01/sharepoint-2013-display-templates.html All I can advise is;

  • Only ever modify the .HTML files. When you upload the html file back into the Display Template folder it will automatically produce the .js file for you.
  • Any JavaScript written within the HTML files needs to be surrounded by <!–#_ javascriptcode _#–> and any reference to JavaScript within HTML attributes needs to be surrounded by _#javascriptcode#_

Reference: http://msdn.microsoft.com/en-us/library/office/jj945138.aspx