assemble / assemble-core

The core assemble application with no presets or defaults. All configuration is left to the implementor.
MIT License
17 stars 2 forks source link

Cannot overwrite pre-existing key/value in `preRender` #9

Open dtothefp opened 8 years ago

dtothefp commented 8 years ago

Demo repo here: https://github.com/dtothefp/assemble-yfm-nunj

"version": "0.8.0" Essentially, overwritting pre-existing data on the file.data context does not seem to work in preRender hook

app.preRender(/\.(?:hbs|md|html)$/, (file, next) => {
  console.log('Append Pre-Render Data Before Merge', file.data);

  file.data = Object.assign({}, file.data, {
    title: 'From Pre-Render',
    custom_stuff: 'Custom stuff from Pre-Render'
  });

  console.log('Append Pre-Render Data After Merge', file.data);
  next();
});

if app.cache.data.title or file.data.title exists then the above doesn't work. I solve this by doing merge in onLoad

app.onLoad(/\.(?:hbs|md|html)$/, (file, next) => {
  matter.parse(file, (err, file) => {
    if (err) return next(err);

    _.assign(file.data, {title: 'blahhhh'});

    next(null, file);
  });
});

or by making a stream plugin

app.task('build', () => {
  return app.src('./templates/pages/**/*.html')
    .pipe(through.obj(function(file, enc, cb) {
      file.data = {title: 'blaahhhhh'}
      this.push(file);
      cb();
    }))
    .pipe(app.renderFile())
    .pipe(app.dest('dist'))
    .on('error', (err) => {
      console.error('Error [assemble]: build');
    })
    .on('data', (file) => {
      console.log('data', file.path);
    })
    .on('end', () => {
      console.log('ended');
    });
});
assemblebot commented 8 years ago

@dtothefp Thanks for the issue! If you're reporting a bug, please be sure to include:

jonschlinkert commented 8 years ago

@dtothefp inside node_modules in assemble-render-file try commenting out the code that creates the ctx object, then just pass locals to render. See if that works. If so we can update that lib. (was just talking to @doowb, he mentioned this)

dtothefp commented 8 years ago

@jonschlinkert when I do that looks like locals is sometimes undefined which causes an error

        // create the context to pass to templates
        //var ctx = utils.merge({}, app.cache.data, locals, file.data);
        //ctx.engine = engine || ctx.engine;

        // render the file
        app.render(file, locals, function(err, res) { //...
/Users/davidfox-powell/dev/prerender-demo/node_modules/assemble-core/node_modules/templates/lib/utils/proto.js:105
  var engine = locals.engine || view.engine || opts.engine;
                     ^

TypeError: Cannot read property 'engine' of undefined
jonschlinkert commented 8 years ago

you probably need to do something like if (!locals) locals = {}