Looping over json, gulp-nunjucks-render rendering all files with same content

1k views Asked by At

I'm trying to render 30+ html pages with gulp-nunjucks-render. I have created one nunjucks template and two json files (general template parts for header and footer and an array of posts data). The logic inside the "posts" function loop is simple: I take the general info that all posts use, add the right post info and send the data to function that renders it into a html file.

I'm using gulp-util inside my "html" function to log out the data that's used for rendering and I see that the data is correct (different for every post). Also the filenames are different every time as they should be. The problem is that the rendered html files content is the same - the content of the latest rendered data.

Relevant parts of my gulp file:

var gulp = require('gulp'), 
    watch = require('gulp-watch'),
    rename = require('gulp-rename'),
    replace = require('gulp-replace'),
    nunjucks = require('gulp-nunjucks-render'),
    data = require('gulp-data'),
    gutil = require('gulp-util');


  gulp.task('watch-projects', function(){ 
  watchDir({ 
      output: 'group/',
      njk: 'group/parts/**/*.html',
      html: 'group/parts/*.html'});
  });
  function watchDir(project) {
    gulp.watch(project.njk, function() {render(project, "en"); render(project, "et");}); 
  }
  function render(project, language) {
    var data = require('./group/parts/data/' + language + '.json'),
    news = require('./group/parts/data/news.' + language + '.json');
    posts('group/parts/news.njk', project.output + language + "/", data, news);

  }
  function posts(template, output, data, posts) { 
    for (var item in posts.posts) {
      data.posts = posts.posts[item];
      html(template, output, data, {basename: data.posts['filename'], extname: ".html"});
    }
  }
  function html(template, output, thedata, name) {
    if (thedata.posts) {
      gutil.log(thedata.posts['title']);
    }
    gulp.src(template)
    .pipe(data(thedata))
    .pipe(nunjucks({path: ['group/parts/']))
    .pipe(rename(name))
    .pipe(gulp.dest(output));
  }

I use news.en.json file that looks sth like this:

{  
  "posts" : [
    {
      "title" : "some title",
      "hero" : "../img/6.jpg",
      "text" : "some content", 
      "pic1" :  "../img/6.jpg",
      "pic2" : "../img/6.jpg",
      "pic3" : "../img/6.jpg",
      "filename" : "news1"
    },
    {
      "title" : "some title2",
      "hero" : "../img/7.jpg",
      "text" : "some content2", 
      "pic1" :  "../img/7.jpg",
      "pic2" : "../img/7.jpg",
      "pic3" : "../img/7.jpg",
      "filename" : "news2"
    }
  ]
}

And I get two files that have the same content (in this case "some title2","../img/7.jpg","some content2"... in both of them).

What am I doing wrong, when I want to get different content in each html? Is there maybe a problem with gulp or nunjucks?

1

There are 1 answers

0
Kaur Saarepuu On BEST ANSWER

I was writing over the referenced variable every time. I had to make a shallow copy of the data, not to change the referenced object itself. with shallow copy the part copied is stored as a reference, but the rest is stored separately.

function posts(template, output, data, posts) { 
  for (var item in posts.posts) {
    // line below did the trick, also had to change "data" in "html" function call to "current"
    var current = Object.assign({},data);
    current.posts = posts.posts[item];
    html(template, output, current, {basename: current.posts['filename'], extname: ".html"});
  }