3

Learning handlebars and Express I'm trying to learn of a way to send an object without always having to build in the render. For example if I have:

const details = {
  version: process.env.npm_package_version,
  author: 'foobar'
}

I can send this to my footer.hbs in partials from:

app.get('/', (req, res) => {
  res.render('index', {
    details
  })
})

but looking for a way to send it to a template file and not always in a render I've read in the documentation about block helpers and tried:

// Define paths for Express config
const publicDir = path.join(__dirname, '../public')
const viewsPath = path.join(__dirname, '../templates/views')
const partialsPath = path.join(__dirname, '../templates/partials')

// Setup hbs engine and views location
app.set('view engine', 'hbs')
app.set('views', viewsPath)
hbs.registerPartials(partialsPath)

hbs.registerHelper('appDetails', () => {
  const details = {
    version: process.env.npm_package_version,
    author: 'foobar'
  }

  return details
})

but in my directory /partials from file footer.hbs I try to use the helper:

<footer>
    <p>Created by {{details.author}} | version: {{details.version}}</p>
</footer>

and it doesn't work. I've searched the site and I've read:

In my Node and Express app is there a way to send data to the partials file without having to always send it in render?

DᴀʀᴛʜVᴀᴅᴇʀ
  • 7,681
  • 17
  • 73
  • 127

1 Answers1

0

There are two ways a Handlebars Helper can add data to the rendering context of a template:

1) By directly mutating the template's context or 2) By using private variables

Example: https://codepen.io/weft_digital/pen/JjPZwvQ

The following helper updates or adds the data points name and newData to the template's global context, and it also passes a private variable, using the data option.

Handlebars.registerHelper('datainjection', function(context, options) {
     this.name = "Bob";
     this.newData = "Updated"
     return context.fn(this, { data: {private:"pirate"} });
});

Before you call the {{#datainjection}}{{/datainjection}} block in your template, {{name}} will be set to whatever value you pass to the render function, but every occurrence of {{name}} within or after the {{#datainjection}}{{/datainjection}} block will use the updated value, which is "Bob" in this case.

The private variable we are passing can only be accessed within the {{#datainjection}}{{/datainjection}} block using the "@" decorator.

For example:

{{#datainjection}}{{@private}}{{/datainjection}}

will render the string "pirate"

Neil VanLandingham
  • 1,016
  • 8
  • 15