Why isn't the Nunjucks extends directive functioning when the template is stored in a different directory and being used

I have successfully integrated nunjucks templating into my express app. Below is the directory structure of my project:

. nunjucks-project
  |__ api
  |__ node_modules
  |__ views
     |__ templates
        |__ layouts
           |__ default.html  
        |__ pages
           |__ home.html
        |__ partials
           |__ header.html
           |__ footer.html

Take a look at my app.js :

/**
 *  Author Kailash K Yogeshwar 2016
 */

var express  = require('express');
var nunjucks = require('nunjucks');
var mongoose = require('mongoose');
var path     = require('path');
var config   = require('config');

var app               =  express();
var viewRoutes  =  require("./routes/viewroutes/index");
var apiRoutes   =  require("./routes/apiroutes/index");


var dbUrl = "mongodb://localhost:27017/techblogs";

mongoose.connect(dbUrl);

mongoose.connection.on('open',() => {
    console.log("Connection successfully established")
});

mongoose.connection.on("error",(err) => {
    console.error(err);
});

//configure views
app.set('views', path.join(__dirname, "views", "templates"));
app.set('view engine', 'html');


// configure nunjucks
var env = nunjucks.configure(app.get('views'), {
    autoescape: true,
    dev: true,
    noCache: true,
    throwOnUndefined: true,
    express : app
});

console.log(JSON.stringify(env, null, 3))

app.use('/', viewRoutes);
app.use('/api', apiRoutes);

app.listen(process.env.PORT || 8080, () => {
    console.log("Server Started to listen on ",process.env.PORT || 8080);
});


module.exports = app;

Now, let's dive into default.html and home.html :

!<!DOCTYPE html>
<html>
<head>
    <title>{{title}}</title>
</head>
<body>
    {% include 'partials/header.html' %}
    {% block content %} {% endblock %}
    {% include 'partials/footer.html' %}
</body>
</html>

home.html

{% extends "layouts/default.html" %}
{% block content %}
<h1> I am home page <h1>
{% endblock %}

I have noticed that the "extends" function only works if the template is in the same directory, and not in a separate directory. I also attempted to specify multiple paths in nunjucks.configure([paths],{}) but it only takes the first path into account, considering the rest as relative paths.

Here is a screenshot for reference:

https://i.sstatic.net/jUzII.png

Answer №1

Just a quick tip for anyone experiencing a similar issue: I found that moving my viewRoute middleware below and exporting the instance of the express app to use in the middleware for rendering solved the problem.

var env = nunjucks.configure(app.get('views'), options);

var viewRoutes = require("./routes/viewroutes/index");
var apiRoutes = require("./routes/apiroutes/index");

app.use('/', viewRoutes);
app.use('/api', apiRoutes);

app.listen(process.env.PORT || 8080, () => {
    console.log("Server Started to listen on ", process.env.PORT || 8080);
});

In my viewRoutes/index.js file:

var express = require('express');
var nunjucks = require('nunjucks');
var app = require("../../index");

var router = express.Router();

app.get("/", function(req, res, next){
    res.render('pages/home.html',{
        title: "Home"
    });
})

module.exports = router;

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Error: Unable to execute function on blog mapping

I am facing an issue with my app where it fails to detect objects. Every time the component in my app calls ".map", I encounter an error message. I have double-checked that index.js is passing props correctly. Can anyone explain why this problem is occurri ...

Testing NodeJS Database Functionality using Mocha and Asserting with should.js

Currently, I am in the process of testing my NodeJS application using mocha and should. The issue I am facing is that while the first test executes smoothly, the second one fails with an error of null. Interestingly, both tests result in a valid user being ...

Using jQuery to eliminate accepting input from form field

Looking to switch between a URL input and file input based on user selection of a radio button. Encountering an issue when attempting to remove the accept attribute from the input, resulting in an Uncaught TypeError: $(...).get(...).removeAttr is not a fu ...

Server Sent Events not being received by client from Express.js server

My Next.js (React) client is set up to receive Server-Sent Events from my Node.js/Express.js server, but it seems like it's not receiving any messages for some unknown reason. While the open and error events of EventSource are functioning correctly, ...

Error: When refreshing the webpage, a TypeError occurs because the property '1' is attempting to be read from an undefined object

