webdiscus / html-bundler-webpack-plugin

Alternative to html-webpack-plugin ✅ Renders Eta, EJS, Handlebars, Nunjucks, Pug, Twig templates "out of the box" ✅ Resolves source files of scripts, styles, images in HTML ✅ Uses a template as entry point
ISC License
146 stars 14 forks source link

Helper embed / content #29

Closed 5ulo closed 1 year ago

5ulo commented 1 year ago

Feature request

What is motivation or use case for adding/changing the behavior?

Latest build in helpers assign, partial, block are sufficient in most situations. Though there are situations where embed or content helper has more power about controling the block content. Imagine you have section partial

<section>
    <h2>{{title}}</h2>
    {{#block 'section-content'}}
    Default content
    {{/block}}
</section>

Now if I assign custom content to the first section

{{#partial 'section-content'}}
Hello World
{{/partial}}
{{>section title="Lorem"}}
{{>section title="Ipsum"}}
{{#partial 'section-content'}}
Foo Bar
{{/partial}}
{{>section title="Dolor"}}

The custom content will be applied to the second section too instead of leaving the default value.

Describe the solution you'd like

In the past I used handlebars-layouts (https://www.npmjs.com/package/handlebars-layouts) to extend my views which you have done with partial helper (great!). But there is also a embed and content helper which was used in this format:

{{#embed "section" title="Lorem"}}
{{#content 'section-content' mode='(append|prepend|replace)'}}
Hello wordl
{{/content}}
{{/embed}}

This way the custom content was applied only to the specific partial but as you can see it will handle only one partial at a time.

Describe alternatives you've considered

I tried to reset the partial helper to empty string but that will remove the default content of the block.

{{#partial 'section-content'}}
Hello World
{{/partial}}
{{>section title="Lorem"}}
{{#partial 'section-content'}}{{/partial}}
{{>section title="Ipsum"}}
{{#partial 'section-content'}}
Foo Bar
{{/partial}}
{{>section title="Dolor"}}

Maybe some reset helper would be sufficient (?)

webdiscus commented 1 year ago

@5ulo

I find these helpers useful. I will add layouts helpers in the build-in plugin helpers.

Thank you!

5ulo commented 1 year ago

So I was thinking about it found this as most sufficient:

{{#content}}
    {{#partial 'section-content' mode='(append|prepend|replace)'}}Hello World{{/partial}}
    {{#partial 'section-footer'}}<button>Touch me</button>{{/partial}}
    {{>section title="Lorem"}}
{{/content}}

where content is something like a jail for the defined partial helpers inside and is applied only to its embedded partial. And you can define multiple partials in it

webdiscus commented 1 year ago

hi @5ulo,

I have looked these handlebars-layouts helpers in details and I don't want to have them as a build-in in my plugin. Why duplicate existing helpers?

You can very easy bind this helpers with the bundler plugin.

  1. install helpers

    npm i -D handlebars-layouts
  2. add to config

    
    const path = require('path');
    const HtmlBundlerPlugin = require('html-bundler-webpack-plugin');
    const handlebars = require('handlebars');
    const layoutHelpers = require('handlebars-layouts');

module.exports = { mode: 'production', output: { path: path.resolve(dirname, './dist'), }, plugins: [ new HtmlBundlerPlugin({ entry: { index: './src/views/index.html', }, preprocessor: 'handlebars', preprocessorOptions: { helpers: layoutHelpers(handlebars), // <= set handlebars-layouts helpers partials: [ path.join(dirname, 'src/views/partials/'), ], }, }), ], };



This works very well and you will always have the latest version of the helpers.

P.S.: here you can see the [preprocessor-handlebars-helper-layouts](https://github.com/webdiscus/html-bundler-webpack-plugin/blob/master/test/cases/preprocessor-handlebars-helper-layouts/webpack.config.js) test for `handlebars-layouts` helpers.
5ulo commented 1 year ago

I'm using that plugin already. it was just an idea to implement something similar because yours {{#partial}} is a lot cleaner :) Anyways thanks for checking that out.