Reading Metadata for Posts

Learning Gulp : part 20 of 22 published on Aug 10, 2015

Lets add metadata to the top of each post that we can read in to then use in our Handlebars templates.

Let’s add a title for each page.

{
  "title": "My First Page"
}
---
<!-- /contents/pages/first_page.md -->

# Isn't markdown great!

Yes, it makes a **bold** statement.

Now add the title to our page.hbs template.

<!-- /contents/page.hbs -->
<!DOCTYPE html>
<html>
<head>
  <title>{{ title }}</title>
  <link rel="stylesheet" href="/styles/main.min.css" />
</head>
<body>
  <a href="/">Back to Home</a>
  {{{ contents }}}
</body>
</html>

And we want to install underscore to access the data from an array easier.

$ npm install underscore --save-dev

Then we can adjust our task code to read the meta data in and use that data when generating the pages.

// /gulpeFile.js
var path = require('path');
var _ = require('underscore');

var Data = {
  pages: {}
};
...
gulp.task('generate_pages', function() {
  // read the template from page.hbs
  return gulp.src('contents/page.hbs')
    .pipe(tap(function(file) {
      // file is page.hbs so generate template from file
      var template = Handlebars.compile(file.contents.toString());

      // now read all the pages from the pages directory
      return gulp.src('contents/pages/**.md')
        .pipe(tap(function(file) {
          // use path library to get file name
          var name = path.basename(file.path, ".md");
          // read meta data contents
          var contents = file.contents.toString();
          var index = contents.indexOf("---");
          // metadata found
          if (index !== -1) {
            var data = JSON.parse(contents.slice(0, index));
            // add name to meta data for lookup
            data.name = name;
            // add url to our meta data
            data.url = "/pages/" + file.relative.replace(".md", ".html");
            // save meta data into object outside stream
            Data.pages.push(data);
            // replace file contents without meta data
            contents = contents.slice(index+3, contents.length);
            file.contents = new Buffer(contents, "utf-8");
          }
        }))
        // convert from markdown
        .pipe(markdown())
        .pipe(tap(function(file) {
          var name = path.basename(file.path, ".html");
          // file is the converted HTML from the markdown
          // set the contents to the contents property on data
          var data = _.findWhere(Data.pages, { name: name });
          data.contents = file.contents.toString();
          // we will pass data to the Handlebars template to create the actual HTML to use
          var html = template(data);
          // replace the file contents with the new HTML created from the Handlebars template + data object that contains the HTML made from the markdown conversion
          file.contents = new Buffer(html, "utf-8");
        }))
        .pipe(gulp.dest('build/pages'));
    }));
});

Run our new gulp task.

Using gulpfile ~/js/gulpwalkthru/gulpFile.js
Starting 'generate_pages'...
Finished 'generate_pages' after 20 ms

And view our results. Notice our title!

<!-- /build/pages/first_page.html -->
<!DOCTYPE html>
<html>
<head>
  <title>My First Page</title>
  <link rel="stylesheet" href="/styles/main.min.css" />
</head>
<body>
  <a href="/">Back to Home</a>
<h1 id="isn-t-markdown-great-">Isn&#39;t markdown great!</h1>
<p>Yes, it makes a <strong>bold</strong> statement.</p>

</body>
</html>
Next: Creating Links