Using grunt js, how can I dynamically add the <title> to static html files? Using grunt js, how can I dynamically add the <title> to static html files? json json

Using grunt js, how can I dynamically add the <title> to static html files?


Here is my take on this. Uses grunt's standard template mechanism, page metadata is defined in an object, outside of actual page files, as you suggested (I can't say I like this).

gruntfile (including the wrap task from Using grunt concat, how would I automate the concatenation of the same file to many other files?):

/*global module:false*/    module.exports = function(grunt) {  // Project configuration.  grunt.initConfig({    meta: {      version: '0.1.0',      banner: '/*! PROJECT_NAME - v<%= meta.version %> - ' +        '<%= grunt.template.today("yyyy-mm-dd") %>\n' +        '* http://PROJECT_WEBSITE/\n' +        '* Copyright (c) <%= grunt.template.today("yyyy") %> ' +        'YOUR_NAME; Licensed MIT */'    },    // Paths    project: {      partials: 'assets/partials',  // don't put trailing slash      pages:    'assets/pages',     // don't put trailing slash      less:     'assets/less',      css:      'assets/css',      img:      'assets/img',      js:       'assets/js'    },    // Used for page title and nav generation.    // It's an array to ensure correct order for nav    pages: [{           file: 'index.html',        title: 'My homepage'        /* This format can be extended to something like:         * {         *      title: 'My homepage',         *      header: 'Welcome to my site',         *      navtitle: 'Home'         * }         * Although I think it's best to keep page metadata as close to content as possible,         * i.e. right inside pages files (think YAML headers in Jekyll pages)           */    }, {        file: 'about.html',        title: 'About me'    }, {        file: 'contact.html',        title: 'Contact'    }],    // wraps files with header and footer    wrap: {        html: {            header: '<%= project.partials %>/head.tmpl',            footer: '<%= project.partials %>/footer.tmpl',            src: [                '<%= project.pages %>/index.html',                '<%= project.pages %>/about.html',                '<%= project.pages %>/contact.html'            ],            dest: '.'   // destination *directory*, probably better than specifying same file names twice        }    },    // processes templates in page files    buildPages: {        pages: '<config:pages>',    // page files metadata        dir: '.'                    // page files location dir    }  });  // Default task.  grunt.registerTask('default', 'wrap buildPages');  grunt.registerMultiTask('wrap', 'Wraps source files with specified header and footer', function() {        var data = this.data,            path = require('path'),            dest = grunt.template.process(data.dest),            files = grunt.file.expandFiles(this.file.src),            header = grunt.file.read(grunt.template.process(data.header)),            footer = grunt.file.read(grunt.template.process(data.footer)),            sep = grunt.utils.linefeed;         files.forEach(function(f) {            var p = dest + '/' + path.basename(f),                contents = grunt.file.read(f);            grunt.file.write(p, header + sep + contents + sep + footer);            grunt.log.writeln('File "' + p + '" created.');        });  });  grunt.registerTask('buildPages', 'Processes templates in page files', function() {  // NOTE: current implementation replaces files    var data = grunt.config('buildPages'),        pages = data.pages,        dir = data.dir,        contents,        curPath;    pages.forEach(function(page) {        curPath = dir + '/' + page.file;        contents = grunt.file.read(curPath);        // feed the entire pages array and current entry to the template        grunt.file.write(curPath, grunt.template.process(contents, {            pages: pages,            curPage: page        }));        grunt.log.writeln('Page at "' + curPath + '" built.');    });  });};

head.tmpl:

<!DOCTYPE html><html>    <head>        <title><%= curPage.title %></title>    </head>    <body>        <!-- NAV -->        <ul class="nav">            <%                pages.forEach(function(p) {                    print(                        '<li class="' + ((curPage === p) ? 'active' : '') + '">' +                            ((curPage === p) ? p.title : ('<a href="' + p.file + '">' + p.title + '</a>')) +                         '</li>\n'                    );                });            %>        </ul>        <!-- /NAV -->        <!-- MAIN CONTENT -->        <div class="main">

footer.tmpl:

        </div>        <!-- /MAIN CONTENT -->    </body></html>