Retrieving the user collection from firebase: const [userInfo, setUserInfo] = useState([]) useEffect(() => { if (currentUser) { const unsubscribe = db .collection("users") .doc(uid) .onSna ...

Tips on how to display a Vue component on a new page with Vue.js router

My current challenge is getting my App to render on a new page instead of the same page. Despite trying render: h => h(App), it still renders on the same page. This is the Vue file (Risks.vue) where the router will be linked: <router-link to="/risk ...

Replacing strings using Regex capture groups in JavaScript

Within my NodeJS application, there is a phone number field containing multiple phone numbers stored in one string. For example: \n\n \n (555) 555-5555 (Main)\n\n, \n\n \n (777) 777-777 (Domestic Fax)\n&bso ...

Tips for dynamically changing the number of visible ListItems in React using a single method

I recently stumbled upon the perfect solution at this link using material-ui. The chapter on "Nested list items" caught my attention, as it only has one nested item with a method for expanding more or less. In my sidebar, I have two nested items that both ...

Saving Labels in Firebase after receiving a POST request for a separate group in Node.js

My system comprises two key collections: posts and tags. The posts collection contains a postId and other relevant metadata, including tags. A typical structure of a post is as follows: { "tags": [ "tag1", "tag2", ... ], ...

Positioning pop-up windows using Javascript and CSS techniques

In my web application, there is a search field that allows users to enter tags for searching. The window should pop up directly below the search field as shown in this image: Image I am trying to figure out how the window positioning is actually d ...

Display the initial three image components on the HTML webpage, then simply click on the "load more" button to reveal the subsequent two elements

I've created a div with the id #myList, which contains 8 sub-divs each with an image. My goal is to initially load the first 3 images and then have the ability to load more when clicking on load more. I attempted to follow this jsfiddle example Bel ...

Error Encountered with Nested Angular Material Tabs

Is there a way to prevent changes made to the upper tab in md-align-tabs attribute from affecting the inner tab when one tab is nested inside another using md-tabs? If so, how can I achieve this? <md-content layout="column" layout-fill> <md-ta ...

Utilize the Webpack library and libraryTarget settings to establish our own custom library as a global variable

I currently have a library named "xyz" that is being imported as a node module from the npm registry. Now, I want to incorporate it as a library and make it accessible under the global name "abc". To achieve this, I plan to utilize webpack configuration. ...

Next.js application shows 404 errors when trying to access assets within the public directory

I've been struggling to display the favicon for my site (which uses next.js). Despite going through numerous Stack Overflow posts and tutorials, I'm feeling increasingly frustrated. The structure of my project, particularly the public directory, ...

Utilize React Native to continuously fetch and display data from this API

[React-Native] Seeking assistance on looping through JSON API for conditional rendering. As a beginner, I would greatly appreciate your guidance. Thank you. Find my code here: https://drive.google.com/file/d/0B3x6OW2-ZXs6SGgxWmtFTFRHV00/view Check out th ...

Having trouble with passing props to data() in Vue.js?

I'm facing an issue where I am unable to pass props to data() in my Vue inline template: <network-index inline-template> ... <network-list :data="networks"></network-list> ... </network-index> Inside the Index.vue file, here ...

Encountering a NPM error when trying to launch the server using ng serve

I encountered an error : ERROR in /opt/NodeJS/FutureDMS/src/app/app.module.ts (5,9): Module '"/opt/NodeJS/FutureDMS/src/app/app.routing"' has no exported member 'APP_ROUTE'. Within my code, I have utilized arrow function in the loadCh ...

Tips on altering a predetermined input text value using JavaScript

I have a question about using JavaScript. I am currently developing a tax calculation system. function calculateTax(){ var invoiceValue = document.getElementById("invoicevalue"); var ppn = document.getElementById("ppn"); var pph = document.get ...

Angular 5 offers the ability to incorporate dynamic checkbox input into your application

Here is my code snippet: <input [type]="'checkbox'" [(ngModel)]="inputValue"> <p>Value: {{ inputValue }}</p> I'm puzzled as to why the value in inputValue remains unchanged. Can anyone shed light on this? I am unable to ...

Creating a Scrollable React Form Group

Struggling to display a large amount of data that is not scrollable, how can I make this form group scrollable to easily view all the data? render() { return ( <div style={{width: '50rem', margin: '1rem&ap ...