emaphp / underscore-template-loader

A Underscore and Lodash template loader for Webpack
MIT License
104 stars 24 forks source link

Dynamic image path loading, vars in image path #18

Closed oller closed 8 years ago

oller commented 8 years ago

I'm having trouble getting the underscore-template-loader to pick up images with a dynamic path

<img src="/img/cat-<%- currentCat.url %>.png" class="cat-img">

Static images are working fine with the following config.

{
    // Compile templates.  Enables var template = require("template.html")
    test: /\.html$/,
    loader: "underscore-template",
    engine: "lodash",
    query: {
        root: config.app
    }
},

Any suggestions on the best way to implement something like this would be appreciated!

emaphp commented 8 years ago

That happens because the attribute parser would not recognize the contents as a "valid" string. Being that you can override underscore/lodash interpolation regex, implementing such thing it's going to be specially hard (if even possible). Are you getting a error message while trying to do this? Maybe I'm mistaken, but isn't this the same as doing require('./' + module)? (which is not supported by any bundler)

oller commented 8 years ago

Hi @emaphp

The error I get is:

ERROR in ./app/templates/charts.html
Module not found: Error: Cannot resolve 'file' or 'directory' app/img/cat-<%- currentCat.url %>.png in app/templates
 @ ./app/templates/charts.html 

So I agree, it looks like it's trying to interpolate those underscore tags as the filename. I can imagine this is quite a tricky use-case specifically for the loader, but just wondered if I should be approaching it in a different way entirely.

emaphp commented 8 years ago

If I'm not wrong, that error you are getting is webpack trying to load the string as a route and failing because you're not installed neither the file-loader or the url-loader. I'm assuming that that's not the intended approach (and even if it were, it wouldn't work either). Sorry for not being helpful atm, maybe another user can provide another approach to your problem.

emaphp commented 8 years ago

Now that I had a time to meditate on the subject I would say that the loader should be able to handle these kinds of usage just fine. What is needed is a way to tell the attribute parser to ignore the contents of a given attribute. I'm still not sure of how this feature should be implemented though. Maybe a special character at the beginning would do the trick:

<img src="@/img/cat-<%- currentCat.url %>.png" class="cat-img">

Or maybe a special namespace that is translated during compilation:

<img _:src="/img/cat-<%- currentCat.url %>.png" class="cat-img">

This is an approach we didn't anticipate because we were too worried about adding support for the file-loader and forgot that this might actually be useful, not only for images. I'll work on this matter and let you know if I come up with something.

oller commented 8 years ago

Makes sense @emaphp, thanks again for the quick response.

Presumably with that suggested improvement, those files would have to be exempt from the file/url loader as that would rename and change the path of the file, breaking the association. So I'd have to manually set webpack to treat those images differently, or would you imagine the template loader could help with that?

emaphp commented 8 years ago

Het @oller , I've made some changes in the attribute parser. Whenever an attribute contains a template expression it will avoid using the file-loader. This way no special syntax is needed. I've also added a few test cases based on this particular issue. Changes are available in v0.7.1 so try updating you current package and see if it works fot you.

oller commented 8 years ago

That works like a charm @emaphp. Thanks again for the prompt effort.

The only issue i'm encountering is if the image path is absolute, (starts with a /). That is being transformed to the complete absolute path on my machine:

<img src="/Users/oller/path/to/img/cat-demographic.png" width="102" class="cat-img">

Once I click back and forth to get the dynamic populating of the image path, it works fine, it's just that initial load state.

As an aside, any ideas how/if it'd be possible to get this working with some kind of hashing?

emaphp commented 8 years ago

That's actually a feature. You must be defining a "root" argument somewhere in your webpack file (https://github.com/emaphp/underscore-template-loader#images). Have you tried omitting this argument? What I can try to do is leaving the argument untouched if a template expression in found, Which is actually easier to me.

oller commented 8 years ago

Aha yes that was it, I ought to be consistent with the paths to images, so shall remove the root options and update my views accordingly.

I'll extract out a separate image loader for these images, so I won't lose hashing across the rest of the images in the app.

Thanks again for all your help!

emaphp commented 8 years ago

No worries. As you illustrated this behavior could be troublesome in some cases. I've deactivated this feature by default. Also, in order to parse dynamic routes, users will need to specify a special argument in their configuration files. I think this will cover all usage cases for now. Try updating the package to v0.7.2 and see what happens.

oller commented 8 years ago

Looks great to me, thanks again! Closing off.