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);
}
}
}
}
Hello,
I am trying to index my grid data, but after updating to Umbraco 7.3.3 (from 7.2.2), I am getting some exceptions when using GridDataModel.Deserialize(e.Fields["myGrid"])
The error + stacktrace is as follows:
The griddata which produced this error is the following
Do you have a suggestion as to what might have gone wrong here?
Regards Peter
EDIT:
I downloaded the source code, built the dll and used it in my project - works like a charm. I guess maybe the Nuget package is not quite up to date?
EDIT#2:
Looks like the package has now been updated, https://github.com/skybrud/Skybrud.Umbraco.GridData/releases/tag/v1.5.1