gulpmustache

How do I compile mustache templates partials with gulp?


I make prototypes of static HTML pages with Mustache/Sass/Compass-watch under Ruby. This setup is VERY slow, so I want to move to building everything with Gulp. I managed to have it build Sass, but not Mustache. It just doesn't see partials in mustache templates. My file structure is like this:

.
├── css
├── scss
├── index.html
├── gulpfile.js
└── templates
    ├── index.mustache
    └── partials
        └── header.mustache

where index.mustache is:

{{> partials/head }}

<body>
    {{> partials/header }}

    <div class="wrap">
        {{> some_inner_partial }}

        <div class="content">
            ...
        </div>
    </div>

    {{> partials/footer }}

</body>
</html>

My gulpfile.js goes like this:

var gulp = require('gulp');
var sass = require('gulp-sass');
var sourcemaps = require('gulp-sourcemaps');
var mustache = require("gulp-mustache-plus");

// Gulp Sass Task 
gulp.task('sass', function() {
  gulp.src('./scss/{,*/}*.{scss,sass}')
    .pipe(sourcemaps.init())
    .pipe(sass({
      errLogToConsole: true
    }))
    .pipe(sourcemaps.write())
    .pipe(gulp.dest('./css'));
});

// Gulp Mustache Task 
gulp.task('mustache', function() {
    gulp.src("./templates/*.mustache")
        .pipe(mustache({},{},{
            file_1: "partials/*.mustache"
        })).pipe(gulp.dest("./"));
});

gulp.task('default', ['sass', 'mustache'], function () {
    gulp.watch('./scss/{,*/}*.{scss,sass}', ['sass']);
    gulp.watch('./templates/{,*/}*.{mustache}', ['mustache']);
});

So when I run gulp in console it builds scss->css just fine and watches for changes, but as for mustache it builds html tags but not partials and also it doesn't watch for changes in mustache files.

Obviously there's something wrong with mustache task. Please help me to understand what I'm missing here. I'm very new to task runners, never used Gulp/Grunt before.


Solution

  • So I figured out the solution. In order to make gulp watch for mustache changes I had to change gulp.watch to gulp.watch('./templates/**/*.mustache', ['mustache']); And in order to make gulp-mustache-plus see the partials I need to manually create an object with partial name and path and pass it as a third parameter to mustache task. And that is weired, because no one wants to do a manual work, right?

    Anyway the gulpfile.js must look like this:

    var gulp = require('gulp');
    var sass = require('gulp-sass');
    var sourcemaps = require('gulp-sourcemaps');
    var mustache = require("gulp-mustache-plus");
    
    // Gulp Sass Task 
    gulp.task('sass', function() {
      gulp.src('./scss/{,*/}*.{scss,sass}')
        .pipe(sourcemaps.init())
        .pipe(sass({
          errLogToConsole: true
        }))
        .pipe(sourcemaps.write())
        .pipe(gulp.dest('./css'));
    });
    
    // Gulp Mustache Task 
    gulp.task('mustache', function() {
        gulp.src("./templates/*.mustache")
            .pipe(mustache({},{},{
                head: "./templates/layout/head.mustache",
                header: "./templates/modules/header.mustache",
                ... etc.... //any oter partials
            })).pipe(gulp.dest("./"));
    });
    
    gulp.task('default', ['sass', 'mustache'], function () {
        gulp.watch('./scss/{,*/}*.{scss,sass}', ['sass']);
        gulp.watch('./templates/**/*.mustache', ['mustache']);
    });
    

    And then in my mustache files I had to put partials names from that object:

    {{> head }}
    
    <body>
        {{> header }}
    
        <div class="wrap">
            {{> some_inner_partial }}
    
            <div class="content">
                ...
            </div>
        </div>
    
        {{> footer }}
    
    </body>
    </html>
    

    Now everything works fine.