underscore-template-loader icon indicating copy to clipboard operation
underscore-template-loader copied to clipboard

Cannot use variables for attributes in include or require macros

Open jamesehly opened this issue 7 years ago • 3 comments

It would be cool if we could use variables with the require and include macros, but it looks like they can only accept string, number, boolean and objects at the moment. For instance, doing this:

@include(htmlWebpackPlugin.options.filename)

results in...

ERROR in   Error: Child compilation failed:
  Module not found: Error: Can't resolve './NaN' in 'C:\static\outkit-docs\src\templates\docs':
  Error: Can't resolve './NaN' in 'C:\static\outkit-docs\src\templates\docs'

Does anyone know of a workaround for this?

jamesehly avatar Oct 05 '17 12:10 jamesehly

+1, the other possible desired use case is something like that – just use something JS evaluate-able :

@require('./header.html', {
    someValue: 2 + 3,
    title: (originalTitle && originalTitle.trim()) || 'no title',
})

This could allow to have more dynamic and complex templating, and generate more static htmls instead of having it in runtime.

idudinov avatar Oct 18 '18 09:10 idudinov

OK, I've investigated the sources a bit, and have found out that object literal (used as second @require argument) is processed by JSON.parse and then by JSON.stringify inside the loader, so should be evaluated somehow before @require is parsed. But as for now, it doesn't seem feasible to me to swap the order of parsing steps or add additional one. So I have no idea how that feature can be implemented.

idudinov avatar Oct 18 '18 12:10 idudinov

A workaround came to me suddenly :) Tricky a bit, and uses portions of the loader's source code as example, but here it is:

<%
    const title = 'Some ' + 'title';
    const headFileName = htmlWebpackPlugin.options.headFileName || 'head.ejs';

    function objExtend(args, obj) {
        args = Array.prototype.slice.call(args);
        args[0] = Object.assign(obj, args[0]);
        return args;
    };
%>

<%= require(`./structure/${headFileName}`).apply(null, objExtend(arguments, { title })) %>

idudinov avatar Oct 18 '18 12:10 idudinov