一、juicer模板的使用

什么是juicer(what)?

Juicer 是一个高效、轻量的前端 (Javascript) 模板引擎,使用 Juicer 可以是你的代码实现数据和视图模型的分离(MVC)。 除此之外,它还可以在 Node.js 环境中运行。Juicer渲染速度很快(百万次渲染耗时仅174ms,具体请移步性能测试,但这个性能可能没想的那么重要)、Juicer库文件很小(压缩文件仅7.7KB),能帮助你实现MVC结构,同时支持Node环境。

通过这个例子直观的展现出前端模板引擎的好处所在,这么做能够完全剥离html和代码逻辑,便于多人协作和后期的代码维护。

一个完善的模板引擎应该兼顾这几点:

语法简明

执行效率高

安全性

错误处理机制

多语言通用性

a.语法

循环: {@each}…{@/each}

判断:{@if}…{@else if}…{@else}…{@/if}

变量(支持函数):${varname|function}

注释:{# comment here}

b.安全性

juicer对数据输出做了安全转义,如果不想被转义,可以使用$${varname}。

c.错误处理

如果没有错误处理机制,在模版编译和渲染出现错误的时候,js会停止加载

juicer的错误处理机制会在出现错误时跳过当前步骤并在控制台上提示Juicer Compile Exception: Unexpected token,不会因为错误导致后续js无法执行。

二、一个关于juicer模板渲染导致页面截断的问题

发现一个关于juicer模板渲染导致页面截断的问题。经过测试,发现是给juicer模板传入了带有如下特殊字符的变量内容所致:

主要出问题的有单引号、双引号、&字符。

一个比较典型的测试case:

SELECT * FROM users WHERE name='***';

由于特殊字符导致juicer模板渲染出错后,会使得该渲染位置之后的页面内容均不再渲染,从而出现页面截断的状况。而且此时并不会报错!这是一个比较坑的地方。

解决办法是在使用juicer模板的时候使用$$,即比一般的渲染多加一个$。

juicer中,$${}内部的变量不会被转义

juicer中的内联辅助函数的使用:

{@helper numberPlus}

function(number) {

return number + 1;

}

{@/helper}

var tpl = 'Number: ${num|numberPlus}';

juicer中的注释:

{# comment here}

三、juicer中的对于模版语法的正则匹配的源码解析

juicer.tags = {

// 操作开

operationOpen: '{@',

// 操作闭

operationClose: '}',

// 变量开

interpolateOpen: '\\${',

// 变量闭标签

interpolateClose: '}',

// 禁止对其内容转义的变量开

noneencodeOpen: '\\$\\${',

// 禁止对其内容转义的变量闭

noneencodeClose: '}',

// 注释开

commentOpen: '\\{#',

// 注释闭

commentClose: '\\}'

};

juicer.tagInit = function() {

/**

* 匹配each循环开始,以下都是OK的

* `each VAR as VALUE`, 如 {@each names as name}

* `each VAR as VALUE ,INDEX`,如 {@each names as name,key}

* `each VAR as`,如 {@each names as}

* 需要说明后两种情况:

* `,key` 是一起被捕获的,所以在编译模板的时候,系统会用`substr`去掉`,`

* as 后没有指定别名的话,默认以`value`为别名,所以

* {@each names as} 等价于 {@each names as value}

*/

var forstart = juicer.tags.operationOpen + 'each\\s*([^}]*?)\\s*as\\s*(\\w*?)\\s*(,\\s*\\w*?)?' + juicer.tags.operationClose;

// each循环结束

var forend = juicer.tags.operationOpen + '\\/each' + juicer.tags.operationClose;

// if条件开始

var ifstart = juicer.tags.operationOpen + 'if\\s*([^}]*?)' + juicer.tags.operationClose;

// if条件结束

var ifend = juicer.tags.operationOpen + '\\/if' + juicer.tags.operationClose;

// else条件开始

var elsestart = juicer.tags.operationOpen + 'else' + juicer.tags.operationClose;

// eles if 条件开始

var elseifstart = juicer.tags.operationOpen + 'else if\\s*([^}]*?)' + juicer.tags.operationClose;

// 匹配变量

var interpolate = juicer.tags.interpolateOpen + '([\\s\\S]+?)' + juicer.tags.interpolateClose;

// 匹配不对其内容转义的变量

var noneencode = juicer.tags.noneencodeOpen + '([\\s\\S]+?)' + juicer.tags.noneencodeClose;

// 匹配模板内容注释

var inlinecomment = juicer.tags.commentOpen + '[^}]*?' + juicer.tags.commentClose;

// for辅助循环

var rangestart = juicer.tags.operationOpen + 'each\\s*(\\w*?)\\s*in\\s*range\\(([^}]+?)\\s*,\\s*([^}]+?)\\)' + juicer.tags.operationClose;

// 引入子模板

var include = juicer.tags.operationOpen + 'include\\s*([^}]*?)\\s*,\\s*([^}]*?)' + juicer.tags.operationClose;

// 内联辅助函数开始

var helperRegisterStart = juicer.tags.operationOpen + 'helper\\s*([^}]*?)\\s*' + juicer.tags.operationClose;

// 辅助函数代码块内语句

var helperRegisterBody = '([\\s\\S]*?)';

// 辅助函数结束

var helperRegisterEnd = juicer.tags.operationOpen + '\\/helper' + juicer.tags.operationClose;

juicer.settings.forstart = new RegExp(forstart, 'igm');

juicer.settings.forend = new RegExp(forend, 'igm');

juicer.settings.ifstart = new RegExp(ifstart, 'igm');

juicer.settings.ifend = new RegExp(ifend, 'igm');

juicer.settings.elsestart = new RegExp(elsestart, 'igm');

juicer.settings.elseifstart = new RegExp(elseifstart, 'igm');

juicer.settings.interpolate = new RegExp(interpolate, 'igm');

juicer.settings.noneencode = new RegExp(noneencode, 'igm');

juicer.settings.inlinecomment = new RegExp(inlinecomment, 'igm');

juicer.settings.rangestart = new RegExp(rangestart, 'igm');

juicer.settings.include = new RegExp(include, 'igm');

juicer.settings.helperRegister = new RegExp(helperRegisterStart + helperRegisterBody + helperRegisterEnd, 'igm');

};

为了简便起见,我们只解析其中的一个正则,其它的可以举一反三。

each\\s*([^}]*?)\\s*as\\s*(\\w*?)\\s*(,\\s*\\w*?)?

\\s*表示空格可有可无

([^}]*?)表示以非贪婪匹配的方式,匹配0-n个非}的字符

