diff --git a/package-lock.json b/package-lock.json index 1ec526b9..c5a6d76c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -6709,9 +6709,9 @@ "dev": true }, "handlebars": { - "version": "4.5.3", - "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.5.3.tgz", - "integrity": "sha512-3yPecJoJHK/4c6aZhSvxOyG4vJKDshV36VHp0iVCDVh7o9w2vwi3NSnL2MMPj3YdduqaBcu7cGbggJQM0br9xA==", + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.6.0.tgz", + "integrity": "sha512-i1ZUP7Qp2JdkMaFon2a+b0m5geE8Z4ZTLaGkgrObkEd+OkUKyRbRWw4KxuFCoHfdETSY1yf9/574eVoNSiK7pw==", "requires": { "neo-async": "^2.6.0", "optimist": "^0.6.1", @@ -13457,9 +13457,9 @@ "dev": true }, "uglify-js": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.7.2.tgz", - "integrity": "sha512-uhRwZcANNWVLrxLfNFEdltoPNhECUR3lc+UdJoG9CBpMcSnKyWA94tc3eAujB1GcMY5Uwq8ZMp4qWpxWYDQmaA==", + "version": "3.7.4", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.7.4.tgz", + "integrity": "sha512-tinYWE8X1QfCHxS1lBS8yiDekyhSXOO6R66yNOCdUJeojxxw+PX2BHAz/BWyW7PQ7pkiWVxJfIEbiDxyLWvUGg==", "optional": true, "requires": { "commander": "~2.20.3", diff --git a/package.json b/package.json index f74e3da7..9ae10646 100644 --- a/package.json +++ b/package.json @@ -67,7 +67,7 @@ "babel-eslint": "^10.0.3", "codemirror": "^5.49.2", "debounce-promise": "^3.1.2", - "handlebars": "^4.5.3", + "handlebars": "^4.6.0", "highlight.js": "^9.16.2", "js-yaml": "^3.13.1", "json5": "^2.1.1", diff --git a/src/.vuepress/config-using-babel.js b/src/.vuepress/config-using-babel.js index 459aec06..65c6c4c4 100644 --- a/src/.vuepress/config-using-babel.js +++ b/src/.vuepress/config-using-babel.js @@ -36,7 +36,7 @@ export default { sidebar: { "/installation/": ["", "precompilation.md", "integrations.md", "when-to-use-handlebars.md"], "/guide/": ["", "expressions.md", "partials.md", "block-helpers.md", "builtin-helpers.md", "hooks.md"], - "/api-reference/": ["", "compilation.md", "runtime.md", "utilities.md", "data-variables.md"], + "/api-reference/": ["", "compilation.md", "runtime.md", "utilities.md", "data-variables.md", "helpers.md"], "/contributing/": ["", "interactive-examples.md", "button-links.md"] }, displayAllHeaders: false, diff --git a/src/api-reference/compilation.md b/src/api-reference/compilation.md index 144b41f8..d7c84cd9 100644 --- a/src/api-reference/compilation.md +++ b/src/api-reference/compilation.md @@ -33,6 +33,8 @@ Supports a variety of options that alter how the template executes. - `explicitPartialContext`: Disables implicit context for partials. When enabled, partials that are not passed a context value will execute against an empty object. +## Runtime options + The resulting template function can be called as `template(context, options)` where `context` is the input object. `options` is an object that can have any of the following properties @@ -46,6 +48,31 @@ The resulting template function can be called as `template(context, options)` wh - `allowCallsToHelperMissing` (since 4.3.0, insecure): If set to `true`, calls like `{{helperMissing}}` and `{{blockHelperMissing}}` will be allowed. Please not that this allows template authors to fabricate templates for Remote Code Execution on the environment running Handlebars (see https://github.com/wycats/handlebars.js/issues/1558) +- `allowedProtoMethods` (since 4.6.0): a string-to-boolean map of property-names that are allowed if they are methods of + the parent object. +- `allowedProtoProperties` (since 4.6.0): a string-to-boolean map of property-names that are allowed if they are + properties but not methods of the parent object. + + ```js + const template = handlebars.compile("{{aString.trim}}"); + const result = template({ aString: " abc " }); + // result is empty, because trim is defined at String prototype + ``` + + ```js + const template = handlebars.compile("{{aString.trim}}"); + const result = template( + { aString: " abc " }, + { + allowedProtoMethods: { + trim: true + } + } + ); + // result = 'abc' + ``` + +```` ::: @@ -55,7 +82,7 @@ Precompiles a given template so it can be sent to the client and executed withou ```js var templateSpec = Handlebars.precompile("{{foo}}"); -``` +```` Supports all of the same options parameters as the `Handlebars.compile` method. Additionally may pass: diff --git a/src/api-reference/helpers.md b/src/api-reference/helpers.md new file mode 100644 index 00000000..fe59afd5 --- /dev/null +++ b/src/api-reference/helpers.md @@ -0,0 +1,13 @@ +# Helpers + +## The `options`-parameter + +In addition to the parameters used in the helper-call, an `options`-object is passed to the helper as additional +parameter. + +- `lookupProperty(object, propertyName)`: a function that returns an "own property" of an object. Whitelists specified + in `allowedProtoProperties` and `allowedProtoMethods` are respected by this functions. Example: + + + +- TODO: Describe all options that are passed to helpers diff --git a/src/examples/helper-lookup-property.md b/src/examples/helper-lookup-property.md new file mode 100644 index 00000000..e397119f --- /dev/null +++ b/src/examples/helper-lookup-property.md @@ -0,0 +1,17 @@ +--- +layout: InteractivePlaygroundLayout +example: + template: | + {{lookupOrDefault this 'firstname' 'Name not found'}} + partials: + preparationScript: | + Handlebars.registerHelper('lookupOrDefault', function (object, propertyName, defaultValue, options) { + var result = options.lookupProperty(object, propertyName) + if (result != null) { + return result + } + return defaultValue + }) + input: + firstname: Yehuda +--- diff --git a/src/installation/index.md b/src/installation/index.md index 2695bd80..e0caafaa 100644 --- a/src/installation/index.md +++ b/src/installation/index.md @@ -1,4 +1,4 @@ -# Installation +# Installations There are a variety of ways to install Handlebars, depending on the programming language and environment you are using.