Gravatar for fcote@coveo.com

Question by fcote, Apr 16, 2015 9:38 AM

Using Sitecore multilist with the BasicHtmlContentInBody Processor

I'm using the BasicHtmlContentInBody Processor to create excerpt from specific fields in Sitecore. I got the results I want for all my fields except one, skill-future, that is a multilist fields. For that field, only the GUID is coming out.

My question is, how could I obtain the value instead of the GUID ?

Here my coveoPostItemProcessingPipeline in my Coveo.SearchProvider.config

<coveoPostItemProcessingPipeline> 
  <processor type="Coveo.SearchProvider.Processors.AddCoveoVersionTag, Coveo.SearchProviderBase" /> 
  <processor type="Coveo.SearchProvider.Processors.BasicHtmlContentInBodyProcessor, Coveo.SearchProviderBase"> 
    <IncludeFieldNames>false</IncludeFieldNames> 
    <TemplatesToInclude>Developer</TemplatesToInclude> 
    <FieldsToInclude>First Name,Last Name,Skills,skills-future</FieldsToInclude> 
  </processor> 
</coveoPostItemProcessingPipeline> 
2 Replies
Gravatar for jflheureux@coveo.com

Answer by Jean-François L'Heureux, Apr 16, 2015 5:13 PM

Seems that the computed fields are not executed in our processor because we are using p_Args.Item.Fields as the fields list.

Here is a stripped down version of our BasicHtmlContentInBodyProcessor tailored for your needs (doesn't include the field names, works only for the "Developer" template). Note that it doesn't handle date fields correctly. I stripped down that part of the code too to keep things simple.

After completion of your logic, it should give the expected result.

Usage:

<coveoPostItemProcessingPipeline>
  <processor type="CustomAssembly.CustomNameSpace.Processors.DeveloperHtmlContentInBodyProcessor, CustomAssembly">
    <FieldsToInclude>First Name,Last Name,Skills,skills-future</FieldsToInclude>
  </processor>
</coveoPostItemProcessingPipeline>

Code:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Coveo.AbstractLayer.FieldManagement;
using Coveo.Framework.Processor;
using Coveo.SearchProvider.Pipelines;
using Sitecore.ContentSearch;

namespace CustomAssembly.CustomNameSpace.Processors
{
    /// <summary>
    /// A processor that will set the HTML content as the body of a developer document.
    /// This will be a basic content according to the document fields and the 
    /// document referenced items.
    /// </summary>
    public class DeveloperHtmlContentInBodyProcessor : IProcessor<CoveoPostItemProcessingPipelineArgs>
    {
        /// <summary>
        /// Gets or sets a comma separated list of fields to include.
        /// </summary>
        /// <remarks>
        /// If this value is null or empty, no fields will be processed.
        /// </remarks>
        public string FieldsToInclude { get; set; }

        /// <summary>
        /// Gets all the field names to include in the HTML content.
        /// </summary>
        private IEnumerable<string> FieldsToIncludeValues
        {
            get
            {
                return SplitValues(FieldsToInclude);
            }
        }

        /// <inheritDoc />
        public void Process(CoveoPostItemProcessingPipelineArgs p_Args)
        {
            object templateName;
            p_Args.CoveoItem.Metadata.TryGetValue(MetadataNames.s_TemplateName.OriginalFieldName, out templateName);

            if (p_Args.CoveoItem.BinaryData == null && ((string) templateName) == "Developer") {
                HtmlContentBuilder htmlBuilder = new HtmlContentBuilder();

                foreach (IIndexableDataField field in GetIncludedFields(p_Args.Item.Fields)) {
                    if (field.Name == "skills-future") {
                        htmlBuilder.AddElement(field.Name, GetSkillsFutureFieldValue(field), false);
                    } else {
                        htmlBuilder.AddField(field, false);
                    }
                }

                p_Args.CoveoItem.BinaryData = Encoding.UTF8.GetBytes(htmlBuilder.GetHtml());
            }
        }

        /// <summary>
        /// Filters the fields and return only the ones that should be included in the HTML content.
        /// </summary>
        /// <param name="p_Fields">The fields that should be filtered.</param>
        /// <returns>The fields that should be included in the HTML content.</returns>
        private IEnumerable<IIndexableDataField> GetIncludedFields(IEnumerable<IIndexableDataField> p_Fields)
        {
            IEnumerable<IIndexableDataField> includedFields = Enumerable.Empty<IIndexableDataField>();

            // Include only the fields that are listed in the FieldsToInclude parameter
            if (FieldsToIncludeValues.Any()) {
                includedFields = includedFields.Where(includedField => FieldsToIncludeValues.Contains(includedField.Name.ToLowerInvariant()));
            }

            return includedFields;
        }

        /// <summary>
        /// Splits comma separated values into an enumerable collection of strings.
        /// </summary>
        /// <param name="p_Values">Comma separated values.</param>
        /// <returns>An enumerable collection of strings.</returns>
        private IEnumerable<string> SplitValues(string p_Values)
        {
            IEnumerable<string> splitValues = Enumerable.Empty<string>();

            if (!String.IsNullOrEmpty(p_Values)) {
                splitValues = p_Values.Split(new[] { "," }, StringSplitOptions.RemoveEmptyEntries)
                                       .Select(x => x.ToLowerInvariant().Trim());
            }

            return splitValues;
        }

        /// <summary>
        /// Transforms the GUIDs list value of the skills-future field to their real value.
        /// </summary>
        /// <param name="p_Field">The skills-future field.</param>
        /// <returns>A string representation of the skills-future field value.</returns>
        private string GetSkillsFutureFieldValue(IIndexableDataField p_Field)
        {
            // Implement your logic to handle GUIDs here
        }
    }
}
Gravatar for adoprog@gmail.com

Comment by adoprog, Nov 21, 2017 3:20 PM

Are there any updates on this issue? Is there a better way to include computed fields into the excerpts, or should we still write custom processor?

Gravatar for lbergeron@coveo.com

Answer by Luc Bergeron, Apr 16, 2015 9:46 AM

What about using a computed field, say formatted-skill-future, which parses the GUID list, lookup the items and format the result as you want?

Also, I would suggest to take a look at the ReferencedFieldComputedField which ships with Coveo. Basically, it can replace the item GUID with another field. It might just do what you want. This page shows how to use this field: https://developers.coveo.com/display/SC201504/Creating+a+Computed+Field+for+a+Referenced+Item

I hope this helps

Gravatar for pavan.omtri@towerswatson.com

Comment by psomtri, Apr 16, 2015 4:41 PM

Yes I tried computed field , it did not work. I don't see computed values in excerpt. Computed field seems to work in facet but not in excerpt.

Ask a question