plugin-hbs icon indicating copy to clipboard operation
plugin-hbs copied to clipboard

handlebars partials support is not convenient.

Open larryhe opened this issue 10 years ago • 4 comments

Hi @davis , this is a great SystemJs plugin. Really love it. but its handlebar partials support is not really convenient. because for each partials, you have to manually register it beforehand. So how can I make it automatically register partials while parsing handlebars template? I know require-handlebars-plugin does this type of things. (https://github.com/SlexAxton/require-handlebars-plugin/blob/master/hbs.js). Thanks for the great job.

larryhe avatar Jan 18 '16 00:01 larryhe

Hey Larry, could you provide an example of what you mean? Thanks!

davis avatar Jan 25 '16 19:01 davis

Hi @davis , I mean this plugin should be able to parse handlebar template and automatically register partials. for example. I have below handlebar template. the plugin should extract /path/to/myPartial out and automatically register it. requirejs-handlebar-plugin works that way. It's the same thing for helper. Not sure If i am making sense. Thanks.

{{> /path/to/myPartial }}

larryhe avatar Jan 26 '16 17:01 larryhe

This is something I recently dealt with in a custom handlebars plugin. Here's a basic overview of how it works:

  • Steals the function findPartials from here to traverse the DOM of a template to get a list of partials.
  • Overrides the fetch method on the handlebars plugin to add dependencies to the template. Looks a bit like this:
export function fetch(load, fetcher) {
  return fetcher(load)
    .then(templateSrc => {
      let partials = findPartials(Handlebars.parse(templateSrc));
      // adds partials to dependencies
      return templateSrc;
    });
}
  • Sends the partials to a separate partial plugin. This requires registering the partial plugin, and amending the attached partials to dependencies to have the right plugin attached. So if you say register the plugin as hbsTmpl, then you'd expand the above // adds partials to dependencies to:
load.metadata.deps = partials.map(p => `${partial}!hbsTmpl`);
  • The main plugin then needs to list the dependencies in the output code. System.js will automatically call the partial plugin on each listed dependency. Each partial will in turn have to do its own discovery & attachment of dependencies to deal with nested partials.
  • The partial plugin looks more-or-less the same as the main plugin, but has different handling of the generated code. The template is specifically registered as a partial rather than exporting it, like so:
let depRequires = load.metadata.deps.map(d => `require("${d}");`;
load.source = `
${depRequires.join('\n')}
require('${handlebarsRuntimePath}').registerPartial(${load.name}, Handlebars.template(${precompiled});
`;

It's rough, but I could fold it up into a PR if there's interest. There's a few points that are definitely sub-par that will need some work before it's really "merge ready", though.

BennettJames avatar Jan 28 '16 18:01 BennettJames

@BennettJames would definitely be open to PRs!

davis avatar Jan 28 '16 19:01 davis