Creating a Coveo facet with Sitecore sub-domains and external sites as options

Take this example: you have multiple sub-domains hosted in your Sitecore site, and each one has its own node under Content and its own Home item. You also have various external sites not hosted in Sitecore as completely separate sites. You’re building a search page with Coveo and want to develop a basic facet to list all of your internal sub-domains and external sites so that the end-users can filter pages and content by site. How would one do this? In this blog post, I will explain. Disclaimer: When I did this, I was working with Coveo for Sitecore v4.1 – Hive Framework, so if your version is much different, it’s possible not everything in this post will be accurate. Additionally, please note that the XML/HTML code snippets in this blog post will have the greater than/less than symbols stripped out because WordPress can’t handle those.

Create a Coveo Field for Your Facet

Every new facet you create will need its own field, so let’s create one. This is going to be a string, single-value field representing the name of a particular site (i.e. “Store” or “Marketing”, etc). In your Coveo.SearchProvider.Custom.config file, add a new field entry in the fieldMap/fieldNames node. In my case, my field’s name was aopaSiteName, so that naming convention will be used in other parts of this post as well. Your field entry should look something like this:

fieldType fieldName="aopaSiteName" settingType="Coveo.Framework.Configuration.FieldConfiguration, Coveo.Framework" isExternal="true" isFacet="true" /

Note that the field definition has isExternal="true" – this specifies that the field is not a normal Coveo for Sitecore field, so the field name won’t need to be converted. So if you put isExternal="false", your field name will become something like fmyfield99999 instead of just myfield. I suggest you keep this setting true to make development easier. Then, isFacet=true is needed so that this field can be used in a facet.

Creating a Computed Field

First, let’s focus on your internal content. What we need to do is actually rather simple: first, set up a basic computed field. See this page for basic information on how to do that with Coveo, and this page for a code sample if you’re not sure how the code for this would look. Inside the ComputeFieldValue method (see the second link above), you’ll want to get the indexable item, then the actual Sitecore item, and perform null checks on both so you have something you can work with:

        public object ComputeFieldValue(IIndexable indexable)
        {
            var indexableItem = indexable as SitecoreIndexableItem;
            if (indexableItem == null) return "Unknown";

            var item = indexableItem.Item;
            if (item == null) return "Unknown";

            ...
        }

Then, you just need to return a string value for each sub-domain node under Content. You can do this in multiple ways; using Glass is advised if possible. I decided to simply check the path and return the appropriate string for that path:

            ...

            if (item.Paths.Path.Contains("Sites/AOPA Main") ||
                item.Paths.Path.Contains("sitecore/media library")) return "AOPA";
            if (item.Paths.Path.Contains("Sites/Insurance")) return "Insurance";
            if (item.Paths.Path.Contains("Sites/Finance")) return "Finance";
            if (item.Paths.Path.Contains("Sites/PPS")) return "PPS";
            if (item.Paths.Path.Contains("Sites/You Can Fly")) return "You Can Fly";
            if (item.Paths.Path.Contains("Sites/Foundation")) return "Foundation";

            return "AOPA";
        }

Next, you’ll need to add a computed index field reference in your Coveo.SearchProvider.Custom.config file, under fields hint="raw:AddComputedIndexField", like this:

field fieldName="AOPASiteName" sourceField="AOPA.Library.Search.CoveoFields.SiteName, AOPA.Library">AOPA.Library.Search.CoveoFields.SiteName, AOPA.Library

Now, rebuild the Coveo indexes so that new field gets added to the index.

Adding Mappings on External Sources

In this example, since we’re building a facet with options showing each internal and external site, you’ll want to add a field mapping for each external site that you want in that list. You can add one by selecting a source and clicking the three dots, then click Manage mappings… Add a new mapping and select the field you created earlier. Then for the rule, simply put the name of the current site in plain text (i.e. “Blog”). Refer to online documentation for how to create a mapping in more depth. Once done, your mapping should look something like this:

aopa site name mapping

Now, add the field as a mapping for all your other external sites, then (preferably once you’ve added all mappings necessary for other features), re-build the source for your external site.

Reference Your External Sources

We need to find a way to reference your external sources in the search interface. Again, I did this with Coveo Hive, so if you are using the legacy framework, what you need to do will be different (and unfortunately I can’t help you there). First off, if you haven’t already created a custom version of your Search Interface view (usually located at /Views/Coveo Hive/Search Interfaces), do that now and place it under /Views/Coveo Hive/Custom/Search Interfaces and create any new directories necessary.

Then, in your Search Interface view, in the main div which iterates through the raw properties, add a new div with class CoveoForSitecoreExternalContent and a data attribute of data-sc-sources, and make the value of that attribute a comma delimited string of the names of your external sources. For example, here’s mine:

div class="CoveoForSitecoreExternalContent" data-sc-sources='AOPA Airports Directory,AOPA Blog,AOPA Brightcove Videos,AOPA Hangar'>
The names referenced there need to be exact as they are in the cloud platform. As of the writing of this post, source names in Coveo Cloud V2 can’t be changed after the source is created, so no worries regarding a source getting renamed and then you having to update it in the view. Here is where you might want to put a little extra effort in, perhaps find a way to render the value of a Sitecore field here so you can manage this string from Sitecore instead.

Completion

Finally, add a new facet to your search interface using the Experience Editor and select the field you created (or type in the field name). Once the facet renders it should show you options for all the sites you referenced in your code or in the source mappings.

sites facet completion

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s