• http+nunjucks模板引擎、koa+nunjucks模板引擎


    模板引擎

    • 模板引擎:模板引擎是web应用中动态生成html的工具,负责将数据和模板结合。
    • 常见模板引擎有:ejs、jade(现更名为pug)、Handlebars、Nunjucks、Swig等;
    • 使用模板引擎可以是项目结构更加清晰,结构更加合理,让项目维护变得更简单。

    nunjucks +http模块

    • app.js
    const http = require('http');
    const fs = require('fs');
    const nunjucks = require('nunjucks');
    
    const tpl = new nunjucks.Environment(
        // 模板存放路径
        new nunjucks.FileSystemLoader('template')
    );
    
    const server = http.createServer( (req, res) => {
    	let content = '';
    	if(req.url === '/){
    		    res.writeHead(200, {
                    'Content-Type': 'text/html;charset=utf-8'
                });
                let tempTitle = 'nunjucks + http';
                let data =  [{
    			        "id": 5,
    			        "title": "世界冠军发言紧张到搓手抿嘴 网友:太可爱了0",
    			        "imgUrl":"http://d.ifengimg.com/w144_h80_q70/x0.ifengimg.com/ucms/2019_43/E188C7C5E98BAFE69BE281B925E99AC4513C833F_w750_h376.jpg",
    			        "from": "环球网",
    			        "newTime": "今天 21:58"
    			    },{
            			"id": 6,
            			"title": "此时此刻,美军官怂恿日本政府向国民宣扬“中国威胁”0",   
            			"imgUrl":"http://d.ifengimg.com/w144_h80_q70/x0.ifengimg.com/ucms/2019_43/22DB248F5A6D4B1FAD1FAFC67504C0840A02E4C0_w750_h376.jpg",
            			"from": "观察者网",
            			"newTime": "今天 21:51"
        		}]
                // content = tpl.renderString(
                //     fs.writeFileSync('./template/index.html'),
                //     {
                //         tempTitle
                //     }
                // );
                content = tpl.render('index.html', {
                    tempTitle,
                    data
                }); 
    	} else {
    		res.writeHead(404, {
                    'Content-Type': 'text/html;charset=utf-8'
            });
    		content = `

    404-什么也没找到

    `
    ; } res.write(content); res.end(); }); server.listen(8081);
    • 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
    • index.html
    DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Documenttitle>
    head>
    <body>
        <h1>{{tempTitle}}h1>
        <ul>
            {%for d in data%}
            <li>{{d.title}}li>
            {%endfor%}
        ul>
    body>
    html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    nunjucks模板引擎在koa中的应用

    • 使用nunjucks
      const nunjucks = require('koa-nunjucks-2');
      app.use(nunjucks({
        ext:"html",   //指定模板后缀
        path:path.join(__dirname,'views'), //指定视图目录
        nunjucksConfig:{
          trimBlocks:true   //开启转义,防止xss漏洞
        }
      }))
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
    • 推荐使用”.njk“后缀名

    nunjucks的语法使用

    • 变量:{{username}}
    • 注释:
     {# Loop through all the users #}
    
    • 1
    • if
     {% if hungry %}
       I am hungry
     {% elif tired %}
       I am tired
     {% else %}
       I am good!
     {% endif %}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • for
       <h1>Posts</h1>
       <ul>
       {% for item in items %}
         <li>{{ item.title }}</li>
       {% else %}
         <li>This would display if the 'item' collection were empty</li>
       {% endfor %}
       </ul>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 过滤器
    {{ foo | replace("foo", "bar") | capitalize }}
    
    • 1
    • 模板继承block/extends

      • 定义父类模板
      <h1>我是公共模板</h1>
            <div class="leftContent">
                {% block left %}
                    这边是左侧的内容
                {% endblock %}
                {% block right %}
                    这边是右侧的内容
                {% endblock %}
                {% block somevalue %}
                    我是一些数据
                {% endblock %}
      </div>
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 继承父类模板
        {% extends "common.html" %}
        {% block left %}
            我是左侧的内容1111
        {% endblock %}
        {% block right %}
            我是右侧的内容11111
        {% endblock %}
        
        {% block somevalue %}
            {{ super() }}
        {% endblock %}
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
    • Macro(宏标签)可以定义可复用的内容,类似与编程语言中的函数

      • 定义
      {% macro pet(animalName,name="小白") %}
          <div>
              这里是一只{{animalName}};他的名字是{{name}}
          </div>
       {% endmacro %}    
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 调用
       {{pet("狗狗")}}
      
      • 1
    • include/import

      • include 引入文件
        {% include "footer.html" %}
      
      • 1
      • import 导入文件
        • 定义
            {% macro pet(animalName) %}
            <p>这是一只{{animalName}}</p>
            {% endmacro %}
            {% macro book(bookName) %}
            <p>这是一本书,名字叫{{bookName}}</p>
            {% endmacro %}
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 调用
          {% import 'somemodule.html' as fn %}
          {{fn.pet("狗狗")}}
          {{fn.book("nodejs从入门到实践")}}
      
      • 1
      • 2
      • 3

    demo

    • index.js
    const Koa = require("koa");
    const Router = require("koa-router");
    const nunjucks = require("koa-nunjucks-2");
    let app = new Koa();
    let router = new Router();
    app.use(nunjucks({
        ext:"html", //.njk
        path:__dirname+"/views",
        nunjucksConfig:{
            trimBlocks:true //防止Xss漏铜;
        }
    }))
    router.get("/",async ctx=>{
        // ctx.body = "hello";
        await ctx.render("index",{
            username:"张三",
            num:2,
            arr:[{
                name:"张三",
                age:20
            },{
                name:"李四",
                age:28
            }],
            str:"hello world"
        });
    })
    router.get("/son",async ctx=>{
        await ctx.render("son");
    })
    
    router.get("/import",async ctx=>{
        await ctx.render("import");
    })
    app.use(router.routes())
    app.listen(8000);
    
    • 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
    • index.html
    DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>Documenttitle>
    head>
    <body>
        <h1>我是标题h1>
        <p>用户名是:{{username}}p>
        
        {# 我是nunjucks注释 #}
        {% if num>3 %}
        <p>num值大于三p>
        {% elseif num<3 %}
        <p>num值小于三p>
        {% else %}
        <p>num值等于三p>
        {% endif %}
        <ul>
            {% for item in arr %}
            <li>姓名是:{{item.name}};年龄是:{{item.age}};li>
            {% endfor %}
        ul>
        {{str | replace("world","世界") | capitalize}}
        
        {% macro pet(name="狗",sex) %}
        <p>我是一只{{name}},我的性别是{{sex}}p>
        {% endmacro %}
        {% macro person(name="小明",sex) %}
        <p>我是{{name}},我的性别是{{sex}}p>
        {% endmacro %}
        {{pet("小狗","公")}}
        {{pet("小猫","公")}}
        {% include 'footer.html' %}
    body>
    html>
    
    • 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
    • footer.html
    <h1>我是公共底部h1>
    
    • 1
    • parent.html
    <div>
        <p>我是父级模板p>
        {% block left %}
            <p>左边内容p>
        {% endblock %}
        {% block right %}
            右边内容
        {% endblock %}
        {% block somevalue %}
            一些数据
        {% endblock %}
    div>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • son.html
    DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>Documenttitle>
    head>
    <body>
        {% extends 'parent.html' %}
        {% block left %}
            我是son里左侧内容
        {% endblock %}
        {% block right %}
            我是son里右侧侧内容
        {% endblock %}
        {% block somevalue %}
            {{super()}}
        {% endblock %}
    body>
    html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • import.html
    DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>Documenttitle>
    head>
    <body>
        {% import 'index.html' as obj %}
        {{obj.pet("公")}}
        {{obj.person("男")}}
    body>
    html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
  • 相关阅读:
    docker删除镜像和容器
    android_ADB 调试工具总结
    Linux nmcli控制NetworkManager的命令行工具
    SpringSecurity - 密码加密
    如何使用Github的Action实现博客的自动部署
    ceval 数据集明文位置编码嵌入
    微软疑断自由软件开发者“活路”,禁止在微软商店发布商业开源
    20212416 2023-2024-2 《移动平台开发与实践》综合实践
    智能车菜单编写(2)
    解决el-autocomplete组件远程搜索的区间匹配问题
  • 原文地址:https://blog.csdn.net/weixin_44178305/article/details/127943448