Technology Sharing

nunjucks dynamically updates template path

2024-07-12

한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina

Dynamically reading files for each request does have a certain performance impact, especially in high concurrency situations. To solve this problem, you can read the template configuration when the application starts and update the configuration when the template changes, so that you only need to read the file when the application starts and the template changes, instead of reading the file for each request.

You can use a global variable to cache the current template path and only update the variable and the file when you change the template.

Here is the improved sample code:

Directory structure example

project
│
├── views/
│   ├── template1/
│   │   └── index.njk
│   ├── template2/
│   │   └── index.njk
│
├── config/
│   └── templateConfig.json
│
├── app.js
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

templateConfig.json Sample content

{
    "currentTemplate": "template1"
}
  • 1
  • 2
  • 3

app.js Sample Code

const express = require('express');
const nunjucks = require('nunjucks');
const path = require('path');
const fs = require('fs');

const app = express();

// 设置静态文件目录
app.use(express.static(path.join(__dirname, 'public')));

// 全局变量,缓存当前模板路径
let currentTemplatePath;

// 读取配置文件中的当前模板路径
function loadTemplateConfig() {
    const config = JSON.parse(fs.readFileSync(path.join(__dirname, 'config/templateConfig.json'), 'utf8'));
    currentTemplatePath = config.currentTemplate;
}

// 配置Nunjucks环境
function configureNunjucks() {
    nunjucks.configure(path.join(__dirname, `views/${currentTemplatePath}`), {
        autoescape: false,
        noCache: true,
        express: app
    });
}

// 初始化时加载配置
loadTemplateConfig();
configureNunjucks();

// 路由
app.get('/', (req, res) => {
    res.render('index.njk', { title: 'Hello Nunjucks!' });
});

// 路由:更改模板路径
app.get('/change-template', (req, res) => {
    const newTemplate = req.query.template;
    if (newTemplate) {
        currentTemplatePath = newTemplate;
        const config = { currentTemplate: newTemplate };
        fs.writeFileSync(path.join(__dirname, 'config/templateConfig.json'), JSON.stringify(config), 'utf8');
        configureNunjucks(); // 更新Nunjucks配置
        res.send(`Template changed to ${newTemplate}`);
    } else {
        res.send('No template specified');
    }
});

// 启动服务器
const port = 3000;
app.listen(port, () => {
    console.log(`服务器已启动,访问地址:http://localhost:${port}`);
});
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56

explain

  1. Global variables currentTemplatePath: Cache the current template path.
  2. loadTemplateConfig function: Read the template configuration file when the application starts and save the path to the global variable.
  3. configureNunjucks function: Configure the Nunjucks environment based on the cached template path.
  4. Loading configuration at initialization: Called when the application starts loadTemplateConfig andconfigureNunjucks function.
  5. Changing the template path routing: When the user changes the template path, update the global variables, files and reconfigure Nunjucks.

In this way, the file is read and Nunjucks is configured only when the application starts and the user changes the template path, avoiding the performance problem of reading the file for each request.