Overview
As Optimizely Graph (and Content Cloud SaaS) makes its global debut, it is known that there are going to be some bugs and quirks.
One of the current quirks in the system is related to using the Geta Categories Addon, specifically with Faceting. Luckily, a few people have figured out how to work around this issue to come up with a temporary solution!
So…..What needs to be done?
Quick Update
Hey Everyone. Before we get into the content, I do want to just announce that I have now transitioned to working directly for Optimizely on the Expert Services team. Please reach out if you need any assistance!
Additionally, this blog post was only made possible with the assistance of Minesh Shah and Muhammad Kashif from Netcel! Thank you both for your hard work!!
Converter
Firstly, we need to have a converter take the Geta Category property and simply….convert it… to a property that can be indexed by Opti Graph.
The best way to do this is to create an Interface that references a common property. This is ideal because then we can implement the converter to target that interface property.
PROTIP: This converter will need to be made for each subsequent property in the interface. For example, a property named “Categories” can be used over and over without another converter, but if we wanted to add a “Categories2”, we would have to create another converter to target that specific property.
CategoriesNamesApiModelProperty.cs
[ServiceConfiguration(typeof(IContentApiModelProperty), Lifecycle = ServiceInstanceScope.Singleton)]
public sealed class CategoriesNamesApiModelProperty : IContentApiModelProperty
{
private readonly ICategoryContentLoader _categoryContentLoader;
public CategoriesNamesApiModelProperty(ICategoryContentLoader categoryContentLoader)
{
_categoryContentLoader = categoryContentLoader;
}
public object GetValue(ContentApiModel contentApiModel)
{
if (contentApiModel.Properties.TryGetValue(nameof(IFilterCategoriesContent.Categories), out var propertyModel))
{
if (propertyModel is List<ContentModelReference> contentModelReferences && contentModelReferences.Any())
{
var names = new List<string>();
foreach (var category in contentModelReferences.Where(x => x.Id != null))
{
if (_categoryContentLoader.TryGet(new ContentReference(category.Id!.Value),
out CategoryData categoryData))
{
names.Add(categoryData.Name);
}
}
return names;
}
}
return Enumerable.Empty<string>();
}
public string Name => "CategoryNames";
}
IFilterCategoriesContent.cs
public interface IFilterCategoriesContent
{
IList<ContentReference>? Categories { get; set; }
}
Graph
Once the above files are in place, any class that inherits from the interface will have a new property “CategoryNames” indexed into Graph. This property can now be used to interact with Geta Categories on the models themselves OR use them as facets.
For example, within Opti Graph, here is a sample query to utilize the CategoryNames property:
query getBlogItemListing(
$start: Int = 0,
$pageSize: Int = 24,
$locale: [Locales!] = [en],
$facetsFilter: [String!])
{
getBlogItems: BlogItemPage(
locale: $locale
skip: $start
limit: $pageSize
orderBy: { StartPublish: DESC }
) {
items {
CategoryNames
Url
StartPublish,
Name
}
total
facets {
category: CategoryNames(
orderBy: DESC,
orderType: COUNT,
filters: $facetsFilter,
limit: 99) {
count
name
}
}
}
}
This code snippit outputs something along the lines of the following (dependent on content)
Summary
In order to utilize Geta Categories as facets within Optimizely Graph, a small amount of custom development needs to happen. These steps provide a workaround or band-aid in order to allow Graph to properly index the category names.
This all being said, work is being done in the background to continually improve the Optimizely products alongside of the addon developers. I do expect at some point there will be an out of the box solution for this problem.