Front End Development
Extending Presentation Layer
Overview
The Sitefinity connector is distributed with several built-in libraries for managing the presentation of Hawksearch. Currently, the V4 version supports ReactJS and Vue.js powered templates which enable the front-end layer to have structured data integration and modern behavior, look and feel.
Each implementation has separate configuration and logic. Though most of the features are shared among them, the specifics of the framework architectures enables some distinct functionalities. At the current stage, extending and modifying the libraries implementation is partially limited, but key concepts distinctive to Sitefinity have been exposed and ready for configuring with various use cases.
Both front end libraries are loaded in the Hawksearch widgets. Which one is currently in use depends on the used template markup. Since the widget template include all the required structures, selecting the library is only a matter of editing the template file.
Goal
This document provides information on managing the front-end libraries in the connector.
Steps for switching between the libraries
- Find the selected widget template for either the box or the results widget. Initially - the one named .Default.cshtml
- Both template structures should be included in the file, but one of them will be commented and the other - not. Comment the one you do not need and uncomment the desired one.
- Save, re-build and refresh the page.
React
React for Box Widget
Overview
The Hawksearch box widget comes with a ReactJS powered front end which has the latest features exposed to the Hawksearch service.
Goal
This document provides information on setting up the Hawksearch box widget using React. Basic usage is covered in Getting started and any additional information may be found here.
Steps for setup
- Open the selected widget template file
- Uncomment, if necessary, the part of the markup designated as React template. This should include a div element with attribute
data-component="react-search-box"
ordata-component="react-search-box-bootstrap"
. It should be an empty div element. Comment the part marked as Vue template.
The React template should look like this:
// React template
if (!SystemManager.IsDesignMode)
{
@Html.Script(Url.WidgetContent("assets/build/js/vendor.bundle.js"), "bottom", false)
@Html.Script(Url.WidgetContent("assets/build/js/main.js"), "bottom", false)
@Html.StyleSheet(Url.WidgetContent("assets/build/css/vendor.css"), "head")
@Html.StyleSheet(Url.WidgetContent("assets/build/css/main.css"), "head")
@Html.StyleSheet(Url.WidgetContent("assets/dist/react-hawksearch.css"), "head")
@Html.StyleSheet(Url.WidgetContent("assets/dist/react-hawksearch-override.css"), "head")
}
<div data-component="react-search-box-bootstrap"
data-client-guid="@Model.ClientId"
data-hawksearch-tracking-api="@Model.TrackingUrl"
data-hawksearch-base-api="@Model.HawksearchBaseAPI"
data-hawksearch-search-api="@Model.HawksearchSearchingAPI"
data-hawksearch-autocomplete-api="@Model.AutocompleteUrl"
data-json-params="@Model.Data"
data-search-page="@Model.ResultsUrl"
data-index-name="@Model.Index"
data-current-culture="@Model.CurrentCulture">
</div>
<script data-translations="react-translations" type="application/json">
{
"Narrow Results": "@Html.HtmlSanitize(Html.Resource("NarrowResults", "HawkWidgetsResources"))",
"Search Results": "@Html.HtmlSanitize(Html.Resource("SearchResults", "HawkWidgetsResources"))",
"Search Results for": "@Html.HtmlSanitize(Html.Resource("SearchResultsFor", "HawkWidgetsResources"))",
"Sort By": "@Html.HtmlSanitize(Html.Resource("SortBy", "HawkWidgetsResources"))",
"Enter a search term": "@Html.HtmlSanitize(Html.Resource("EnterKeyword", "HawkWidgetsResources"))",
"Quick Lookup": "@Html.HtmlSanitize(Html.Resource("QuickLookup", "HawkWidgetsResources"))",
"Clear All": "@Html.HtmlSanitize(Html.Resource("ClearAll", "HawkWidgetsResources"))",
"Clear": "@Html.HtmlSanitize(Html.Resource("Clear", "HawkWidgetsResources"))",
"No Results": "@Html.HtmlSanitize(Html.Resource("NoResults", "HawkWidgetsResources"))",
"Loading": "@Html.HtmlSanitize(Html.Resource("Loading", "HawkWidgetsResources"))",
"You've Selected": "@Html.HtmlSanitize(Html.Resource("YouSelected", "HawkWidgetsResources"))"
}
</script>
- Save, re-build and refresh the page.
Enable React for HawkSearch results widget
Overview
The Hawksearch results widget also has an implementation with ReactJS. This version provides the most common use cases of the search service.
Goal
This document provides information on setting up the Hawksearch results widget using ReactJS. Basic usage is covered in Getting started and any additional information may be found here.
Steps for setup
- Open the selected widget template file
- Uncomment, if necessary, the part of the markup designated as React template. This should include a div element with attribute
data-component="react-app"
ordata-component="react-app-bootstrap"
. It should be an empty div element. Comment the part marked as Vue template.
The React template is looking like this:
// React template
@Html.Script(Url.WidgetContent("assets/build/js/vendor.bundle.js"), "bottom", false)
@Html.Script(Url.WidgetContent("assets/build/js/main.js"), "bottom", false)
@Html.StyleSheet(Url.WidgetContent("assets/build/css/vendor.css"), "head")
@Html.StyleSheet(Url.WidgetContent("assets/build/css/main.css"), "head")
@Html.StyleSheet(Url.WidgetContent("assets/dist/react-hawksearch.css"), "head")
@Html.StyleSheet(Url.WidgetContent("assets/dist/react-hawksearch-override.css"), "head")
<div data-component="react-app-bootstrap"
data-client-guid="@Model.ClientId"
data-hawksearch-tracking-api="@Model.TrackingUrl"
data-hawksearch-base-api="@Model.HawksearchBaseAPI"
data-hawksearch-search-api="@Model.HawksearchSearchingAPI"
data-hawksearch-autocomplete-api="@Model.AutocompleteUrl"
data-tracking-events="@Model.TrackingEvents"
data-index-name="@Model.HawksearchIndexName"
data-json-params="@Model.Data"
data-show-searchbox="@Model.ShowSearchBox.ToString()"
data-current-culture="@Model.CurrentCulture">
</div>
<script data-translations="react-mappings" type="application/json">
{
"Telerik.Sitefinity.Events.Model.Event": "@Html.HtmlSanitize(Html.Resource("EventTypeDisplayName", "HawkWidgetsResources"))",
"Telerik.Sitefinity.Libraries.Model.Image": "@Html.HtmlSanitize(Html.Resource("ImageTypeDisplayName", "HawkWidgetsResources"))",
"Telerik.Sitefinity.Libraries.Model.Video": "@Html.HtmlSanitize(Html.Resource("VideoTypeDisplayName", "HawkWidgetsResources"))",
"Telerik.Sitefinity.Libraries.Model.Document": "@Html.HtmlSanitize(Html.Resource("DocumentTypeDisplayName", "HawkWidgetsResources"))",
"Telerik.Sitefinity.News.Model.NewsItem": "@Html.HtmlSanitize(Html.Resource("NewsItemDisplayName", "HawkWidgetsResources"))",
"Telerik.Sitefinity.Blogs.Model.BlogPost": "@Html.HtmlSanitize(Html.Resource("BlogPostDisplayName", "HawkWidgetsResources"))",
"Telerik.Sitefinity.Lists.Model.ListItem": "@Html.HtmlSanitize(Html.Resource("ListItemDisplayName", "HawkWidgetsResources"))",
"Telerik.Sitefinity.Pages.Model.PageNode": "@Html.HtmlSanitize(Html.Resource("PageNodeDisplayName", "HawkWidgetsResources"))"
}
</script>
<script data-translations="react-translations" type="application/json">
{
"Narrow Results": "@Html.HtmlSanitize(Html.Resource("NarrowResults", "HawkWidgetsResources"))",
"Search Results": "@Html.HtmlSanitize(Html.Resource("SearchResults", "HawkWidgetsResources"))",
"Search Results for": "@Html.HtmlSanitize(Html.Resource("SearchResultsFor", "HawkWidgetsResources"))",
"Sort By": "@Html.HtmlSanitize(Html.Resource("SortBy", "HawkWidgetsResources"))",
"Enter a search term": "@Html.HtmlSanitize(Html.Resource("EnterKeyword", "HawkWidgetsResources"))",
"Quick Lookup": "@Html.HtmlSanitize(Html.Resource("QuickLookup", "HawkWidgetsResources"))",
"Clear All": "@Html.HtmlSanitize(Html.Resource("ClearAll", "HawkWidgetsResources"))",
"Clear": "@Html.HtmlSanitize(Html.Resource("Clear", "HawkWidgetsResources"))",
"No Results": "@Html.HtmlSanitize(Html.Resource("NoResults", "HawkWidgetsResources"))",
"Loading": "@Html.HtmlSanitize(Html.Resource("Loading", "HawkWidgetsResources"))",
"You've Selected": "@Html.HtmlSanitize(Html.Resource("YouSelected", "HawkWidgetsResources"))",
"response_error_generic": "An error occurred while searching for your results. Please contact the site administrator."
}
</script>
- Save, re-build and refresh the page.
- Now the active template that is used in the Hawksearch result widget should be the React one.
Localize Labels in React
Overview
Sitefinity supports multiple languages and the React SDK is integrated into this. A wide range of labels are exposed for translation via Sitefinity localization feature and any configured language can used to translate the widgets interface.
Goal
This document provides insight on React powered templates localization features.
Translations mapping
Each of the Hawksearch widgets comes with a JSON array that defines the mappings of exposed labels from the React SDK to the Sitefinity resources. It defines how these labels are translated and is a finite list of label keys. Any new labels that are created for the interface are added to the array and it usually doesnโt require any additional configuration.
Label translations
<script data-translations="react-translations" type="application/json">
{
"Narrow Results": "@Html.HtmlSanitize(Html.Resource("NarrowResults", "HawkWidgetsResources"))",
"Search Results": "@Html.HtmlSanitize(Html.Resource("SearchResults", "HawkWidgetsResources"))",
"Search Results for": "@Html.HtmlSanitize(Html.Resource("SearchResultsFor", "HawkWidgetsResources"))",
"Sort By": "@Html.HtmlSanitize(Html.Resource("SortBy", "HawkWidgetsResources"))",
...
}
</script>
The inclusion of this array is required for enabling translations. Removing it will prevent the system to modify any of the labels and fallback to its default language. The default language is English.
Customize Search Results in React
Overview
The React integration of Hawksearch results can be customized with additional functionalities and extended layouts. For this, it is required to install the react-hawksearch NPM package separately and include the extended build resources.
Goal
This document provides information regarding extending the Hawksearch results widget and its layout and styles.
Extending the widget template
- Follow the React SDK setup steps to set up the npm package in your target project. This should result in a dedicated folder with the specified structure (e.g. hawksearch/react).
- Open the active results widget template for editing. It is located in Mvc\Views\Hawksearch\Hawksearch.Default.cshtml. If a resource package is used, then edit the same path in the ResourcePackages folder. Make sure that this is the correct template.
- Copy the file of the base template and name it accordingly (Hawksearch.CustomResults.cshtml for example).
- Make sure to enable the proper markup (i.e. the target element) in the widget template. It should have the react prefix.
- Import the bundled JS resources that include the component's initialization.
@Html.Script(Url.WidgetContent("hawksearch/react/build/js/\<build_file>.js"), "bottom", false)
- Clean up all other component's markup that is not relevant to this widget.
- Save, rebuild and refresh the page.
Vue.js
Enable Vue.js for Hawksearch box widget
Overview
The Hawksearch Box using Vue.js provides framework-specific integration of the search field and enables an optimized and efficient way of using the widget.
Goal
This document provides information on setting up the Hawksearch box widget using Vue.js. Basic usage is covered in Getting started and any additional information may be found there.
Steps for setup
- Open the selected widget template file
- Uncomment, if necessary, the part of the markup designated as Vue template. This should include a
div
element with attributedata-component="vue-app-searchbox"
. In it, there should be a Vue component namedsearch-box
. Comment the part marked as React template. Only this step is required for enabling the component, the rest of the steps are optional. - Modify the
data-client-guid
attribute to set the Hawksearch client ID. - Modify the
data-hawksearch-base-api
attribute to set the Base API URL. - Modify the
data-hawksearch-search-api
attribute to set the Search API URL - Modify the
data-json-params
attribute (JSON object, param_name: param_value) to set additional search parameters, specific for the widget instance. - Modify the
data-index-name
attribute to set index for the widget search requests. - Edit the HTML structure around to set the desired layout. The existing classes are used for the built-in theme.
- Modify the search-page attribute in
<search-box>
to set the redirect page. - Save, re-build and refresh the page.
Enable Vue.js for Hawksearch search widget
Overview
The Hawksearch results widget implementation with Vue.js provides out-of-the-box access to the Hawksearch service. The framework specifics expose some particular features that cover many advanced scenarios.
Goal
This document provides information on setting up the Hawksearch results widget using Vue.js. Basic usage is covered in Getting started and any additional information may be found here.
Steps for setup
- Open the selected widget template file
- Uncomment, if necessary, the part of the markup designated as Vue template. This should include a
div
element with attributedata-component="vue-app-spa"
. In it, there should be Vue components namedsearch-box
,facet-list
andresults
. Comment the part marked as React template. Only this step is required for enabling the components, the rest of the steps are optional. - Modify the
data-client-guid
attribute to set the Hawksearch client ID. - Modify the
data-hawksearch-base-api
attribute to set the Base API URL. - Modify the
data-hawksearch-search-api
attribute to set the Search API URL - Modify the
data-json-params
attribute (JSON object, param_name: param_value) to set additional search parameters, specific for the widget instance. - Modify the
data-index-name
attribute to set the index for the widget search requests. - Edit the HTML structure around
<search-box>
,<facet-list>
and<results>
to set the desired layout. The existing classes are used for the built-in theme. There is an additional Razor condition if the search box should be shown. - Save, rebuild and refresh the page.
Customize search results in Vue.js
Overview
All components in the Vue.js suite are extendable and can be modified to handle custom layout, styles and behaviour. This is possible due to the built-in capability of the platform to attach templates as script tag and therefore supplying a dynamic structure of the presentation.
Goal
This document provides information regarding the template extension of the Hawksearch results widget and its layout and style customization capabilities.
Steps of extending the base template
- Open the results active widget template for editing. It is located in Mvc\Views\Hawksearch\Hawksearch.Default.cshtml. If a resource package is used, then edit the same path in the ResourcePackages folder. Make sure you are using the correct template.
- Place the script tag containing the componentโs overridden template in the file.
- Save, rebuild and refresh the page.
Template overrides examples
The result item will most probably be extended. The component has a property for accessing individual fields from the index. To place the field value invoke getField() with the field key. The override should be placed in the Hawksearch results widget template.
Example: Overriding the result item component to include images and links
Example: Overriding the result item component with two column layout using bootstrap classes
Example: Extending the result items with different layout for products and content
Example: Extending search results view to show additional fields based on the type of the result item
Example: Extending result item component to include a field from the response object
Example: Extending pagination tool with custom markup
General info
- Vue.js requires all component templates to have a single root element. Note that all the examples are placed in a single
- The template is defined by HTML id attribute and there can only be one on a single page. Make sure not to duplicate the template overrides.
- If there are several Hawksearch widget templates used in different cases, there can be different component templates for each. For instance, if you need a separate structure for a specific list that has a dedicated widget, apply the custom template override there and use it only for this case.
- The script tag is not required to be in the widget template where it's used. A more general approach can be to place all the page specific templates separately and used them for all widgets on this page. This can be implemented with the Embedded code widget from the Scripts and Styles section.
- All of Vue.js directives (v-if, v-else, v-else-if, v-show etc.) are applicable in the template override. Vue.js Directives
Localize labels in Vue.js
Overview
Sitefinity supports multiple languages and the Vue SDK is integrated into this. A wide range of labels are exposed for translation via the Sitefinity localization feature and any configured language can be used to translate the widgets interface.
Goal
This document provides insight on Vue.js powered templates localization features.
Translations mapping
Each of the Hawksearch widgets comes with a JSON array that defines the mappings of exposed labels from the Vue SDK to the Sitefinity resources. It defines how these labels are translated and is a finite list of label keys. Any new labels that are created for the interface are added to the array and it usually doesnโt require any additional configuration.
Label translations
<script data-translations="vue-translations" type="application/json">
{
"Narrow Results": "@Html.HtmlSanitize(Html.Resource("NarrowResults", "HawkWidgetsResources"))",
"Search Results": "@Html.HtmlSanitize(Html.Resource("SearchResults", "HawkWidgetsResources"))",
"Search Results for": "@Html.HtmlSanitize(Html.Resource("SearchResultsFor", "HawkWidgetsResources"))",
"Sort By": "@Html.HtmlSanitize(Html.Resource("SortBy", "HawkWidgetsResources"))",
...
}
</script>
The inclusion of this array is required for enabling translations. Removing it will prevent the system to modify any of the labels and fallback to its default language. The default language is English.
Localize facets in Vue.js
Overview
In some rare cases, it is needed to override part of the data that is associated with the search results. For these case, there is a custom labels mapping structure that enhances the data.
Goal
This document provides insight on Vue.js powered custom mappings feature.
Labels mapping
The label mappings are realized the same way as the translations. An array with the label values is positioned in Hawksearch results and Hawksearch Box widget templates. In this case, however, the array should be extended with any values that are specific to the indexed data. The most common case is mapping the Sitefinity content type value to a human-readable label in the facets and selections header.
<script data-translations="vue-mappings" type="application/json">
{
"Telerik.Sitefinity.Events.Model.Event": "@Html.HtmlSanitize(Html.Resource("EventTypeDisplayName", "HawkWidgetsResources"))",
"Telerik.Sitefinity.Libraries.Model.Image": "@Html.HtmlSanitize(Html.Resource("ImageTypeDisplayName", "HawkWidgetsResources"))",
"Telerik.Sitefinity.Libraries.Model.Video": "@Html.HtmlSanitize(Html.Resource("VideoTypeDisplayName", "HawkWidgetsResources"))"
...
}
</script>
The inclusion of this array is required for enabling custom label mapping. Removing it will prevent the system to modify any of the labels. Though it is not mandatory, it is not recommended to remove it from the widget template.
Hawksearch Results
@model HawksearchWidgets.Mvc.ViewModels.Hawksearch.SearchViewModel
@using Telerik.Sitefinity.Frontend.Mvc.Helpers;
@using Telerik.Sitefinity.Services
@if (Model.Version == "V2L" || Model.Version == "V3L" || Model.Version == "V4L")
{
<div data-role="hawk-results" class="row hs-wrap" style="display: none;">
<div class="col-md-3 hs-col-3">
<div id="hawkbannerlefttop"></div>
<div id="hawkfacets"></div>
<div id="hawkbannerleftbottom"></div>
<input type="hidden" name="search-term" value="@Model.Keyword" />
</div>
<div role="main" class="col-md-9 hs-col-9" id="main-content">
<div id="hawktitle"></div>
<div class="right-bg">
<div id="hawkbannertop"></div>
<div id="hawktoptext"></div>
<div id="hawkrelated"></div>
<div id="hawktoppager"></div>
<div id="hawktoptext"></div>
<div id="hawkitemlist" class="item-list horizontal resource-listing clearfix">
</div>
<div id="hawkbottompager"></div>
<div class="clear"> </div>
</div>
</div>
</div>
if (!SystemManager.IsDesignMode)
{
@Html.Script(Url.WidgetContent("Mvc/Scripts/polyfills.js"), "top", false)
@Html.Script(Url.WidgetContent("Mvc/Scripts/hawksearch-init.js"), "head", false)
@Html.Script(Url.WidgetContent("Mvc/Scripts/hawksearch.js"), "head", false)
}
}
else if (!SystemManager.IsDesignMode)
{
if (Model.Languages.Length > 1 && Model.IsMultilingualEnabled)
{
<div>
<span>@Html.Resource("ChangeResultsLanguageLabel", "HawkWidgetsResources") </span>
@for (var i = 0; i < Model.Languages.Length; i++)
{
var language = Model.Languages[i];
var indexName = string.Empty;
var uri = this.Request.Url;
if (uri != null)
{
var query = HttpUtility.ParseQueryString(uri.Query);
indexName = query.Get("indexName");
}
var languageUrl = string.Format(string.IsNullOrWhiteSpace(indexName) ? "{0}?language={1}" : "{0}?language={1}&indexName={2}", Model.UrlPath, language.Name, indexName);
<a href="@languageUrl">@language.DisplayName</a>
if (i < Model.Languages.Length - 2)
{
<span>, </span>
}
else if (i == Model.Languages.Length - 2)
{
<span> @Html.Resource("OrLabel", "HawkWidgetsResources") </span>
}
}
</div>
}
// Vue template
@Html.Script(Url.WidgetContent("assets/build/js/vendor.bundle.js"), "bottom", false)
@Html.Script(Url.WidgetContent("assets/build/js/main.js"), "bottom", false)
@Html.StyleSheet(Url.WidgetContent("assets/build/css/vendor.css"), "head")
@Html.StyleSheet(Url.WidgetContent("assets/build/css/main.css"), "head")
@Html.StyleSheet(Url.WidgetContent("assets/dist/vue-hawksearch.css"), "head")
@Html.StyleSheet(Url.WidgetContent("assets/dist/vue-hawksearch-override.css"), "head")
<div data-component="vue-app-spa"
data-client-guid="@Model.ClientId"
data-hawksearch-tracking-api="@Model.TrackingUrl"
data-hawksearch-base-api="@Model.HawksearchBaseAPI"
data-hawksearch-search-api="@Model.HawksearchSearchingAPI"
data-hawksearch-autocomplete-api="@Model.AutocompleteUrl"
data-tracking-events="@Model.TrackingEvents"
data-index-name="@Model.HawksearchIndexName"
data-json-params="@Model.Data"
data-current-culture="@Model.CurrentCulture"
data-hawksearch-recommendation-api=""
data-widget-guid=""
data-show-searchbox="@Model.ShowSearchBox.ToString()">
<div class="hawk">
@if (Model.ShowSearchBox)
{
<div class="hawk__header">
<div data-component="hawksearch-field">
<search-box></search-box>
</div>
</div>
}
<div class="hawk__body">
<div data-component="hawksearch-facets">
<facet-list></facet-list>
</div>
<div data-component="hawksearch-results">
<results></results>
</div>
</div>
</div>
</div>
<script id="vue-hawksearch-result-item" type="x-template">
<div class="media-body sf-media-body" v-on:click="onClick">
<h3>
<template v-if="link">
<a :href=link>{{ title }}</a>
</template>
<template v-else>
{{ title }}
</template>
</h3>
<p>
<strong class="sfHighlight">{{ title }}</strong>
<span>{{ content }}</span>
</p>
<a :href="link">{{ link }}</a>
</div>
</script>
<script data-translations="vue-mappings" type="application/json">
{
"Telerik.Sitefinity.Events.Model.Event": "@Html.HtmlSanitize(Html.Resource("EventTypeDisplayName", "HawkWidgetsResources"))",
"Telerik.Sitefinity.Libraries.Model.Image": "@Html.HtmlSanitize(Html.Resource("ImageTypeDisplayName", "HawkWidgetsResources"))",
"Telerik.Sitefinity.Libraries.Model.Video": "@Html.HtmlSanitize(Html.Resource("VideoTypeDisplayName", "HawkWidgetsResources"))"
}
</script>
<script data-translations="vue-translations" type="application/json">
{
"Filter By": "@Html.HtmlSanitize(Html.Resource("FilterBy", "HawkWidgetsResources"))",
"Search Results": "@Html.HtmlSanitize(Html.Resource("SearchResults", "HawkWidgetsResources"))",
"Search Results for": "@Html.HtmlSanitize(Html.Resource("SearchResultsFor", "HawkWidgetsResources"))",
"Sort By": "@Html.HtmlSanitize(Html.Resource("SortBy", "HawkWidgetsResources"))",
"Enter a search term": "@Html.HtmlSanitize(Html.Resource("EnterKeyword", "HawkWidgetsResources"))",
"Quick Lookup": "@Html.HtmlSanitize(Html.Resource("QuickLookup", "HawkWidgetsResources"))",
"Clear All": "@Html.HtmlSanitize(Html.Resource("ClearAll", "HawkWidgetsResources"))",
"Clear": "@Html.HtmlSanitize(Html.Resource("Clear", "HawkWidgetsResources"))",
"No Results": "@Html.HtmlSanitize(Html.Resource("NoResults", "HawkWidgetsResources"))",
"Loading": "@Html.HtmlSanitize(Html.Resource("Loading", "HawkWidgetsResources"))",
"You've Selected": "@Html.HtmlSanitize(Html.Resource("YouSelected", "HawkWidgetsResources"))",
"response_error_generic": "An error occurred while searching for your results. Please contact the site administrator."
}
</script>
}
Hawksearch Box
Hawksearch Box widget template with included label mappings.
@model HawksearchWidgets.Mvc.ViewModels.HawksearchBox.SearchBoxViewModel
@using Telerik.Sitefinity.Frontend.Mvc.Helpers;
@using Telerik.Sitefinity.Modules.Pages
@using Telerik.Sitefinity.Services
@using Newtonsoft.Json
@if (Model.Version == "V2L" || Model.Version == "V3L" || Model.Version == "V4L")
{
<div class="site-search">
<input type="hidden" value="@Model.Index">
<input type="hidden" value="@Model.ResultsUrl" data-search-page="@Model.ResultsUrl">
<div>
<input class="site-search-input" placeholder="@Html.HtmlSanitize(Html.Resource("ImLookingFor", "HawkWidgetsResources"))" type="text" id="txtSiteSearch">
<button class="site-search-btn" id="btnSiteSearch">
<span class="visually-hidden">@Html.HtmlSanitize(Html.Resource("SubmitButtonText"))</span>
<svg class="icon icon-search-01">
<use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#icon-search-01"></use>
</svg>
</button>
</div>
</div>
//string hawkCssUrl = Hawksearch.Helpers.HawksearchApiHelper.GetHawksearchUrl().Replace("http://", "https://") + "/includes/hawksearch.css";
@*@Html.StyleSheet(hawkCssUrl, "head", false)*@
@Html.Script(ScriptRef.JQuery, "top", false)
if (!SystemManager.IsDesignMode)
{
@Html.Script(Url.WidgetContent("Mvc/Scripts/polyfills.js"), "top", false)
@Html.Script(Url.WidgetContent("Mvc/Scripts/hawksearch-init.js"), "head", false)
@Html.Script(Url.WidgetContent("Mvc/Scripts/hawksearch.js"), "head", false)
@Html.Script(Url.WidgetContent("Mvc/Scripts/hawksearch-autosuggest.js"), "bottom", false)
@Html.Script(Url.WidgetContent("Mvc/Scripts/hawksearchbox.js"), "bottom", false)
}
}
else
{
// Vue template
@Html.Script(Url.WidgetContent("assets/build/js/vendor.bundle.js"), "bottom", false)
@Html.Script(Url.WidgetContent("assets/build/js/main.js"), "bottom", false)
@Html.StyleSheet(Url.WidgetContent("assets/build/css/vendor.css"), "head")
@Html.StyleSheet(Url.WidgetContent("assets/build/css/main.css"), "head")
@Html.StyleSheet(Url.WidgetContent("assets/dist/vue-hawksearch.css"), "head")
@Html.StyleSheet(Url.WidgetContent("assets/dist/vue-hawksearch-override.css"), "head")
<div data-component="vue-app-searchbox"
data-client-guid="@Model.ClientId"
data-hawksearch-tracking-api="@Model.TrackingUrl"
data-hawksearch-base-api="@Model.HawksearchBaseAPI"
data-hawksearch-search-api="@Model.HawksearchSearchingAPI"
data-hawksearch-autocomplete-api="@Model.AutocompleteUrl"
data-search-page="@Model.ResultsUrl"
data-show-searchbox="True"
data-json-params="@Model.Data"
data-index-name="@Model.Index"
data-current-culture="@Model.CurrentCulture">
<div class="hawk">
<div class="hawk__header">
<div data-component="hawksearch-field">
<search-box search-page="@Model.ResultsUrl"></search-box>
</div>
</div>
</div>
</div>
<script data-translations="vue-mappings" type="application/json">
{
"Telerik.Sitefinity.Events.Model.Event": "@Html.HtmlSanitize(Html.Resource("EventTypeDisplayName", "HawkWidgetsResources"))",
"Telerik.Sitefinity.Libraries.Model.Image": "@Html.HtmlSanitize(Html.Resource("ImageTypeDisplayName", "HawkWidgetsResources"))",
"Telerik.Sitefinity.Libraries.Model.Video": "@Html.HtmlSanitize(Html.Resource("VideoTypeDisplayName", "HawkWidgetsResources"))"
}
</script>
<script data-translations="vue-translations" type="application/json">
{
"Filter By": "@Html.HtmlSanitize(Html.Resource("FilterBy", "HawkWidgetsResources"))",
"Search Results": "@Html.HtmlSanitize(Html.Resource("SearchResults", "HawkWidgetsResources"))",
"Search Results for": "@Html.HtmlSanitize(Html.Resource("SearchResultsFor", "HawkWidgetsResources"))",
"Sort By": "@Html.HtmlSanitize(Html.Resource("SortBy", "HawkWidgetsResources"))",
"Enter a search term": "@Html.HtmlSanitize(Html.Resource("EnterKeyword", "HawkWidgetsResources"))",
"Quick Lookup": "@Html.HtmlSanitize(Html.Resource("QuickLookup", "HawkWidgetsResources"))",
"Clear All": "@Html.HtmlSanitize(Html.Resource("ClearAll", "HawkWidgetsResources"))",
"Clear": "@Html.HtmlSanitize(Html.Resource("Clear", "HawkWidgetsResources"))",
"No Results": "@Html.HtmlSanitize(Html.Resource("NoResults", "HawkWidgetsResources"))",
"Loading": "@Html.HtmlSanitize(Html.Resource("Loading", "HawkWidgetsResources"))",
"You've Selected": "@Html.HtmlSanitize(Html.Resource("YouSelected", "HawkWidgetsResources"))",
"response_error_generic": "An error occurred while searching for your results. Please contact the site administrator."
}
</script>
}
Setting up Banners
Overview
A major part of the appearance of the Hawksearch results page is having a custom layout including relevant to the search results banners and displaying information regarding active campaigns. This can be achieved few configurations steps in both the Hawksearch dashboard and in the results page template.
Goal
Setup and display the campaign information on the results page.
Campaigns
Steps
- Configure the campaigns based on the search results.
- Extend the search results component using Example: Extending the results set. In this sample, there are a couple of Banner components defined prior and after the result set.
<script id="vue-hawksearch-results" type="x-template">
<div class="hawk-results">
...
<banner zone="Top"></banner>
...
...
<banner zone="Bottom"></banner>
...
</div>
</script>
The tag is designating the position and layout of the Banner component. Each banner has a specific zone property that defines the used data set (i.e. Top, Bottom). These zones correspond to the configured zone in the Hawksearch dashboard. Their machine name can be verified from the search request response, from the Merchandising
property. For example, if the selected zone is FeaturedBottom
the setup should look like this:
<script id="vue-hawksearch-results" type="x-template">
<div class="hawk-results">
...
<banner zone="FeaturedBottom"></banner>
...
</div>
</script>
There arenโt any banners placed by default in the results template. All required banners can be added in any desired possition, configuration, and multiple times, as long as they are enabled in the dashboard.
Updated almost 2 years ago