Egg.js模板引擎集成:Nunjucks渲染实战

Egg.js模板引擎集成:Nunjucks渲染实战

【免费下载链接】egg 🥚 Born to build better enterprise frameworks and apps with Node.js & Koa 【免费下载链接】egg 项目地址: https://gitcode.com/gh_mirrors/egg11/egg

你是否在寻找一种简单高效的方式来构建动态网页?Egg.js作为基于Node.js和Koa的企业级框架,提供了强大的模板渲染能力。本文将带你一步步实现Nunjucks模板引擎在Egg.js项目中的集成与应用,从基础配置到高级功能,让你轻松掌握页面渲染技巧。

为什么选择Nunjucks?

Nunjucks是由Mozilla开发的功能丰富的模板引擎,支持变量替换、条件判断、循环、继承等特性,语法简洁易懂。Egg.js通过egg-view-nunjucks插件提供了对Nunjucks的完美支持,保持了一致的API接口,同时兼顾了性能和安全性。

Egg.js框架架构

快速开始:环境准备与插件安装

安装Nunjucks插件

首先,通过npm安装egg-view-nunjucks插件:

npm i egg-view-nunjucks --save

启用插件

在Egg.js项目中,插件配置位于config/plugin.js文件中。添加以下配置启用Nunjucks:

// config/plugin.js
exports.nunjucks = {
  enable: true,
  package: 'egg-view-nunjucks',
};

核心配置:定制你的模板引擎

Egg.js提供了灵活的配置选项,让你可以根据项目需求定制Nunjucks的行为。主要配置文件为config/config.default.js

基础配置

// config/config.default.js
const path = require('path');
module.exports = appInfo => {
  return {
    view: {
      root: path.join(appInfo.baseDir, 'app/view'), // 模板文件根目录
      mapping: { '.nj': 'nunjucks' }, // 文件后缀与模板引擎映射
      defaultViewEngine: 'nunjucks', // 默认模板引擎
      defaultExtension: '.nj', // 默认文件后缀
    },
    nunjucks: {
      cache: true, // 生产环境启用缓存
      autoescape: true, // 自动转义HTML特殊字符
    }
  }
};

多目录支持

如果需要从多个目录加载模板,可以将root配置为目录数组:

// config/config.default.js
view: {
  root: [
    path.join(appInfo.baseDir, 'app/view'),
    path.join(appInfo.baseDir, 'app/admin/view'),
  ].join(',') // 多个目录用逗号分隔
}

模板渲染:三种渲染方式详解

Egg.js在Context对象上提供了三个模板渲染接口,满足不同场景需求:

1. 渲染文件并输出到响应

使用ctx.render()方法渲染模板文件,并自动将结果赋值给ctx.body

// app/controller/home.js
module.exports = class HomeController extends Controller {
  async index() {
    const { ctx } = this;
    // 渲染app/view/home.nj模板,传入数据
    await ctx.render('home', { 
      title: 'Egg.js + Nunjucks',
      user: { name: '访客' },
      list: [ 'item1', 'item2', 'item3' ]
    });
  }
};

2. 渲染文件返回字符串

使用ctx.renderView()方法渲染模板文件,但不自动赋值给ctx.body,而是返回渲染后的字符串:

// app/controller/home.js
async detail() {
  const { ctx } = this;
  const html = await ctx.renderView('post/detail', { 
    post: { title: '模板引擎使用指南', content: '...' }
  });
  // 可以对html进行进一步处理
  ctx.body = html.replace(/ Egg /g, ' <strong>Egg</strong> ');
}

3. 渲染模板字符串

使用ctx.renderString()方法直接渲染模板字符串:

// app/controller/home.js
async message() {
  const { ctx } = this;
  const tpl = 'Hello {{ name }}! Today is {{ date | date("YYYY-MM-DD") }}';
  ctx.body = await ctx.renderString(tpl, {
    name: 'Egg',
    date: new Date()
  }, { viewEngine: 'nunjucks' }); // 指定模板引擎
}

模板语法:Nunjucks核心功能示例

变量与过滤器

Nunjucks支持丰富的变量输出和过滤器操作:

<!-- app/view/home.nj -->
<div class="user-info">
  <h1>{{ title | upper }}</h1>
  <p>欢迎您,{{ user.name | default('Guest') }}</p>
  <p>当前时间:{{ now | date("YYYY-MM-DD HH:mm") }}</p>
</div>

条件判断与循环

