pcardune / handlebars-loader

A handlebars template loader for webpack
560 stars 169 forks source link

inlineRequires doesn't work with dynamic context? #132

Open milewski opened 7 years ago

milewski commented 7 years ago

Is there anyway to add a dynamic require ?? for example...

{ "photo": "../path/to/photo.jpg" }
...
<img src="{{ photo }}">

This will result in <img src="../path/to/photo.jpg">

in my webpack config i have

{
    test: /\.handlebars$/,
    loader: 'handlebars-loader',
    options: {
        inlineRequires: /photo/,
        helperDirs: [path.resolve(context, 'views/helpers')],
        partialDirs: [path.resolve(context, 'views/partials')]
    }
}

But because the photo is coming from a helper the inlineRequires options doesn't seem to work as if i would place the ../path/to/photo.jpg directly in the .handlebars file

i have even tried <img src="require('{{ photo }}')"> but doesn't seems to work neither.

it looks like that the inlineRequires phase runs before the helpers parsing phase...

milewski commented 7 years ago

any one could help on this?

putnamn21 commented 7 years ago

Having the same issue. inlineRequire runs first so if you are trying to generate a dynamic src reference it fails.

<img src="../images/{{size}}/foo.jpg" alt="">

rschaufler commented 6 years ago

any news? i'm running into this issue too

CTaylor1118 commented 6 years ago

I think my fork of this at https://github.com/CTaylor1118/handlebars-loader/tree/attributeRequires should be able to handle that.

gregorvoinov commented 6 years ago

Anyone tested this? Because I have the same problem now. Or how can I use your fork? Do I have to replace any files in the node_modules/handlebars-loader folder from your fork?

asked this also on stackoverflow

milewski commented 6 years ago

@gregorvoinov to install a fork or any other lib on github you can always

npm install https://github.com/CTaylor1118/handlebars-loader

i havent tested it personally, as im no longer working on the project that required such functionality.. if it does work for you let us know so we can close this issue and perhaps prepare a pull request to this repo..

rschaufler commented 6 years ago

@gregorvoinov @CTaylor1118 i ended up not using the fork but instead just chaining the handlebars loader. Also inlineRequires is NOT enabled

webpack.config.js

      {
        test: /\.hbs$/,
        use: [
          {
            loader: 'handlebars-loader'
          },
          {
            loader: 'extract-loader'
          },
          {
            loader: 'html-loader',
            options: {
              interpolate: true
            }
          }
        ]
      }

You can then reference your images in your handlebars template just like you would do with the html-loader

<img src="./assets/your-image.jpg" alt="Placeholder">

I think the inlineRequires option could be obsolete, and it doesn't even work within partials. My solution actually does

gregorvoinov commented 6 years ago

@milewski got this error if I install the fork

ERROR in Error: Child compilation failed: Module build failed: TypeError: Cannot read property 'handlebarsLoader' of undefined ...

@rschaufler thank you for your effort, but the path still can't be resolved.

ERROR in ./hbs/partials/icon.hbs Module build failed: ModuleNotFoundError: Module not found: Error: Can't resolve '../../assets/{{name}}.png' in 'AbsolutePathToProject\src\hbs\partials'

gregorvoinov commented 6 years ago

any other ideas?

rschaufler commented 6 years ago

@gregorvoinov have you tried interpolation? i used this to pass assets to partials like this

{{> ./partials/contact asset='${require('./assets/1.jpg')}' }}

gregorvoinov commented 6 years ago

That works 👍 It's not as clean as if I only use one parameter and build the path inside the partial, but at least it works :)

 {{> icon svg="myIcon" fallback="${require('../../assets/myIcon.png')}" }}
fbove commented 6 years ago

This is my webpack.config.js:

{
  test: /\.hbs$/,
  use: [
    {
      loader: 'handlebars-loader'
    },
    {
      loader: 'extract-loader'
    },
    {
      loader: 'html-loader',
      options: {
        interpolate: true
      }
    }
  ]
}

But I've been unable to solve this one:

<img src="~img/{{iconType}}_icon.png" />

Also tried something like:

<img src="${require(`../../img/${iconType}_icon.png`)}" />

It says that iconType is not defined, my guess is that is not defined at html-loader level because it is defined.

Any thoughts?

gregorvoinov commented 6 years ago

@fbove I think that's not possible, because the packaging runs before the runtime and at this moment your variable ${iconType} is not set.

mhluska commented 5 years ago

So there's actually no solution when using dynamic paths from handlebars? For example in an {{#each}} loop.

@CTaylor1118 are there instructions for using your fork?

Edit: I figured out how to get his fork working:

npm install --save-dev CTaylor1118/handlebars-loader#attributeRequires

Add the following to the handlebars-loader config:

query: {
  attributes: ['img:src'],
  parseDynamicRoutes: true,
}

Unfortunately I wasn't able to get it to do anything useful. In my case, I'm trying to get a require working for the following template:

{{#each htmlWebpackPlugin.options.integrations}}
  <img
    src="../../images/integrations/{{this.key}}.{{this.extension}}"
    alt="{{this.name}} logo"
  />
{{/each}}

I give up 😄

SuhushinAS commented 4 years ago

I have found solution with helper:

module.exports = function(iconName, block) {
    const icon = require(`icons/${iconName}.svg`);
    return block.fn({icon});
};

And usage example:

{{#[helpers/withIcon] 'my-icon'}}
    <img src={{icon}} alt="">
{{/[helpers/withIcon]}}