handlebars-loader icon indicating copy to clipboard operation
handlebars-loader copied to clipboard

how to user handlebars-loader with handlebars-helpers

Open Shpiller opened this issue 9 years ago • 29 comments

handlebars-helpers link https://github.com/assemble/handlebars-helpers

Shpiller avatar Sep 14 '16 07:09 Shpiller

Set knownHelpersOnly to false and register the helpers at runtime the old-fashioned way.

mAAdhaTTah avatar Oct 26 '16 14:10 mAAdhaTTah

var Handlebars = require('handlebars/runtime');

Handlebars.registerHelper('myHelper', myHelperFunction);

mAAdhaTTah avatar Oct 26 '16 15:10 mAAdhaTTah

The Handlebars documentation has more info.

mAAdhaTTah avatar Oct 26 '16 15:10 mAAdhaTTah

@mAAdhaTTah some example would be nice, cheers.

villeristi avatar Nov 03 '16 00:11 villeristi

@villeristi @sidonaldson I gave an example above. The helpers linked appear to register themselves with the Handlebars runtime, if you pass your own instance. There isn't anything webpack-specific going on here. The above example would go in your application code.

mAAdhaTTah avatar Nov 03 '16 12:11 mAAdhaTTah

@villeristi heres an example of what I used recently to set my google maps api key per environment.

https://gist.github.com/phoenixbox/d095d29fc09792ae4f51bf5f60aadd06

any questions let me know 👍

phoenixbox avatar Nov 10 '16 02:11 phoenixbox

@villeristi how do you use handlebars-loader with handlebars-helpers in webpack?

sidonaldson avatar Nov 10 '16 08:11 sidonaldson

I can't get this to work. WebPack compiles the handlebars template, then when my application is run registerHelper is called, but it's too late as the template is already compiled. Where am I going wrong?

gregholland avatar Feb 26 '17 01:02 gregholland

@phoenixbox you're example doesn't seem to use handlebars-helpers?

I've tried registering with the handlebars/runtime

require('handlebars-helpers')({
  handlebars: require('handlebars/runtime')
});

But webpack throws a bunch of errors aliasing explained here

Anyone had any luck with this?

craigmulligan avatar Mar 07 '17 10:03 craigmulligan

Hey All,

So I managed to register helpers individually by forking and then altering the export from the loader.

This is how I did it.

var helpers = require('handlebars-helpers')();

      // export as module if template is not blank
      var slug = template ?
        'var Handlebars = require(' + JSON.stringify(runtimePath) + ');\n'
        + 'Handlebars.registerHelper("capitalize", ' + helpers.capitalize + ');\n'

Still figuring out how to register them all at once, problem is we you can't JSON.stringify an all the methods as they lose scope.

@mAAdhaTTah any idea on how to go about this?

craigmulligan avatar Mar 10 '17 20:03 craigmulligan

Best guess is to use webpack to alias handlebars/runtime to the path to the CJS instance of the runtime.

mAAdhaTTah avatar Mar 10 '17 20:03 mAAdhaTTah

Hi everyone,

I got an email from someone about this issue recently. After going back and forth for a bit, the way we solved it was to specific the loader's options.runtime to match the handlebars/runtime alias, so that when you import hbs from 'handlebars/runtime';, hbs is the same Handlebars environment as the one used by your application code.

imo we should probably not be using require.resolve at all in the loader, and should just default to handlebars/runtime, which moves it from node's require resolution algo into webpack's, which is then subject to the resolve.alias rules.

mAAdhaTTah avatar Apr 17 '17 18:04 mAAdhaTTah

Hey there!

Has anyone actually been able to solve this? I'd be curious to see some working configuration, not sure how to integrate with this Webpack config for now.

Thanks!

astorije avatar Dec 10 '17 08:12 astorije

@mAAdhaTTah mind to share your webpack config?

kimyu-ng avatar Jan 18 '18 05:01 kimyu-ng

Best example I have public is here and I register the helpers here. Note that, in this case, I also have aliases for handlebars & handlebars/runtime. The reason for this is the test file is intended to run both in Node with Mocha as well as a browser with Mocha + Karma, and Handlebars behaves slightly differently depending on whether it's running in Node vs. Browser (it modifies node to allow you to require files with .hbs extensions).

This may be a bit complicated for the use case here, but should give you an idea of what you might need to do to to get external helpers working. Also note that I'm not sure the knownHelpers key is necessary, but once I got it working, I didn't change it.

