Search code examples
replacehandlebars.jsbigcommercehelper

How does the "replace" handlebars helper work?


Faceted search is giving me problems when the facet name includes special characters - specifically /, (, and ). I am trying to replace special characters using the handlebars helpers built into Stencil. I keep getting a 500 error any time I use the replace handlebar helper.

npm's documentation example:

{{replace "Liquid Snake" "Liquid" "Solid"}}

Even using that exact bit of code (simple Strings, not variables), I get the 500 error.

Here's the log:

Debug: internal, implementation, error 
TypeError: Uncaught error: options.inverse is not a function
at Object.<anonymous> (/Users/theuser/.nvm/versions/node/v4.4.0/lib/node_modules/@bigcommerce/stencil-cli/node_modules/@bigcommerce/stencil-paper/helpers/replace.js:19:28)
at Object.template.1 (eval at <anonymous> (/Users/theuser/.nvm/versions/node/v4.4.0/lib/node_modules/@bigcommerce/stencil-cli/node_modules/@bigcommerce/stencil-paper/index.js:71:44), <anonymous>:11:72)
at Object.prog [as fn] (/Users/theuser/.nvm/versions/node/v4.4.0/lib/node_modules/@bigcommerce/stencil-cli/node_modules/handlebars/dist/cjs/handlebars/runtime.js:193:15)
at Object.<anonymous> (/Users/theuser/.nvm/versions/node/v4.4.0/lib/node_modules/@bigcommerce/stencil-cli/node_modules/@bigcommerce/stencil-paper/helpers/if.js:85:28)
at Object.template.main (eval at <anonymous> (/Users/theuser/.nvm/versions/node/v4.4.0/lib/node_modules/@bigcommerce/stencil-cli/node_modules/@bigcommerce/stencil-paper/index.js:71:44), <anonymous>:70:35)
at Object.ret [as components/faceted-search/facets/multi] (/Users/theuser/.nvm/versions/node/v4.4.0/lib/node_modules/@bigcommerce/stencil-cli/node_modules/handlebars/dist/cjs/handlebars/runtime.js:159:30)
at Object.<anonymous> (/Users/theuser/.nvm/versions/node/v4.4.0/lib/node_modules/@bigcommerce/stencil-cli/node_modules/@bigcommerce/stencil-paper/helpers/dynamicComponent.js:32:50)
at Object.template.7 (eval at <anonymous> (/Users/theuser/.nvm/versions/node/v4.4.0/lib/node_modules/@bigcommerce/stencil-cli/node_modules/@bigcommerce/stencil-paper/index.js:71:44), <anonymous>:33:109)
at Object.prog [as fn] (/Users/theuser/.nvm/versions/node/v4.4.0/lib/node_modules/@bigcommerce/stencil-cli/node_modules/handlebars/dist/cjs/handlebars/runtime.js:193:15)
at Object.<anonymous> (/Users/theuser/.nvm/versions/node/v4.4.0/lib/node_modules/@bigcommerce/stencil-cli/node_modules/@bigcommerce/stencil-paper/helpers/if.js:85:28)

Solution

  • I think you are looking at the documentation for the wrong replace helper. The helper library you are using is from BigCommerce and its replace helper is a Handlebars Block Helper. The way to use it would be:

    {{#replace "Liquid" "Liquid Snake"}}Solid{{/replace}}
    

    Edit

    Thanks for pointing out that I had incorrectly wrapped the replacement string in my example in mustache brackets. I have replaced {{"Solid"}} with Solid in my original code block, so the example is now correct.

    As to your follow-up about there being no output when the string to be replaced (the needle) is not found in the target string (the haystack): It turns out that this is the designed behavior of the helper. I have checked the source code, and I can confirm that it implements the following rules:

    • If the haystack contains the needle, return the haystack with all instances of the needle replaced.
    • If the haystack does not contain the needle, return the else branch of the helper.

    This means that if we want to display any output, like the original haystack, when there are no matches of the needle within the haystack, then we must do so with an else branch in our template:

    {{#replace "Liquid" "Liquid Snake"}}Solid{{else}}Liquid Snake{{/replace}}
    

    Truthfully, this does seem like a quite awkward implementation of this helper.