2

I'm trying to understand the language of Nunjucks templates.

To generate HTML I use Gulp + plugin gulp-nunjucks-render.

Faced a problem: I can not understand how to implement the generation of meta tags title and description.

Project file structure:

project
 |
 | -> dist > index.html (compiled)
 |           page1.html (compiled)
 |           page2.html (compiled)
 |
 |
 | -> src 
        |-> pages -> index.njk (home page)        
        |            page1.njk (page 1)      
        |            page2.njk (page 2)            
        |
        |-> templates
        |            |-> layout.njk
        |            |
        |            |-> parts -> header.njk
        |                         footer.njk
        |
        |-> styles -> style.css
        |             style.min.css
        |
        |-> data.json

layout.njk

<!-- layout.njk -->

<html lang="en">
  <head>
      <title>{{ title }}</title>
      <link rel="stylesheet" href="styles/style.css">
  </head>
  <body class="page">
      {% block header %}{% endblock %}
      {% block main %}{% endblock %}
      {% block footer %}{% endblock %}
  </body>
</html>

Which I connect to each page as follows:

{% extends "layout.njk" %}

index.njk

{% extends "layout.njk" %}

{% block header %} {% include "parts/header.njk" %} {% endblock %}
{% block main %}
    <main class="main">
    <!-- content -->
    </main>
{% endblock %}
{% block footer %} {% include "parts/footer.njk" %} {% endblock %}

page1.njk

{% extends "layout.njk" %}

{% block header %} {% include "parts/header.njk" %} {% endblock %}
{% block main %}
    <main class="main">
    <!-- content page1 -->
    </main>
{% endblock %}
{% block footer %} {% include "parts/footer.njk" %} {% endblock %}

page2.njk

{% extends "layout.njk" %}

{% block header %} {% include "parts/header.njk" %} {% endblock %}
{% block main %}
    <main class="main">
    <!-- content page1 -->
    </main>
{% endblock %}
{% block footer %} {% include "parts/footer.njk" %} {% endblock %}

I couldn't find any examples of title output in the documentation, so the most an interesting way to I saw here.

For example, get the title and description from a file .JSON

data.json

"pages": [
    {
        title: "Hompage"
        description: "This is the home page"
    },
    {
        title: "Page1"
        description: "This is page 1"
    }
    {
        title: "Page2"
        description: "This is page 2"
    }
]

gulpfile.js

const gulp           = require('gulp');
const nunjucksRender = require('gulp-nunjucks-render');
const data           = require('gulp-data');

gulp.task('nunjucks', function() {
  return gulp.src('src/pages/**/*.njk')
  .pipe(data(function() {
    return require('./src/data.json')
  }))
  .pipe(nunjucksRender({
    path: ['src/templates']
    }))
    .pipe(gulp.dest('docs'))
    .pipe(browserSync.reload({stream: true}));
});

gulp.task('watch', function(cb) {
    gulp.parallel(
        'nunjucks',
    )(cb);
    gulp.watch('src/**/*.njk', gulp.series('nunjucks'));
});

gulp.task('default', gulp.series('watch'));

I don't know how to extract data from json. Please advise a solution.

Yuri Fedorov
  • 33
  • 1
  • 6

3 Answers3

1

Since you extends layout.njk in your pages, you could set the title and the description variables at the top of the document like so:

{% set title = myTitle %}
{% set description = myDescriptionHere %}

Then you do that for every pages (index.njk, page1.njk, page2.njk, etc.)

Alternatively, you could define your variables in nunjucksRender in the gulpfile.js as so:

.pipe(nunjucksRender({
    path: ["yourPath"],
    title: "yourTitle",
    description: "yourDescriptionHere"
}))
// Rest of the code...

I didn't test it, I just deduce that from de documentation and great articles: Killer features of Nunjucks and Building a static website with components using Nunjucks.

Phil Dukhov
  • 67,741
  • 15
  • 184
  • 220
Mathieu
  • 11
  • 1
1

If you are hoping to pass the data from data.json file

Step 1: you need to use someway to specify the page name in the data file itself.

Eg: data.json

{
    "pages": {
        "home": {
            "title": "Hompage",
            "description": "This is the home page"
        },
        "page1": {
            "title": "Page1",
            "description": "This is page 1"
        },
        "page2": {
            "title": "Page2",
            "description": "This is page 2"
        }
    }
}

Step 2: You have to set the page name as a variable in the nunjucks page.

Eg: index.njk

{% set pageName = 'home' %}
{% extends "layout.njk" %}

{% block header %} {% include "parts/header.njk" %} {% endblock %}
{% block main %}
    <main class="main">
    <!-- content -->
    </main>
{% endblock %}
{% block footer %} {% include "parts/footer.njk" %} {% endblock %}

Step 3: Use the pageName variable in any nunjucks page, layout or partial to get the specific data for a specific page.

Eg: layout.njk

<html lang="en">
  <head>
    <title>{{ pages[pageName].title }}</title>
    <link rel="stylesheet" href="styles/style.css">
  </head>
  <body class="page">
    {% block header %}{% endblock %}
    {% block main %}{% endblock %}
    {% block footer %}{% endblock %}
  </body>
</html>

I didn't compile and test this code. So make sure all variables and code syntax are correct if you are directly copying this code. The logic must work based on the documentation

Lasithds
  • 2,161
  • 25
  • 39
0

When you use extends, you should redefine block to override it

var nunjucks  = require('nunjucks');
var env = nunjucks.configure();

var html = `
{% extends "layout.njk" %}

{% block header %}
    {{pages[1].title}}
{% endblock %}

{% block main %}
    {{pages[1].description}}
{% endblock %}
`

var data = {
    pages: [
    {
        title: "Hompage",
        description: "This is the home page"
    },
    {
        title: "Page1",
        description: "This is page 1"
    },
    {
        title: "Page2",
        description: "This is page 2"
    }]
}

res = nunjucks.renderString(html, data);
console.log(res);
Aikon Mogwai
  • 4,954
  • 2
  • 18
  • 31
  • Thank you for your advice, but I don't fully understand. Inserted the code you suggested into gulpfile.js and got a syntax error. I slightly corrected my question, pointed to the file structure and some more details. I would be very grateful if you explain in more detail how to organize everything for work. – Yuri Fedorov Jan 08 '19 at 10:38
  • I don't understand what do you want exactly: why `page1.njk` = `page2.njk`? Where is `nunjucks` use your data? Also I don't know `gulp` and so I don't know how it iterate over pages. – Aikon Mogwai Jan 08 '19 at 11:01
  • 'page1' and 'page2' have a common header and footer, only the main content is different. Nunjucks takes data from external data.json (return require('./src/data.json')). If you find it difficult to answer, it does not matter. You have already given a hint, I'll try to figure it out somehow. – Yuri Fedorov Jan 08 '19 at 11:16