mAAdhaTTah avatar Jan 18 '18 15:01 mAAdhaTTah

@mAAdhaTTah I get passed a lot of error based on your example, I would be nice if we don't have to do this at all and able to call those helpers on .hbs file

hbs.registerHelper('blackbox', attr => new hbs.SafeString(blackboxAttribute(attr)));
hbs.registerHelper('container', attr => new hbs.SafeString(containerAttribute(attr)));
hbs.registerHelper('key', attr => new hbs.SafeString(keyAttribute(attr)));
hbs.registerHelper('event', (...args) => new hbs.SafeString(eventAttribute(...args)));

kimyu-ng avatar Jan 19 '18 17:01 kimyu-ng

Unfortunately, you can't really get around that. You have to either write a helper file for every helper you want to register with the loader, or you have to manually register helpers at runtime. I think that's the best we can do.

mAAdhaTTah avatar Jan 19 '18 19:01 mAAdhaTTah

@pcardune any idea how we can contribute to handlebars loader to support handlebars-helpers so that there is a path way to use those helpers without so much hassles like what @mAAdhaTTah suggested above?

kimyu-ng avatar Jan 22 '18 19:01 kimyu-ng

@kimyu92 best way to contribute is to submit a pull request! I actually don't use handlebars-loader myself anymore and am just here to review PRs and publish new releases. If anyone would like to help with that I can give you write access to this repo and the npm package.

pcardune avatar Jan 22 '18 20:01 pcardune

@kimyu92 The bigger problem is you may not be able to set up integration with a package like handlebars-helper in a generic enough way to integrate with other helper libraries, unless all of them work the same way.

mAAdhaTTah avatar Jan 22 '18 21:01 mAAdhaTTah

sounds like what i could do is to port the whole handlebars helpers that complement with this loader so that people can easily use them by pointing to the dir

kimyu-ng avatar Jan 23 '18 05:01 kimyu-ng

@mAAdhaTTah Where do you register the helpers so that the loader sees them? You are linking to a test file but if you have this in a build, and you specify the known helpers in webpack.config.js, and you write them in a dir (say src/helpers), and then you reference them in a hbs file with double brackets, I can't get them to work. I can get them to work as partials -- {{> nameOfHelper }}, but not as helpers -- {{ nameOfHelper }}. Personal project (exploratory) where this is not working:

https://github.com/davedub/handlepack

davedub avatar Jan 29 '18 00:01 davedub

@davedub Best bet is to put it in an entry point or in a separate module imported by the entry point. Register them as early as possible so you don't accidentally attempt to run template functions before they've been registered.

mAAdhaTTah avatar Jan 29 '18 00:01 mAAdhaTTah

@mAAdhaTTah Yep, was making it harder than it needed to be. Thanks for the tip. Adding the helper registers to the entry point of the app (in this case, app.js) and making sure the loader is fully configured in webpack.config.js, helpers work as indicated. @villeristi if you are still interested in an example, my project (linked above) has Handlebars helpers and partials pre-compiling via Webpack v2. I found the examples in the handlebars-loader project (which seem to be from Webpack v1) - while it's nice they are there - still hard to follow.

davedub avatar Jan 29 '18 17:01 davedub

would definitely be nice to have a proper solution.

Vadorequest avatar Feb 28 '18 11:02 Vadorequest

Managed to get this working. All you need to do is (just as @mAAdhaTTah said) to register helpers manually.

In short:

  • create separate *.js file
  • import Handlebars
  • register custom helpers
  • export resulting Handlebars object
  • point handlebars-loader to that exported Handlebars (hint: use "runtime" property).

Example

impankratov avatar Jun 29 '18 19:06 impankratov

I've tried @impankratov solution for "handlebars-helpers" library but I cannot make it work, anyone has acomplished this and could share an example of the config?

Thanks!

victorgb6 avatar Jul 17 '19 14:07 victorgb6

Thanks @impankratov. Here's an example based on your approach:

const Handlebars = require('handlebars/runtime');
Handlebars.registerHelper('loud', function(aString) {
  return aString.toUpperCase();
});
module.exports = Handlebars;

vmohir avatar Apr 05 '20 17:04 vmohir

@gvmohzibat requiring 'handlebars/runtime' instead of just 'handlebars' did the trick!

wehttam0 avatar Feb 04 '21 18:02 wehttam0