Custom Multi-Sort Tutorial - Translate Fields

Warning
Legacy feature

This article pertains to the Coveo Hive framework which is now in maintenance mode.

Choose one of Coveo’s more modern, lightweight, and responsive libraries for any future search interface development. See the search interface Implementation guide for more details.

This page covers how to translate the custom fields in the Coveo for Sitecore format.

Since Coveo for Sitecore fields depends on the master or web context, they need to be translated in your page to query the right context. For more information about field translation, see Handling Duplicate Field Names Between Indexes.

JavaScript Search Framework Attributes Serialization

Instead of using the Properties directly in our model, we’ll take advantage of the SearchUiProperty attribute serialization.

public class MultiSortModelProperties : IModelProperties
{
    [SitecoreProperty("FirstField")]
    [SearchUiProperty]
    public string FirstField { get; set; }

    [SitecoreProperty("SecondField")]
    [SearchUiProperty]
    public string SecondField { get; set; }

    [SitecoreProperty("Descending")]
    public bool Descending { get; set; }

    [SearchUiProperty]
    public string Direction => Descending ? "descending" : "ascending";
}

There are a few things to note about this code:

  • Descending is only used to toggle to set the Direction, so it doesn’t required to be output in the DOM. This is why it doesn’t have a SearchUiProperty attribute.

  • Direction has no attribute read from Sitecore, it’s computed to be output in the DOM. This is why it has the SearchUiProperty.

  • FirstField and SecondField will both be required.

This will generate the following keys in the Model’s RawProperties :

  • first-field

  • second-field

  • direction

All those keys will have a value associated with their data source.

Adding the Special RawProperties Loop

In your MultiSort.cshtml file, change the attributes for the following loop:

@model Coveo.Custom.MultiSortModel

<div class="CoveoSort"
    data-caption="My Multi-Sort"
    @foreach (var property in @Model.RawProperties) {
        @:data-@(property.Key)='@(property.Value)'
    }></div>

This allows you to shift the control of the properties to the model instead of manually inputting each of the properties in your .cshtml file.

For example, if you have a nullable property, you would require code similar to:

<div ...
     @if (!String.IsNullOrEmpty(Model.Properties.Caption)) {
         data-caption="@Model.Properties.Caption"
     }></div>

This redundancy is removed with the loop. If the Caption field is empty, the caption key won’t be added to the RawProperties dictionary, which leaves cleaner Views for your components.

It also allows you to add properties, in the future, by adding SearchUiProperty in the back-end code, without altering the .cshtml file.

For more information about Coveo Hive models, see Integrate a Custom Component in Sitecore Using the Coveo Hive Framework

Building the Sort Criteria

Since our component depends on the context, it requires a little magic to build the sort criteria with translated fields.

Given the following data source field values:

  • FirstField: "@name"

  • SecondField: "@indexeddate"

  • Ascending: true

The following markup will be output:

<div data-first-field="@name" data-second-field="@indexeddate" data-direction="descending"></div>

We require a unique ID to identify this div through the page using JavaScript code:

<div id="@Model.Id" ...></div>

We can now build the sort criteria:

<script>
    document.addEventListener("DOMContentLoaded", function() {
        var attributes = document.getElementById("@Model.Id").dataset;
        var firstCriteria = CoveoForSitecore.Context.fields.toCoveo(attributes.firstField) + " " + attributes.direction;
        var secondCriteria = CoveoForSitecore.Context.fields.toCoveo(attributes.secondField) + " " + attributes.direction;

        attributes.sortCriteria = firstCriteria + ", " + secondCriteria;
    });
</script>

Result

This will add the following attribute to the element:

<div id="@Model.Id" data-sort-criteria="@fname2053 descending, @indexeddate descending" ...></div>
Important

In this case, since indexeddate is defined as an external field, it was not translated.

The next step will cover how to improve the user experience for people using your component.