sagold / handlebars-webpack-plugin

Renders your html-template at build time
161 stars 45 forks source link

How do I get file path with Handlebars templates? #70

Open simzikov opened 4 years ago

simzikov commented 4 years ago

I am using Webpack and Handlebars templates:

index.html

{{> head.html}}

head.html

<link rel="stylesheet" href="./style.css" />
<title>...</title>

Works like a charm. Now I've added a folder next to index.html:

/index.html
/docs/index.html

Both file import the same head.html. However, the one from the docs folder will have an error in the console because the stylehsheet is not loaded. I could have solved this by passing another variable to it, e.g.:

{{> head.html webRoot="."}}

and

{{> head.html webRoot=".."}}

and change head.html to:

<link rel="stylesheet" href="{{webRoot}}/style.css" />
<title>...</title>

However, I hope to think Handlebars has some built-in variable for that. Is there any?

sagold commented 3 years ago

Hi simpleqcode.

Handlebar-Webpack-Plugin is a simple wrapper around Handlebars. This looks like a specific Handlebars issue to me and your solution seems alright to be used in Handlebars. Additionally, correct path resolution depends on your output-structure and can be configured by webpack or other plugins.

simzikov commented 3 years ago

Hi simpleqcode.

Handlebar-Webpack-Plugin is a simple wrapper around Handlebars. This looks like a specific Handlebars issue to me and your solution seems alright to be used in Handlebars. Additionally, correct path resolution depends on your output-structure and can be configured by webpack or other plugins.

I've solved this by creating a custom {{webRoot}} helper:

helpers: {
    webRoot: function () {
        return '{{webRoot}}';
    },
 },
 onBeforeSave: function (Handlebars, resultHtml, filename) {
    const level = filename.split('//').pop().split('/').length;
    const finalHtml = resultHtml.split('{{webRoot}}').join('.'.repeat(level));

    return finalHtml;
},

Now I can use it like this: <img src="{{webRoot}}/assets/img/logo.png" alt="..." />.

sagold commented 3 years ago

Nice. Thanks for sharing your solution!

5ulo commented 3 years ago

I've solved this by creating a custom {{webRoot}} helper:

Perfect! This was something I was looking for. I had to modify it a bit as I have multiple levels like ../../../, so this is my solution:

onBeforeSave: function (Handlebars, resultHtml, filename) {
    const level = filename.split('//').pop().split('/').length;
    function relPath(level) {
        var res = ( level > 1 ) ? '..' : '.';
        for (var i = 0; i < level; i++) {
            if ( i > 0 ) {
                res += '/..';
            }
        }
        return res;
    }
    const finalHtml = resultHtml.split('{{wroot}}').join(relPath(level));
    return finalHtml;
},