Load handlebar-helpers as needed, instead of a switch.

This commit is contained in:
Mikael Svenson 2018-12-03 09:49:34 +01:00
parent 53b04d5b81
commit e95fbcb122
5 changed files with 174 additions and 26 deletions

View File

@ -61,6 +61,7 @@ Version|Date|Comments
2.1.1.0 | Oct 30, 2018 | <ul><li>Bug fix for editing custom template.</li><li>Bug fix for dynamic loading of video helper library.</li><li>Added support for Page context query variables.</li><li>Added `getUniqueCount` helper function.</li></ul>
2.1.2.0 | Nov 9, 2018 | <ul><li>Bug fix for IE11.</li><li>Added date query variables.</li><li>Added support for both result source id and query template.</li><li>Added `getUniqueCount` helper function.</li></ul>
2.2.0.0 | Nov 11, 2018 | <ul><li>Upgraded to SPFx 1.7.0</li><li>Added a TypeScript Azure Function to demonstrate NLP processing on search query</li><li>Removed extension data source. Now we use the default SPFx 'Page Environment' data source.</li></ul>
2.2.0.1 | Dec 3, 2018 | <ul><li>Remove switch for handlebar helpers, and instead load helpers if used in the template.</li></ul>
## Important notice on upgrading the solution from pre v2.2.0.0
**Due to code restucturing we have hit an edge case which impacts upgrades from previous versions. To solve the issue go to `https://<tenant>.sharepoint.com/sites/<appcatalog>/Lists/ComponentManifests` and remove the entries for SearchBox and Search Results, and then upload the .sppkg for the new release.**

View File