(\\w*?)表示以非贪婪匹配的方式,匹配0-n个数字、字母或下划线的字符

https://github.com/PaulGuo/Juicer/blob/master/src/juicer.jshttps://github.com/PaulGuo/Juicer

你的支持,是对博主最大的鼓励。猛戳这里,右上角给点个Star吧!>>>

juicer模板返回html,juicer模板的使用相关推荐

  1. js模板引擎juicer嵌入html元素,Javascript 模板引擎(Juicer.js)--实现数据和视图模型的分离...

    在开发流程表单或自定义页面时,经常会遇到类似主从表数据的展示,简单的做法就是循环的去拼接html,简单结构时这样做没问题.复杂的结构就不是很合适. Juicer.js可以方便的把数据和模板分离. 具体 ...

  2. js模板引擎juicer嵌入html元素,juicer前端模板引擎(示例代码)

    Juicer 中文文档:http://www.juicer.name/docs/docs_zh_cn.html 官网:http://juicer.name/ 一个Javascript模板引擎的实现和优 ...

  3. Cherno C++系列笔记17——P52~P54 处理多返回值、模板、堆和栈内存的比较

    文章目录 1.P52 处理多返回值 2.P53 模板 2.1.模板函数 2.2.模板类 2.2.1.将数组大小作为模板参数 2.2.2.将数组大小和数组类型都作为模板参数 2.3.何时使用模板 3.P ...

  4. C++中函数模板的返回值是模板类型参数的调用方法

    1 函数模板 模板定义以关键字template开始,后接模板形参表,模板形参表是用尖括号扩住的一个或多个模板形参的列表,形参之间以逗号分隔.关于函数模板的详细介绍,请参考<C++中模板函数及模板 ...

  5. Django模板、配置文件、静态文件及案例实现(创建模板、设置模板查找路径、模板接收视图传入的数据、模板处理数据、BASE_DIR、DEBUG、本地语言与时区、App应用配置)

    1.Django模板 网站如何向客户端返回一个漂亮的页面呢? 漂亮的页面需要html.css.js. 可以把这一堆字段串全都写到视图中, 作为HttpResponse()的参数,响应给客户端. 存在的 ...

  6. 泛函编程—模板函数_类模板

    函数业务逻辑一样,只是函数参数类型不同 函数模板的本质:类型参数化--泛型编程 语法: template <typename T> template <class T1,class ...

  7. 由浅入深:自己动手开发模板引擎——解释型模板引擎

    受到群里兄弟们的竭力邀请,老陈终于决定来分享一下.NET下的模板引擎开发技术.本系列文章将会带您由浅入深的全面认识模板引擎的概念.设计.分析和实战应用,一步一步的带您开发出完全属于自己的模板引擎.关于 ...

  8. 由浅入深:自己动手开发模板引擎——置换型模板引擎(四)

    受到群里兄弟们的竭力邀请,老陈终于决定来分享一下.NET下的模板引擎开发技术.本系列文章将会带您由浅入深的全面认识模板引擎的概念.设计.分析和实战应用,一步一步的带您开发出完全属于自己的模板引擎.关于 ...

  9. 由浅入深:自己动手开发模板引擎——置换型模板引擎(三)

    受到群里兄弟们的竭力邀请,老陈终于决定来分享一下.NET下的模板引擎开发技术.本系列文章将会带您由浅入深的全面认识模板引擎的概念.设计.分析和实战应用,一步一步的带您开发出完全属于自己的模板引擎.关于 ...

