Using Pug filters and the jsTransformer-handlebars module I'm trying to insert some handlebars code into a pug template that will make use of locals. However, since Pug renders filters at compile time, we can't make use of the templates locals. So I'm wondering if making the jsTransformer available on the browser will fix this, and if so, how to pack the jsTransformer-handlebars module and make it available on the browser.
I have the following helper functions I would typically use with handlebars:
// helpers.js
module.exports = {
truncate: (str, len) => {
//code
return str;
},
stripTags: (input) => input.replace(/<(?:.|\n)*?>/gm, ""),
formatDate: (date, format) => moment(date).format(format),
select: function(selected, options) {
return options
.fn(this)
.replace(new RegExp(` value="${selected}"`), '$&selected="selected"')
.replace(new RegExp(`>${selected}</option>`), 'selected="selected"$&');
},
};
helpers.js gets imported at app.js and the functions are set as application variables. They are all usable in pug, except select()
.
// sets application locals so I can call these functions from a pug template
app.locals = {
truncate,
stripTags,
formatDate,
select,
};
For example, the following code in any pug template returns the formatted date as expected:
#{formatDate(story.date, 'MMMM Do YYYY')}
However, when trying to use the select function:
select(name='status' id='status')
#{select(story.status)}
option(value='Public' selected) Public
option(value='Private') Private
option(value='Unpublished') Unpublished
label(for='status') Status
Gives the breaking error:
Cannot read property 'fn' of undefined
This is most likely because I can't pass in the options parameter like I normally would in handlebars:
<select name ='status' id='status'>
{{#select story.status}}
<option value='Public' selected> Public </option>
<option value='Private'> Private </option>
<option value='Unpublished'> Unpublished </option>
{{#/select}}
I ran the above, using handlebars, and it worked as expected.
The next solution for me was then to use pug filters to insert the handlebars code into pug. However when attempting this the variables wouldn't generate in the filter. This is, of-course, because pug renders filtered code at compile time so the variables/locals never get passed into the handlebars code.
Pug has a warning about this on their documentation
Warning
Filters are rendered at compile time. This makes them fast, but it also means that they cannot support dynamic content or options.By default, compilation in the browser does not have access to JSTransformer-based filters, unless the JSTransformer modules are explicitly packed and made available through a CommonJS platform (such as Browserify or Webpack). In fact, the page you are reading right now uses Browserify to make the filters available in the browser.
Templates pre-compiled on the server do not have this limitation.
Although I currently have a work-around I would really like to get this helper working with pug. I don't specifically need to be able to pass the locals variable into the handlebars filter, since that may not be possible. But, maybe there's something I'm missing with pug that would make the select()
helper work?
I'm really hoping I'm missing something simple in pug that would get the select()
helper working, or that there's a way to make locals accessible from within filters. But, as a newbie any help is appreciated!