Widgets content and Pages index
This article will explain how you can show the content of the widgets in Smart search results when using Pages index.
Rather than discussing this issue theoretically, let’s dive into some real example. Let’s suppose we have page called myPage (CMS.MenuItem), on this page we have Editable Region web part and inserted some text on the Page tab. If we want to display this text in the body of search result item, all we need to do is to ensure that Content field is set to DocumentContent. For CMS.MenuItem page type, it is set by default, but you can double check that in Page types application -> edit CMS.MenuItem page type -> Search fields section.
You will need to use the following approach to make the content searchable when you are using Widgets to store the content of the page. Since Web Parts and Widgets work a little bit differently you will need to implement the following customization. In the example below I am using Rich Text Widget to store the content of the page.
First I need to open my Kentico project in Visual Studio and create a new class called SmartSearchContentLoaderAttribute in App_Code folder. It will have the following content:
using CMS.Base;
using CMS.DocumentEngine;
using CMS.Helpers;
using CMS.Membership;
using CMS.SiteProvider;
[SmartSearchContentLoader]
public partial class CMSModuleLoader
{
/// <summary>
/// Attribute class for assigning event handlers.
/// </summary>
private class SmartSearchContentLoaderAttribute : CMSLoaderAttribute
{
/// <summary>
/// Called automatically when the application starts.
/// </summary>
public override void Init()
{
// Assigns a handler to the GetContent event for pages
DocumentEvents.GetContent.Execute += OnGetPageContent;
}
private void OnGetPageContent(object sender, DocumentSearchEventArgs e)
{
TreeNode currentIndexedPage = e.Node;
if (currentIndexedPage != null)
{
PageInfo pageInfo = PageInfoProvider.GetPageInfo(SiteContext.CurrentSiteName, currentIndexedPage.NodeAliasPath, "en-us",
currentIndexedPage.DocumentUrlPath, currentIndexedPage.NodeID, SiteContext.CurrentSite.CombineWithDefaultCulture);
if (pageInfo != null)
{
CMS.PortalEngine.PageTemplateInstance templateInst = pageInfo.DocumentTemplateInstance;
CMS.PortalEngine.WebPartZoneInstance webpartZoneInst = templateInst.GetZone("zoneA");
if (webpartZoneInst != null)
{
foreach (CMS.PortalEngine.WebPartInstance inst in webpartZoneInst.WebParts)
{
string widgetText = ValidationHelper.GetString(inst.GetValue("text"), "");
e.SearchDocument.AddGeneralField("testField", widgetText, true, true);
}
}
}
}
}
}
}
The class above creates a new field called testField in your index and stores the content of the widget into this field. More information about customizing the content of search indexes could be found here https://docs.kentico.com/display/K9/Customizing+the+content+of+search+indexes . All you need to do now is to change the transformation which renders the Smart search results. For example by default you will display the content using Eval("Content") however when this method returns empty string you will use GetSearchValue("testField") instead, which returns the content of the widget. You can take a look at this page how to display search results using transformation https://docs.kentico.com/display/K9/Displaying+search+results+using+transformations