Coveo for Sitecore Legacy Search UI Framework - Overview of CoveoSearch.ascx
Coveo for Sitecore Legacy Search UI Framework - Overview of CoveoSearch.ascx
CoveoSearch.ascx is a sublayout file that represents a search component, which includes a search box, a list of search results, a pager control, and a few placeholders where you can insert additional components.
Its default location is c:\inetpub\wwwroot\SitecoreInstanceName\Website\layouts\Coveo\CoveoSearch.ascx.
Digging into Its Code
The code of CoveoSearch.ascx may appear complex at first, but taking a second look reveals its simplicity:
-
At the top, you can find a small block of JavaScript code that initializes the JavaScript Search Framework V1.0:
-
Coveo.$('#search')is a special extension that selects the elements matching the specified CSS selector. In this case, thedivelement is selected with anidattribute equal tosearch. -
Calling the
coveoForSitecorefunction on the selecteddivelement automatically instantiates/renders a search interface. -
Notice that the set of options to the
coveoForSitecorefunction was passed (retrieved by callingGetJavaScriptInitializationOptions). These options correspond to the attributes on thedivelement (that is,data-enable-history,data-results-per-page, etc.).
-
-
Inside the
divelement with anidattribute equal tosearch, you can find several otherdivelements, each one having a different value for itsclassattribute. A few values include:-
CoveoSearchBox: renders a full-featured search box control that allows you to enter queries. -
CoveoPager: renders a pager control that allows you to browse through the several pages of search results. -
CoveoResultList: renders a list of search results.
-
-
Inside the
divelement with aclassattribute equal toCoveoResultList, you can find ascriptelement with aclassattribute equal toresult-templateand atypeattribute equal totext/x-underscore-template. This is actually an underscore.js template:-
It allows you to dynamically build your search results by adding additional fields (for example,
raw.<%= ToCoveoFieldName("LayoutId", false) %>). -
It allows you to run conditional expressions, which allows for greater flexibility (for example,
ifstatements).
-
-
You can find special
sc:placeholderelements into which you can drop additional components (or more precisely sublayouts). They can be identified by theirkeyattribute:-
coveo-facets: this is where you can insert facet components. -
coveo-sorts: this is where you can insert sort components. -
coveo-tabs: this is where you can insert tab components.
-
-
You can find statements such as
Model.Somethingthat allow you to access the options and settings that you defined for your component in the Page Editor. The properties ofModelare currently undocumented. -
Overall, you can see that these HTML elements are the building blocks of your search interface.
<%@ Control Language="c#" AutoEventWireup="true" Inherits="Coveo.UI.CoveoSearch" TargetSchema="http://schemas.microsoft.com/intellisense/ie5" %>
<%@ Import Namespace="Coveo.UI" %>
<%@ Register TagPrefix="coveoui" Namespace="Coveo.UI.Controls" Assembly="Coveo.UIBase" %>
<!-- When customizing this component, ensure to use "Coveo.$" instead of the regular jQuery "$" to
avoid any conflicts with Sitecore's Page Editor/Experience Editor. -->
<coveoui:ErrorSummary runat="server" />
<coveoui:WhenConfigured runat="server">
<script type="text/javascript" src="/Coveo/js/cultures/<%= Model.CultureName %>.js"></script>
<script type="text/javascript">
Coveo.$(function() {
CoveoForSitecore.componentsOptions = <%= Model.GetJavaScriptInitializationOptions() %>;
});
</script>
<!-- This hidden input is required to bypass a problem with the Enter key causing a form submission
if the form has exactly one text field, or only when there's a submit button present. -->
<input type="text" class="fix-submit" />
<div id="search"
class="CoveoSearchInterface"
data-design='new'
data-enable-history="<%= Model.EnableHistory %>"
data-results-per-page="<%= Model.ResultsPerPage %>"
data-excerpt-length="<%= Model.ExcerptLength %>"
data-hide-until-first-query="<%= Model.HideUntilFirstQuery %>"
data-auto-trigger-query="<%= Model.AutoTriggerQuery %>"
data-maximum-age="<%= Model.MaximumAge %>">
<% if (Model.AnalyticsEnabled) { %>
<div class="CoveoAnalytics"
data-anonymous="<%= Model.IsUserAnonymous %>"
data-endpoint="<%= Model.GetAnalyticsEndpoint() %>"
data-search-hub="<%= Model.GetAnalyticsCurrentPageName() %>"
data-send-to-cloud="<%= Model.CoveoAnalyticsEnabled %>">
</div>
<% } %>
<div class="coveo-main-section">
<% if (Model.DisplayTabs) { %>
<div class="coveo-tab-section coveo-placeholder-fix">
<sc:placeholder key="coveo-tabs" runat="server"></sc:placeholder>
</div>
<% } %>
<% if (Model.DisplayFacets) { %>
<div class="coveo-facet-column">
<% if (Model.DisplayLogo) { %>
<div class="coveo-logo"></div>
<% } %>
<sc:placeholder key="coveo-facets" runat="server"></sc:placeholder>
</div>
<% } %>
<div class="coveo-results-column">
<% if (Model.DisplaySearchbox) { %>
<div class="CoveoSearchbox"
<% if (Model.EnableOmnibox) { %>
data-enable-omnibox="true"
data-omnibox-timeout="<%= Model.OmniboxTimeout %>"
data-enable-field-addon="<%= Model.OmniboxEnableFieldAddon %>"
data-enable-simple-field-addon="<%= Model.OmniboxEnableSimpleFieldAddon %>"
data-enable-top-query-addon="<%= Model.OmniboxEnableTopQueryAddon %>"
data-enable-reveal-query-suggest-addon="<%= Model.OmniboxEnableMLQuerySuggestAddon %>"
data-enable-query-extension-addon="<%= Model.OmniboxEnableQueryExtensionAddon %>"
<% } %>
<% if (Model.IsSearchAsYouTypeEnabled) { %>
data-enable-search-as-you-type="true"
data-search-as-you-type-delay="<%= Model.SearchboxSuggestionsDelay %>"
<% } %>
></div>
<% } %>
<% if (Model.DisplayBreadcrumb) { %>
<div class="CoveoBreadcrumb"></div>
<% } %>
<div class="coveo-results-header">
<div class="coveo-summary-section">
<% if (Model.DisplayQuerySummary) { %>
<span class="CoveoQuerySummary"
data-enable-search-tips="<%= Model.QuerySummaryEnableSearchTips %>"
data-only-display-search-tips="<%= Model.QuerySummaryOnlyDisplaySearchTips %>"></span>
<% } %>
<% if (Model.DisplayQueryDuration) { %>
<span class="CoveoQueryDuration"></span>
<% } %>
</div>
<% if (Model.DisplaySorting) { %>
<div class="coveo-sort-section">
<sc:placeholder key="coveo-sorts" runat="server"></sc:placeholder>
</div>
<% } %>
</div>
<div class="CoveoHiddenQuery"></div>
<% if (Model.DisplayDidYouMean) { %>
<div class="CoveoDidYouMean"
data-enable-auto-correction="<%= Model.EnableDidYouMeanAutoCorrection %>"></div>
<% } %>
<% if (Model.DisplayErrorReport) { %>
<div class="CoveoErrorReport"></div>
<% } %>
<% if (Model.DisplayResultList) { %>
<% if (Model.DisplayTopPager) { %>
<div class="CoveoPager" data-number-of-pages="<%= Model.PagerNumberOfPages %>"
data-max-number-of-pages="<%= Model.PagerMaxNumberOfPages %>"
data-enable-navigation-button="<%= Model.EnablePagerNavigationButton %>"></div>
<% } %>
<div class="CoveoResultList" data-wait-animation="fade"
data-enable-infinite-scroll="<%= Model.EnableInfiniteScroll %>"
data-infinite-scroll-page-size="<%= Model.InfiniteScrollPageSize %>">
<script class="result-template" type="text/underscore">
<div class="coveo-result-frame">
<div class="coveo-result-row">
<div class="coveo-result-cell" style="width:85px;text-align:center;padding-top:7px;">
<span class="CoveoIcon"></span>
{{ if (hasHtmlVersion) { }}
<div class='CoveoQuickview'
data-fixed='true'
data-width='70%'
data-heigth='70%'
data-template-id='CoveoQuickviewTemplate'></div>
{{ } }}
</div>
<div class="coveo-result-cell" style="padding-left:15px;">
<div class="coveo-result-row">
<div class="coveo-result-cell" style="font-size:18px;">
<div class='coveo-title'>
{{ if (raw.<%= ToCoveoFieldName("HasLayout", false) %> === "1" || raw.syssource !== "<%= Model.IndexSourceName %>") { }}
<a class='CoveoResultLink'>{{=title?highlight(title, titleHighlights):clickUri}}</a>
{{ } else { }}
<span class='CoveoResultTitle'>{{=title?highlight(title, titleHighlights):''}}</span>
{{ } }}
</div>
</div>
<div class="coveo-result-cell" style="width:120px; text-align:right; font-size:12px">
{{/* Change the tooltip on the date. */}}
{{if(raw.<%= ToCoveoFieldName("created", false) %> === raw.<%= ToCoveoFieldName("updated", false) %>) { }}
<div title='<%= Model.Labels[LocalizedStringKeys.CREATION_TIME] %>'>{{-dateTime(raw.sysdate)}}</div>
{{ } else { }}
<div title='<%= Model.Labels[LocalizedStringKeys.LAST_TIME_MODIFIED] %>'>{{-dateTime(raw.sysdate)}}</div>
{{ } }}
</div>
</div>
<div class="coveo-result-row">
<div class="coveo-result-cell">
<span class="CoveoExcerpt"></span>
</div>
</div>
</div>
</div>
<div class="coveo-result-row">
<div class="coveo-result-cell" style="font-size:13px">
++++
<div class='table-wrap'>
<table class="CoveoFieldTable">
<tbody>
<tr data-field='<%= ToCoveoFieldName("_templatename") %>' data-caption='<%= Model.Labels[LocalizedStringKeys.TEMPLATE] %>' />
{{ if (raw.<%= ToCoveoFieldName("created", false) %> === raw.<%= ToCoveoFieldName("updated", false) %>) { }}
<tr data-field='<%= ToCoveoFieldName("parsedcreatedby") %>' data-caption='<%= Model.Labels[LocalizedStringKeys.CREATED_BY] %>' />
{{ } else { }}
<tr data-field='<%= ToCoveoFieldName("parsedcreatedby") %>' data-caption='<%= Model.Labels[LocalizedStringKeys.CREATED_BY] %>' />
<tr data-field='<%= ToCoveoFieldName("created") %>' data-caption='<%= Model.Labels[LocalizedStringKeys.CREATED] %>' data-helper='dateTime' />
<tr data-field='<%= ToCoveoFieldName("parsedupdatedby") %>' data-caption='<%= Model.Labels[LocalizedStringKeys.UPDATED_BY] %>' />
{{ } }}
<tr data-field='<%= ToCoveoFieldName("parsedlanguage") %>' data-caption='<%= Model.Labels[LocalizedStringKeys.LANGUAGE] %>' />
<tr>
<th class='CoveoCaption'><%= Model.Labels[LocalizedStringKeys.UNIFORM_RESOURCE_IDENTIFIER] %></th>
<td class='CoveoClickableUri'>
<a href="{{= clickUri}}">{{= clickUri}}</a>
</td>
</tr>
</tbody>
</table>
</div>
++++
</div>
</div>
</div>
</script>
</div>
<% if (Model.DisplayBottomPager) { %>
<div class="CoveoPager" data-number-of-pages="<%= Model.PagerNumberOfPages %>"
data-max-number-of-pages="<%= Model.PagerMaxNumberOfPages %>"
data-enable-navigation-button="<%= Model.EnablePagerNavigationButton %>"></div>
<% } %>
<% } %>
</div>
</div>
</div>
<script class='result-template' id='CoveoQuickviewTemplate' type='text/underscore'>
<div class='coveo-quick-view-header'>
++++
<div class='table-wrap'>
<table class='CoveoFieldTable'>
<tr data-field='@sysdate' data-caption='Date' data-helper='dateTime' />
<tr data-field='@sysauthor' data-caption='Author' />
<tr data-field='@clickuri' data-html-value='true' data-caption='URL' data-helper='anchor' data-helper-options='{text: "{{= clickUri }}", target: "_blank"}'>
</table>
</div>
++++
<div class='CoveoQuickviewDocument'></div>
</div>
</script>
<script type="text/javascript">
Coveo.$(function() {
Coveo.$('#search').coveoForSitecore('init', CoveoForSitecore.componentsOptions);
});
</script>
</coveoui:WhenConfigured>
<% if (Model.HasErrors) { %>
<div class="CoveoServerError">
<h3><%= Model.Labels[LocalizedStringKeys.FRIENDLY_SEARCH_UNAVAILABLE_TITLE] %></h3>
<h4><%= Model.Labels[LocalizedStringKeys.FRIENDLY_SEARCH_UNAVAILABLE_DETAIL] %></h4>
</div>
<% if (SitecoreContext.IsEditingInPageEditor()) { %>
<script type="text/javascript">
Coveo.$(function() {
Coveo.PageEditorDeferRefresh.triggerUpdate();
});
</script>
<% } %>
<% } %>
What’s next?
Proceed to reading Overview of CoveoFacet.ascx.