Search code examples
jinja2templatingnunjucks

Template Inheritance in Nunjucks, what are the requirements?


Ok super basic question but I must be missing something.

I render my page:

router.get('/', function(req, res) {
        res.render('index.njk', {});
});

Create my base layout, main-layout.njk in layout folder:

<!DOCTYPE html>

<html>
    <body>       
        {% block content %}
        {% endblock %}   
    </body>  
</html>

Extend my template, index.njk to add content to the layout:

{% extends 'layout/main-layout.njk' %} 

{% block content %}
<?php include_once("analyticstracking.php") ?>
<main>

   <p>sploooge</p>

   {% block panel %}{% endblock %}

</main>
{% endblock %} 

Now I would like index.njk to be extended by panel.njk (the file is in the same folder):

{% extends 'index.njk' %} 

{% block panel %}
    <p>second sploooge</p>
{% endblock %} 

But I cannot get it to appear. The documentation doesn't mention anything but do I need to render it somehow like index.njk?


Solution

  • I believe this issue lies in where you have the 'middle' file.

    I got this to work with the following configuration:

    File Tree:

    pages/
      -index.njk
    
    templates/
      -base.njk
      -layout.njk
    

    base.njk:

    <!DOCTYPE html>
    <html lang="en">
    <head></head>
    <body>
       {% block content %}{% endblock %}
    </body>
    </html>
    

    layout.njk

    {% extends "base.njk" %}
    {% block content %}
        Content
    {% block more %}{% endblock %}
    {% endblock %}
    

    index.njk:

    {% extends "layout.njk" %}
    {% block more %}
        More Content
    {% endblock %}
    

    Output:

    <!DOCTYPE html>
    <html lang="en">
    <head></head>
    <body>
       Content
       More Content
    </body>
    </html>
    

    You can use a template that is anywhere, you just need to make sure you add that to the url in the extend. Example:

    {% extends "templates/layouts/extras/template.njk" %}
    

    This would get horribly confusing and increase the potential for error, but theoretically it would work.

    Look into using includes in some areas as well, it may be beneficial in this case to not have an extra layer of templates.