By using my Skybrud.Umbraco.GridData package (which introduces a strongly typed model for the Grid), indexing the new Grid in Umbraco 7.2 is quite easy.
At Skybrud.dk we typically create a class named ExamineIndexer
that takes care of the Examine related events. This class should be initalized during Umbraco startup like this:
using Umbraco.Core;
namespace FanoeTest {
public class Startup : ApplicationEventHandler {
private static ExamineIndexer _examineIndexer;
protected override void ApplicationStarted(UmbracoApplicationBase umbracoApplication, ApplicationContext applicationContext) {
// Register events for Examine
_examineIndexer = new ExamineIndexer();
}
}
}
The ExamineIndexer
class it self will now look like the example below. The example is very specific, since only certain document types where we know that the content
property holds a Grid value are handled.
The example could be modified to use the Content Service for finding all properties that holds a Grid value. But since the Content Service uses the database, it may slow the performance when building your index.
using System;
using System.Text;
using System.Text.RegularExpressions;
using System.Web;
using Examine;
using Examine.Providers;
using Skybrud.Umbraco.GridData;
using Skybrud.Umbraco.GridData.Values;
using Umbraco.Core.Logging;
namespace FanoeTest {
public class ExamineIndexer {
public ExamineIndexer() {
BaseIndexProvider externalIndexer = ExamineManager.Instance.IndexProviderCollection["ExternalIndexer"];
externalIndexer.GatheringNodeData += OnExamineGatheringNodeData;
}
private void OnExamineGatheringNodeData(object sender, IndexingNodeDataEventArgs e) {
try {
string nodeTypeAlias = e.Fields["nodeTypeAlias"];
LogHelper.Info<ExamineIndexer>("Gathering node data for node #" + e.NodeId + " (type: " + nodeTypeAlias + ")");
if (nodeTypeAlias == "Home" || nodeTypeAlias == "LandingPage" || nodeTypeAlias == "TextPage" || nodeTypeAlias == "BlogPost") {
string value;
if (e.Fields.TryGetValue("content", out value)) {
LogHelper.Info<ExamineIndexer>("Node has \"content\" value\"");
GridDataModel grid = GridDataModel.Deserialize(e.Fields["content"]);
StringBuilder combined = new StringBuilder();
foreach (GridControl ctrl in grid.GetAllControls()) {
switch (ctrl.Editor.Alias) {
case "rte": {
// Get the HTML value
string html = ctrl.GetValue<GridControlRichTextValue>().Value;
// Strip any HTML tags so we only have text
string text = Regex.Replace(html, "<.*?>", "");
// Extra decoding may be necessary
text = HttpUtility.HtmlDecode(text);
// Now append the text
combined.AppendLine(text);
break;
}
case "media": {
GridControlMediaValue media = ctrl.GetValue<GridControlMediaValue>();
combined.AppendLine(media.Caption);
break;
}
case "headline":
case "quote": {
combined.AppendLine(ctrl.GetValue<GridControlTextValue>().Value);
break;
}
}
}
e.Fields["content"] = combined.ToString();
} else {
LogHelper.Info<ExamineIndexer>("Node has no \"content\" value\"");
}
}
} catch (Exception ex) {
LogHelper.Error<ExamineIndexer>("MAYDAY! MAYDAY! MAYDAY!", ex);
}
}
}
}
Hi Anders
Thanks for the example code, looking forward to check it out, and the package.
I hope you can help with a question.
I would like to put some boost on things like the 'headline' or a part of the RTE field?
Thanks in advance :)