Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

A gulp workflow with markdown and nunjucks

I am working on setting up a workflow for generating static pages using Markdown and Nunjucks, through Gulp. The current two tasks I rely on for this are:

gulp.task('templates', function() {
    return gulp.src('app/templates/pages/*.nunjucks') 
        .pipe(nunjucksRender({
        path: ['app/templates/', 'app/templates/pages/']
        }))
        .pipe(gulp.dest('app'));
});

gulp.task('pages', function() {
    gulp.src('app/pages/**/*.md')
        .pipe(frontMatter())
        .pipe(marked())
        .pipe(wrap(function (data) {
            return fs.readFileSync('app/templates/pages/' + data.file.frontMatter.layout).toString()
        }, null, {engine: 'nunjucks'}))
        .pipe(gulp.dest('app'))
});

With the following structure:

/app
|   index.html
|
+---css
|       app.scss
|       custom.scss
|
+---js
|       app.js
|
+---pages
|       index.md
|
\---templates
    |   layout.nunjucks
    |
    +---macros
    |       nav-macro.nunjucks
    |
    +---pages
    |       index.nunjucks
    |
    \---partials
            navigation.nunjucks

If I run gulp templates this compiles index.html into /app using index.nunjucks which extends layout.nunjucks. However, I want to use gulp pages to draw frontmatter and Markdown from index.md to generate the contents of index.html.

The problem I am having is pathing: Given the structure above, how to I use /app/pages/index.md as the content for /app/index.html through /app/templates/pages/index.nunjucks? Currently the task fails with Template render error: (unknown path).

Essentially, I am trying to extend what is achieved here: Gulp Front Matter +Markdown through Nunjucks

like image 326
OleVik Avatar asked Mar 13 '23 02:03

OleVik


1 Answers

I have a simplified version of your setup running that uses the exact same Gulpfile.js you posted. It looks like this:

project/Gulpfile.js 
project/index.html 
project/app/pages/index.md
project/app/templates/layout.nunjucks
project/app/templates/pages/index.nunjucks

index.md

---
title: Example
layout: index.nunjucks
date: 2016-03-01
---
This is the text

layout.nunjucks

<h1>{{file.frontMatter.title}}</h1>

<div class="date">{% block date %}{% endblock %}</div>

<div>{% block text %}{% endblock %}</div>

index.nunjucks

{% extends "app/templates/layout.nunjucks" %}

{% block date %}
{{file.frontMatter.date}}
{% endblock %}

{% block text %}
{{contents}}
{% endblock %}

index.html after running gulp pages:

<h1>Example</h1>

<div class="date">
Tue Mar 01 2016 01:00:00 GMT+0100 (CET)
</div>

<div>
<p>This is the text</p>

</div>

The tricky part that you're probably getting wrong is how to specify the path for {% extends %} in index.nunjucks or some other place.

When you run gulp it changes the current working directory (CWD) to the folder where the Gulpfile.js is located (in my case: project/). By default nunjuck uses a FileSystemLoader that searches the CWD to load other templates. That means all the paths in your .nunjucks files need to be relative to the CWD, i.e. your project's base folder.

Theoretically it should be possible to provide your own FileSystemLoader so you can specify template paths relative to index.nunjucks, but gulp-wrap uses consolidate internally to abstract away the differences between the many templating engines and I haven't bothered to figure out how and if that allows you to provide a custom loader.

like image 92
Sven Schoenung Avatar answered Mar 23 '23 00:03

Sven Schoenung