@ -3,7 +3,7 @@
"solution": {
"name": "PnP - Search Web Parts",
"id": "890affef-33e0-4d72-bd72-36399e02143b",
"version": "2.2.0.0",
"version": "2.2.0.1",
"includeClientSideAssets": true,
"skipFeatureDeployment": false,
"isDomainIsolated": false

View File

@ -22,16 +22,14 @@ abstract class BaseTemplateService {
this.registerTemplateServices();
}
public async LoadHandlebarsHelpers(load: boolean) {
if (load) {
let component = await import(
/* webpackChunkName: 'search-handlebars-helpers' */
'handlebars-helpers'
);
this._helper = component({
handlebars: Handlebars
});
}
private async LoadHandlebarsHelpers() {
let component = await import(
/* webpackChunkName: 'search-handlebars-helpers' */
'handlebars-helpers'
);
this._helper = component({
handlebars: Handlebars
});
}
/**
@ -292,7 +290,7 @@ abstract class BaseTemplateService {
});
// Return the URL or Title part of a URL automatic managed property
// <p>{{getDate MyLinkOWSURLH "Title"}}</p>
// <p>{{getUrlField MyLinkOWSURLH "Title"}}</p>
Handlebars.registerHelper("getUrlField", (urlField: string, value: "URL" | "Title") => {
let separatorPos = urlField.indexOf(",");
if (value === "URL") {
@ -325,6 +323,168 @@ abstract class BaseTemplateService {
*/
public async processTemplate(templateContext: any, templateContent: string): Promise<string> {
// Process the Handlebars template
const handlebarFunctionNames = [
"getDate",
"after",
"arrayify",
"before",
"eachIndex",
"filter",
"first",
"forEach",
"inArray",
"isArray",
"itemAt",
"join",
"last",
"lengthEqual",
"map",
"some",
"sort",
"sortBy",
"withAfter",
"withBefore",
"withFirst",
"withGroup",
"withLast",
"withSort",
"embed",
"gist",
"jsfiddle",
"isEmpty",
"iterate",
"length",
"and",
"compare",
"contains",
"gt",
"gte",
"has",
"eq",
"ifEven",
"ifNth",
"ifOdd",
"is",
"isnt",
"lt",
"lte",
"neither",
"or",
"unlessEq",
"unlessGt",
"unlessLt",
"unlessGteq",
"unlessLteq",
"moment",
"fileSize",
"read",
"readdir",
"css",
"ellipsis",
"js",
"sanitize",
"truncate",
"ul",
"ol",
"thumbnailImage",
"i18n",
"inflect",
"ordinalize",
"info",
"bold",
"warn",
"error",
"debug",
"_inspect",
"markdown",
"md",
"mm",
"match",
"isMatch",
"add",
"subtract",
"divide",
"multiply",
"floor",
"ceil",
"round",
"sum",
"avg",
"default",
"option",
"noop",
"withHash",
"addCommas",
"phoneNumber",
"random",
"toAbbr",
"toExponential",
"toFixed",
"toFloat",
"toInt",
"toPrecision",
"extend",
"forIn",
"forOwn",
"toPath",
"get",
"getObject",
"hasOwn",
"isObject",
"merge",
"JSONparse",
"parseJSON",
"pick",
"JSONstringify",
"stringify",
"absolute",
"dirname",
"relative",
"basename",
"stem",
"extname",
"segments",
"camelcase",
"capitalize",
"capitalizeAll",
"center",
"chop",
"dashcase",
"dotcase",
"hyphenate",
"isString",
"lowercase",
"occurrences",
"pascalcase",
"pathcase",
"plusify",
"reverse",
"replace",
"sentence",
"snakecase",
"split",
"startsWith",
"titleize",
"trim",
"uppercase",
"encodeURI",
"decodeURI",
"urlResolve",
"urlParse",
"stripQuerystring",
"stripProtocol"
];
for (let i = 0; i < handlebarFunctionNames.length; i++) {
const element = handlebarFunctionNames[i];
let regEx = new RegExp("{{#.*?" + element + ".*?}}", "m");
if (regEx.test(templateContent)) {
await this.LoadHandlebarsHelpers();
break;
}
}
let template = Handlebars.compile(templateContent);
let result = template(templateContext);
if (result.indexOf("-preview-item") != -1) {
@ -418,7 +578,7 @@ abstract class BaseTemplateService {
}));
}
private async _loadVideoLibrary(){
private async _loadVideoLibrary() {
// Load Videos-Js on Demand
// Webpack will create a other bundle loaded on demand just for this library

View File

@ -19,6 +19,5 @@ export interface ISearchResultsWebPartProps {
selectedLayout: ResultsLayoutOption;
externalTemplateUrl: string;
inlineTemplateText: string;
useHandlebarsHelpers: boolean;
webPartTitle: string;
}

View File

@ -87,9 +87,6 @@ export default class SearchResultsWebPart extends BaseClientSideWebPart<ISearchR
let queryKeywords;
let renderElement = null;
if (typeof this.properties.useHandlebarsHelpers === 'undefined') {
this.properties.useHandlebarsHelpers = true;
}
// Get value from data source
const dataSourceValue = this.properties.queryKeywords.tryGetValue();
@ -171,12 +168,9 @@ export default class SearchResultsWebPart extends BaseClientSideWebPart<ISearchR
this._templateService = new TemplateService(this.context.spHttpClient, this.context.pageContext.cultureInfo.currentUICultureName);
}
await this._templateService.LoadHandlebarsHelpers(this.properties.useHandlebarsHelpers);
// Configure search query settings
this._useResultSource = false;
// Set the default search results layout
this.properties.selectedLayout = this.properties.selectedLayout ? this.properties.selectedLayout : ResultsLayoutOption.List;
@ -265,8 +259,6 @@ export default class SearchResultsWebPart extends BaseClientSideWebPart<ISearchR
this.properties.externalTemplateUrl = '';
}
}
await this._templateService.LoadHandlebarsHelpers(this.properties.useHandlebarsHelpers);
}
/**
@ -689,10 +681,6 @@ export default class SearchResultsWebPart extends BaseClientSideWebPart<ISearchR
dialogTitle: strings.DialogTitle,
saveButtonText: strings.SaveButtonText
}
}),
PropertyPaneToggle('useHandlebarsHelpers', {
label: "Handlebars Helpers",
checked: this.properties.useHandlebarsHelpers
})
];