Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

how to user handlebars-loader with handlebars-helpers #110

Open
Shpiller opened this issue Sep 14, 2016 · 29 comments
Open

how to user handlebars-loader with handlebars-helpers #110

Shpiller opened this issue Sep 14, 2016 · 29 comments

Comments

@Shpiller
Copy link

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

@mAAdhaTTah
Copy link
Contributor

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

@mAAdhaTTah
Copy link
Contributor

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

Handlebars.registerHelper('myHelper', myHelperFunction);

@mAAdhaTTah
Copy link
Contributor

The Handlebars documentation has more info.

@villeristi
Copy link

@mAAdhaTTah some example would be nice, cheers.

@mAAdhaTTah
Copy link
Contributor

@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.

@phoenixbox
Copy link

@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 👍

@sidonaldson
Copy link

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

@gregholland
Copy link

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?

@craigmulligan
Copy link

@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
Copy link

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?

@mAAdhaTTah
Copy link
Contributor

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

@mAAdhaTTah
Copy link
Contributor

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.

@astorije
Copy link

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!

@kimyu92
Copy link

kimyu92 commented Jan 18, 2018

@mAAdhaTTah mind to share your webpack config?

@mAAdhaTTah
Copy link
Contributor

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.

@kimyu92
Copy link

kimyu92 commented Jan 19, 2018

@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)));

@mAAdhaTTah
Copy link
Contributor

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.

@kimyu92
Copy link

kimyu92 commented Jan 22, 2018

@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?

@pcardune
Copy link
Owner

@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.

@mAAdhaTTah
Copy link
Contributor

@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.

@kimyu92
Copy link

kimyu92 commented Jan 23, 2018

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

@davedub
Copy link

davedub commented Jan 29, 2018

@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

@mAAdhaTTah
Copy link
Contributor

@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.

@davedub
Copy link

davedub commented Jan 29, 2018

@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.

@Vadorequest
Copy link

would definitely be nice to have a proper solution.

@impankratov
Copy link

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

@victorgb6
Copy link

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!

@vmohir
Copy link

vmohir commented Apr 5, 2020

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;

@wehttam0
Copy link

wehttam0 commented Feb 4, 2021

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests