Skip to content

Instantly share code, notes, and snippets.

@leekelleher
Last active April 27, 2021 15:03
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save leekelleher/691667dc4b0ddbf06b44c006f1e12f1d to your computer and use it in GitHub Desktop.
Save leekelleher/691667dc4b0ddbf06b44c006f1e12f1d to your computer and use it in GitHub Desktop.
Contentment: Examine (Lucene) data-source
/* Copyright © 2021 Lee Kelleher.
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
using System.Collections.Generic;
using System.Linq;
using Examine;
using Examine.Search;
using Umbraco.Core;
using Umbraco.Core.IO;
using Umbraco.Core.PropertyEditors;
using UmbConstants = Umbraco.Core.Constants;
namespace Umbraco.Community.Contentment.DataEditors
{
public sealed class ExamineDataListSource : IDataListSource
{
private readonly IExamineManager _examineManager;
private const string _defaultNameField = "nodeName";
private const string _defaultValueField = "__Key";
private const string _defaultIconField = "__Icon";
public ExamineDataListSource(IExamineManager examineManager)
{
_examineManager = examineManager;
}
public string Name => "Examine Query";
public string Description => "Populate the data source from an Examine query.";
public string Icon => "icon-search";
public OverlaySize OverlaySize => OverlaySize.Small;
public IEnumerable<ConfigurationField> Fields => new ConfigurationField[]
{
new ConfigurationField
{
Key = "examineIndex",
Name = "Examine Index",
Description = "Select the Examine index.",
View = IOHelper.ResolveUrl("~/App_Plugins/Contentment/editors/dropdown-list.html"),
Config = new Dictionary<string, object>
{
{ "allowEmpty", "0" },
{ "items", _examineManager.Indexes.OrderBy(x => x.Name).Select(x => new DataListItem { Name = x.Name.SplitPascalCasing(), Value = x.Name }) },
}
},
new ConfigurationField
{
Key = "luceneQuery",
Name = "Lucene query",
Description = "Enter your raw Lucene expression to query Examine with.",
View = IOHelper.ResolveUrl("~/App_Plugins/Contentment/editors/code-editor.html"),
Config = new Dictionary<string, object>
{
{ "mode", "text" },
{ "minLines", 1 },
{ "maxLines", 5 },
}
},
new ConfigurationField
{
Key = "nameField",
Name = "Name Field",
Description = "Enter the field name to select the name from the Examine record.",
View = "textstring",
},
new ConfigurationField
{
Key = "valueField",
Name = "Value Field",
Description = "Enter the field name to select the value (key) from the Examine record.",
View = "textstring",
},
new ConfigurationField
{
Key = "iconField",
Name = "Icon Field",
Description = "<em>(optional)</em> Enter the field name to select the icon from the Examine record.",
View = "textstring",
},
new ConfigurationField
{
Key = "descriptionField",
Name = "Description Field",
Description = "<em>(optional)</em> Enter the field name to select the description from the Examine record.",
View = "textstring",
},
};
public Dictionary<string, object> DefaultValues => new Dictionary<string, object>
{
{ "examineIndex", UmbConstants.UmbracoIndexes.ExternalIndexName },
{ "luceneQuery", "+__IndexType:content" },
{ "nameField", _defaultNameField },
{ "valueField", _defaultValueField },
{ "iconField", _defaultIconField },
{ "descriptionField", string.Empty },
};
public IEnumerable<DataListItem> GetItems(Dictionary<string, object> config)
{
string getConfig(string key, string defaultValue)
{
return config.TryGetValue(key, out var obj) == true && obj is string str && string.IsNullOrWhiteSpace(str) == false
? str
: defaultValue;
};
var examineIndex = getConfig("examineIndex", UmbConstants.UmbracoIndexes.ExternalIndexName);
if (_examineManager.TryGetIndex(examineIndex, out var index) == true)
{
var luceneQuery = getConfig("luceneQuery", string.Empty);
if (string.IsNullOrWhiteSpace(luceneQuery) == false)
{
var nameField = getConfig("nameField", _defaultNameField);
var valueField = getConfig("valueField", _defaultValueField);
var iconField = getConfig("iconField", _defaultIconField);
var descriptionField = getConfig("descriptionField", string.Empty);
var results = index
.GetSearcher()
.CreateQuery()
.NativeQuery(luceneQuery)
// NOTE: For any `OrderBy` complaints, refer to: https://github.com/Shazwazza/Examine/issues/126
.OrderBy(new SortableField(nameField, SortType.String))
.Execute();
if (results?.TotalItemCount > 0)
{
return results.Select(x => new DataListItem
{
Name = x.Values.ContainsKey(nameField) == true ? x.Values[nameField] : x.Values[_defaultNameField],
Value = x.Values.ContainsKey(valueField) == true ? x.Values[valueField] : x.Values[_defaultValueField],
Icon = x.Values.ContainsKey(iconField) == true ? x.Values[iconField] : x.Values[_defaultIconField],
Description = x.Values.ContainsKey(descriptionField) == true ? x.Values[descriptionField] : null,
});
}
}
}
return Enumerable.Empty<DataListItem>();
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment