Coveo Cloud Learnings – Part 3

Follow my trail if you have not  read coveo cloud part 1 and 2.  Get a read on them here –

Coveo Cloud Learning – Part one 

Coveo Cloud Learning – Part two 

This is the last blog of this series, but, of course there is no end to learning.  I will continue to post new blogs as and when I encounter an interesting thing to share with you all as I proceed to take on new challenges and projects.

On this blog, I will cover how we used underscore, organized our views for better maintainability and all of this with Helix in play.

First though, Coveo does do an awesome job of documenting how to split result templates on conditions which comes in handy in various json situations.  Learn more here:
https://docs.coveo.com/en/413/javascript-search-framework/result-templates

After some pondering, we did go with data-condition route on our result templates.  We also have to remember to have a default result template at the last in the pile.  For better maintainability, we chose to add in partial views in MVC.  We do not have dynamic views as we only have a set of types.  If your implementation calls for content author control over these, you might choose to provide that additional layer of flexibility.  For us, it is an overhead in various ways, so, we avoided that and loaded the partial views on our own custom coveo search view.

Some thing like below:

@Html.Partial(“~/Views/Search/ResultTemplates/ProductResultTemplate.cshtml”, Model)
@Html.Partial(“~/Views/Search/ResultTemplates/StandardResultTemplate.cshtml”, Model)
@Html.Partial(“~/Views/Search/ResultTemplates/GeneralResultTemplate.cshtml”, Model)

Also, we definitely needed some same key attributes on all of this views and we do not want the Controller code to actually hit every single time, it would be in-efficient.  So, we chose to have a custom coveo model that inherits from the Search Model available in Coveo.UI.Mvc.Models with the additional attributes we need.   It was quite easy to make this happen, also, these instructions noted here might come in handy if you are trying something similar.   Awesome post by Vincent. 🙂 Basically, chose bits and pieces I needed to pull this off.

https://source.coveo.com/2014/12/10/creating-custom-model-coveo-for-sitecore/

Now, we have manageable pieces, so, we can work parallel on different result templates and also great for the future when it is time for enhancements.   In real life situations, it becomes very important while working with underscore templates to ensure a specific json piece you are looking for is not undefined and has a value in it, we had quite a few requirements to not even show a matching label on the view if a specific json attribute is missing.  We accomplished that with a simple underscore check as below on those applicable.  Below is a snippet for your reference.

{{ if (!_.isUndefined(raw.yearoforigin) && !_.isEmpty(raw.yearoforigin) ) { }}
<li class=”coveo-product-details__item”>
<span class=”coveo-product-details__category”>@Translate.Text(“Year of Origin”)</span>
<span>{{=raw.yearoforigin}}</span>
<a href=”#” class=”more”>(+)</a>
</li>
{{ } }}

Also, note that we continue to follow Sitecore best practices on the side to load all labels from Dictionary instead of hard coding on the view.  Another thing to note, is for the data conditions you need on the result templates, if it is a static value such as a GUID or string, always follow Helix best practice of having these defined in Templates.cs file of your project.  In our case, we maintained this in Feature Search project.  So, the data condition and templates.cs would look like –

<script id=’faqResultTemplate’ class=’result-template’ type=’text/underscore’ data-condition=’raw.contenttype==”@Templates.ContentTypes.FAQType”‘>

public struct ContentTypes
{
public static readonly string FAQType = “FAQs”;
}

I know, I wish this is not a string and is a GUID, but, unfortunately due to content structure we had to work with has these distributed out in content areas rather than defined templates, so, had to go this route.  But, where you can always rely on GUIDS as that is more stable implementation.

Also, we had lot of external fields which need to be used as Facets in our case.  There is documentation on how to make an external field Facetable, but, one thing to remember is actually a combination that you will need to do to make this work.  You have to do what is noted here and also ensure you add the field to external fields section as well.  As always,  it is always recommended to patch using a special config file on your Helix project rather than updating either custom coveo config  or raw coveo config file.

Say, if I had a field on my Cloud Index called contenttype, I would then add the following on this patch config file to ensure it is facetable and hash is excluded considering this is an external index.

<configuration xmlns:patch=”http://www.sitecore.net/xmlconfig/”>
<sitecore>
<coveo>
<defaultIndexConfiguration>
<fieldMap>
<fieldNames hint=”raw:AddFieldByFieldName”>fieldType fieldName=”contenttype” isExternal=”true” settingType=”Coveo.Framework.Configuration.FieldConfiguration, Coveo.Framework” />
</fieldNames>
</fieldMap>
<fieldMap>
<externalFields hint=”raw:AddExternalField”>
<field fieldName=”contenttype” />
</fieldMap>
</defaultIndexConfiguration>
</coveo>
</sitecore>
</configuration>

Also see this interesting post below that we used to migrate all our external fields on to production sandbox when we are ready.  We had lot of custom fields added to sandbox due to what we were trying to accomplish and wanted to eliminate manual work to load these up and replicate to avoid error and mundane task.  Thanks to coveo team for letting us know a better way does exist.  Take a peek of that here

Another interesting thing I bumped in to while working on this project was how some functionality is abstracted out from us on Cloud as compared to on-premise.  On Cloud, especially when working with trail sandboxes, if you queue way too many rebuilds, it might take a while, so, do not panic and give it some time.  All should be fine unless there is something else going on, if your logs are clean and no obvious errors on cloud console logs, you should be fine and it is just a delay on the cloud queue as trial sandboxes might not be given immediate preference.  If in doubt, talk to your Coveo point of contact and they will calm you down. 🙂

Also, when you are in active indexing state, say items are being added to your external index on cloud.  Sometimes, same queries and parameters passed from your Coveo Search Page/Components could yield different results due to elastic nature of Coveo.  Obviously, this should not happen when indexing is done.  But, I was super curious to know the reason behind this as I was doing some smoke test on my end.

That is all for now you all, have fun and enjoy the week ahead. Happy Monday!

Leave me a comment if you are curious to know more.

 

 

 

 

 

 

Journey with Helix

Hi There!  With new project I am getting an opportunity to work with Helix patterns, along with leading a team who is awaiting instructions and pointers from me, I am re-inventing and looking at sitecore from a totally different perspective.  Since, the whole sitecore world is moving towards Helix and embracing it, I was bent to take a step forward as well.  I am subtly nervous about this, but, hey, we got a a great team both internally and in community who would pitch in to help us take some decisions.

As I roll along, I plan to share what I learned and how we solved each question/concern that came up while implementing Helix for the first time ever.

Two of them so far.  Below are those noted and steps I took based on recommendations of my fellow super stars.  Do you agree? Do you have some totally different direction that we could lean towards.  I would look forward to getting some different thoughts around this.

  1. Helix does not support base page template and advice to have the page templates inherit from several interface templates instead.
    • Pain point – This would mean, every time there is a need for Global interface template to be added to all page templates, some one has to go to each template and add that in.  Hopefully, if architecture is planned correctly, this should not happen very often, but, yeah, I might have to install powershell for sure to do bulk operations very soon.  I can totally see it.
    • I had no option left at this time other than manually adding couple of those sections that are Global to all templates.
  2. Helix proposes to use a different project per feature/module, but, I guess I agree to use grouping instead to group tightly related siblings(I think you may call it that) in to one project instead.  For example, you have similar looking Hero Slider modules, but, we all know that there is not just one Hero on your website, you will have different flavors for this kind of modules.  So, instead of creating one feature project for each Hero, we tend to group them in to one Feature project instead.  Keeping this balanced, like not abusing it, but, at the same time judging each module case by case basis.
    • In this paradigm, I feel a little confused once in a while especially when Client says any module could be used any where on the site, well technically you could use any module any where on Sitecore, assuming not too many restrictions are placed using placeholder settings, but, saying all modules are Global kind of puts the categorizing in terms of Helix in jeopardy or confused state.
    • What I did to overcome this is – Think about different ways of grouping a module based on name of the module, fields/sitecore items in use for the module, where this module is likely to be used, what is the generic purpose of this module.  Few such questions I answered to myself to give clarity on naming the feature projects.  If the module seems to be really generic and not fitting in to any category, we would then plan to drop it under Modules project.  Again, being careful to not abuse this.

Will definitely bump in to more. Also, cool find, I see that the unit testing feedback provided on Helix/Habitat is pretty cool if you wanna check out

http://helix.sitecore.net/devops/testing/unit-testing.html