最新文章

  1. 英语影视台词---四、Sideways
  2. Cocos2d-x之绘制线条
  3. Python编程基础:第四十二节 多重继承Multi Level Inheritance
  4. 快速排序(Quick_Sort)
  5. python中列表实现自加减元素_python初学者知识整合
  6. 加油python_力扣——gas station (加油站) python实现
  7. java中文件处理之图片_在Java 7中处理文件
  8. MYSQL 5.7.26 二进制版本安装
  9. 数据隐私与加密学技术 |链捕手
  10. 打开量化交易的黑箱——note1
  11. 斐讯K2 烧写第三方固件的简单方法
  12. 人脸识别——基于CNN的模型实现
  13. 计算机考试后的感想,计算机考试的感想
  14. 请查收 | 2022 阿里妈妈技术文章回顾
  15. Java基础(一)Java语言概述及入门
  16. 使用HTML+CSS实现轮播图
  17. grbl源码解析——速度前瞻(1)
  18. postgresql数据库字节流类型详解
  19. 就靠这一篇文章,我就弄懂了 Python Django 的 django-admin 命令行工具集
  20. 滴滴出行数据应用平台建设实践

热门文章

  1. 解决网页禁止复制,禁止右键。
  2. uCOSII任务就绪过程分析
  3. latex_1_安装及语法基础入门
  4. VirtualBox创建虚拟系统,出现“硬件加速”问题:需要禁用硬件虚拟化才能启动虚拟机。
  5. 第十二天---用户组管理与提权
  6. Java通过出生日期计算属相(生肖)和星座
  7. Photoshop.js对图层的基本操作
  8. 伯特兰-切比雪夫定理(洛谷P5535 【XR-3】小道消息)
  9. Cadence OrCAD Capture 将Port信息从底层更新到顶层的方法
  10. Arduino教程 模拟输入输出以及电机和舵机控制