<!-- app/view/product/list.nj -->
<ul class="product-list">
  {% for product in products %}
    <li class="{% if loop.index % 2 == 0 %}even{% else %}odd{% endif %}">
      <h3>{{ product.name }}</h3>
      <p class="price">${{ product.price | round(2) }}</p>
      {% if product.stock > 0 %}
        <span class="in-stock">有货</span>
      {% else %}
        <span class="out-of-stock">缺货</span>
      {% endif %}
    </li>
  {% else %}
    <li class="no-products">暂无商品</li>
  {% endfor %}
</ul>

模板继承与复用

Nunjucks的模板继承功能可以大幅提高代码复用率:

基础模板 (base.nj):

<!-- app/view/base.nj -->
<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <title>{% block title %}My Site{% endblock %}</title>
  <link rel="stylesheet" href="/public/css/style.css">
  {% block styles %}{% endblock %}
</head>
<body>
  <header>
    <h1>My Site</h1>
    <nav>{% block nav %}{% endblock %}</nav>
  </header>
  <main>{% block content %}{% endblock %}</main>
  <footer>© 2025 My Site</footer>
  {% block scripts %}{% endblock %}
</body>
</html>

子模板 (home.nj):

<!-- app/view/home.nj -->
{% extends 'base.nj' %}

{% block title %}首页 - My Site{% endblock %}

{% block nav %}
  <ul>
    <li><a href="/" class="active">首页</a></li>
    <li><a href="/products">产品</a></li>
  </ul>
{% endblock %}

{% block content %}
  <h2>欢迎来到首页</h2>
  <p>最新公告:{{ notice }}</p>
{% endblock %}

高级特性:Helper与安全渲染

自定义Helper函数

Egg.js允许通过扩展Helper来添加自定义工具函数,在模板中直接使用:

定义Helper:

// app/extend/helper.js
exports.formatPrice = function(price) {
  return '¥' + (price / 100).toFixed(2);
};

exports.lowercaseFirst = str => str[0].toLowerCase() + str.substring(1);

在模板中使用:

<!-- app/view/product/item.nj -->
<div class="product">
  <h3>{{ helper.lowercaseFirst(product.name) }}</h3>
  <p class="price">{{ helper.formatPrice(product.price) }}</p>
</div>

安全渲染与XSS防护

Egg.js内置的egg-security插件提供了安全辅助函数,防止XSS攻击:

<!-- 安全输出HTML内容 -->
<div class="content">{{ helper.shtml(article.content) }}</div>

<!-- 安全生成URL -->
<a href="{{ helper.surl(article.url) }}">阅读全文</a>

调试与最佳实践

开发环境配置

在开发环境中,建议关闭模板缓存,以便实时查看修改效果:

// config/config.local.js
module.exports = {
  nunjucks: {
    cache: false, // 开发环境关闭缓存
    watch: true, // 监听文件变化自动重载
  }
};

性能优化

  1. 生产环境启用缓存:通过cache: true配置开启模板缓存
  2. 合理组织模板结构:使用继承和包含减少重复代码
  3. 避免在模板中编写复杂逻辑:复杂逻辑应在Controller或Service中处理

Egg.js快速启动示例

常见问题与解决方案

Q: 如何在Nunjucks中使用Egg.js的路由函数?

A: 可以通过Helper扩展实现URL生成:

// app/extend/helper.js
exports.pathFor = function(name, params) {
  return this.ctx.router.url(name, params);
};

在模板中使用:

<a href="{{ helper.pathFor('product', { id: product.id }) }}">查看详情</a>

Q: 如何在Nunjucks中处理国际化?

A: 结合Egg.js的i18n插件,在模板中使用__函数:

<p>{{ __('welcome.message', user.name) }}</p>

总结与进阶学习

通过本文的介绍,你已经掌握了Nunjucks模板引擎在Egg.js中的基本使用方法。要深入了解更多高级特性,可以参考以下资源:

掌握模板引擎的使用,将大大提高你构建动态网页的效率。无论是开发博客系统、电商平台还是企业网站,Nunjucks与Egg.js的组合都能为你提供强大的支持。

现在,开始动手实践吧!创建你的第一个模板文件,体验Egg.js带来的高效开发体验。

【免费下载链接】egg 🥚 Born to build better enterprise frameworks and apps with Node.js & Koa 【免费下载链接】egg 项目地址: https://gitcode.com/gh_mirrors/egg11/egg

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值