1

I'm using plop for code generation of some TypeScript files. This is not using HTML at all. Under the hood plop uses Handlebars for it's templating. One of my templates generates a series of new properties on a class like this:

My data looks something like this:

const data = { items: ['one', 'two', 'three'] }

In my template file:

... part of the class

{{#each items}}
import {
  Name as {{this}}Name
} from '.../{{this}}';
{{/each}}

... other stuff happening

{{#each items}}
const thing{{this}} = new Thing({
  someProperty: `${{{this}}Name}`
});
{{/each}}

... the rest of the class

The desired output would look something like this:

import {
  Name as oneName
} from '.../one';
import {
  Name as twoName
} from '.../two';
import {
  Name as threeName
} from '.../three';

const thingone = new Thing({
  someProperty: `${oneName}`
});
const thingtwo = new Thing({
  someProperty: `${twoName}`
});
const thingthree = new Thing({
  someProperty: `${threeName}`
});

The problem seems to be with the `${{{entity}}Name}` portion of the template. When attempting to compile it throws the following error:

Expecting 'CLOSE_UNESCAPED', 'OPEN_SEXPR', 'ID', 'STRING', 'NUMBER', 'BOOLEAN', 'UNDEFINED', 'NULL', 'DATA', got 'CLOSE'

I'm guessing this is because the syntax in handle bars to html escape is denoted by the {{{ syntax.

I'm curious if there is a way to escape that fist { and tell handlebars not to worry about it and treat it as a literal. I know I can split the line like this `${ {{entity}}Name }`, however, that breaks linting rules within the project and is not desirable.

I've tried looking through the handlebars documentation and searching on SO without much luck.

Any help is appreciated.

stetson
  • 145
  • 2
  • 11

1 Answers1

0

I figured this out after some more digging.I found this answer on SO. Looks like the only way to accomplish this is using a handlebar helper function. In my case, since I'm using plop, I can simply put the following in my plopfile:

plop.addHelper('curlyName', (entity) => {
  return `{${entity}Name}`;
});

then call that helper from the template like this

{{#each items}}
const thing{{this}} = new Thing({
  someProperty: `${{curlyName this}}`
});
{{/each}}

which will give me the result of

const thingone = new Thing({
  someProperty: `${oneName}`
});
const thingtwo = new Thing({
  someProperty: `${twoName}`
});
const thingthree = new Thing({
  someProperty: `${threeName}`
});

Really disappointing there isn't a simply way to just throw a / or some other character to escape within the template itself. Hopefully someone finds this helpful and waste a few hours figuring out such a simple thing, like I did.

stetson
  • 145
  • 2
  • 11