Custom Multi-Sort Tutorial - Translating Fields

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, refer to Translating Fields to the Coveo Format in Coveo for Sitecore Hive Framework.

JavaScript Search Framework Attributes Serialization

Instead of using the Properties directly in our model, we will 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 does not required to be output in the DOM. This is why it does not have a  SearchUiProperty attribute.
  • Direction has no attribute read from Sitecore, it is 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 instance, 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 will not be added to the RawProperties dictionary, which leaves cleaner Views for your components.

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

For more information about Coveo for Sitecore Hive models, refer to Integrating a Custom Component in Sitecore using Coveo for Sitecore 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: “@sysindexeddate”
  • Ascending: true

The following markup will be output:

<div data-first-field="@name" data-second-field="@sysindexeddate" 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, @sysindexeddate descending" ...></div>

In this case, since sysindexeddate 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.