问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501

九洲战记

发布网友 发布时间:2022-04-21 19:05

我来回答

2个回答

懂视网 时间:2022-04-21 23:26

这周发了个etpl的node包装器,到npm上,以及对应的github地址: https://github.com/wslx520/etpl-wrap

为什么会有etpl-wrap?

etpl是我用过的一款非常强大的模板引擎,该有的功能都有。

etpl是可以用在node环境下的,但用法与我想像中的不一样。

这就要从我学习koa说起了,我学的koa2,他有一个koa-views的中间件,用来接入渲染模板文件的功能。但理所当然的是,无法与etpl配合起来使用。

之前express也是如此,如果有某引擎要与express配合起来,需要额外设置,也许还要在源码里专门做些工作。

我觉得这样很别扭,web框架与模板引擎关系大吗?不应该是互相独立的吗?

比如koa,使用了koa-views并接入模板引擎用,为的就是在渲染模板的时候,可以使用

ctx.body = ctx.render(‘index’,data)

这样的语法来渲染。但我想,假如我有一个完全独立的模板引擎,难道不可以这样用?:

ctx.body = etpl.render(‘index’,data)

这样的用法,模板引擎与web框架完全无关。你甚至可以在express中,按同样的语法使用:

res.end(etpl.render(‘index’,data))

这样不才是更好的状态吗?为啥模板引擎必须要注入到web框架里?

etpl在Node下的不一样

Node好歹也是服务器环境,如果他有模板文件 ,一般也是一个文件。但 etpl不具备直接渲染文件的能力。

如果我们使用etpl来渲染一个Node下的模板文件,按正常流程,我们需要先读取到文件的内容,转换成字符串,然后传给etpl.compile,然后render。

但这样太不智能了,我不能接受。

所以我就想写这么一个包装器,用来在node.js下方便的使用etpl.

包装原理

包装器有个原则:不能改动原始的源代码。也就是说,我不能对etpl本身做什么,不然etpl以后升级了,我就难办了。

我粗看了一个etpl的源代码,但复杂了,而我时间有限,看完他不现实(其实是我看不太懂)

本来我打算的是,在render时,动态读取对应的模板文件,如果未编译,就编译,再渲染,并要把编译结果缓存起来(避免重复编译的消耗);如果已编译,就马上渲染

但这样有些难了,而且说不定必须改etpl源码。

后来我自我安慰说,一个网站的模板文件,加起来应该也不超过10M吧,小case,我 从一进来就读取所有的模板文件,并依次调用etpl.compile编译了,以后etpl.render的时候,就不用担心“有没有编译过”的问题。

虽然这样肯定 在启动服务器时,就会有额外的消耗,但应该可以接受。

target

etpl为了方便编译不同的“模块”,使用了target。比如我们新建了一个index.html的模板文件,如果以后想etpl.render(‘index’,data)的话,则index.html的第一句必须是一个target声明,如:

但这样对服务器端显然不合理,因为在服务器端,每个不同的文件,就是不同的模块。

所以包装器做了个处理:

如果模板文件第一句不是target声明,则以当前模板文件的名字作为target的名字

还有,如果你非要在模板文件第一句声明target,则target name需要与模板文件名一致

这么一算还是不写target划算

另外,在浏览器端,用户需要自行规避target同名的问题。但在服务器端,根目录下可以有list.html,子目录下也可以有,二者理论上是完全不冲突的

子目录下的模板文件

2016/5/5下午想明白一个原则:“ 同目录下的所有target都是同级的”。这原则相信没人会反对,基于本原则,很多关于子目录下的模板问题都能简单解决

如果子目录下有多个模板文件,则默认以index当作主文件。如有子目录:main,则其下的index会自动变成target:main

此时如有想引用main/index的,引用main就行了。

,其他文件如main/content,则会变成target: main/content

但其实main与main/content是同级的(因为main=main/index)

可以 考虑增加一个“默认主模板”的参数,可以设置为index,main等

子目录下的模块与父级模板互引用

服务器环境的模板,还有个问题,就是子目录下的模板。

比如根目录下的index.html可能会 import: list/list1.html

而子目录下的模板也可能会引用父级目录的模板如:import : ../header

这是浏览器端的etpl不会碰到的情况

所幸如果 直接把target名字取为一个路径的话,在etpl里也能正常使用,如:

target: header/head-detail

同文件下多个target的情况

etpl当然是允许一个模板文件下有多个target的,所以我不能去掉这个功能

那么,在一个模板文件中,有import其他target时,此时就要考虑:

是引用的本文件的其他某target?

是引用的本文件同级下的其他模板文件?

如果引用的target,在同级或父级的其他模板文件中,也有,优先级是?–本文件最高

按最简单的原则,优先级应该是:同文件下的target==> 同级下的其他文件里target

一个文件引用其他文件下的其他target

比如有个header.html,会被默认当作target:header,但他后面有另一个target: li,此时,有另一个模板文件list.html,也想使用target:li,该如何引用?

本来我考虑在import时,使用 import: header.li 来引入,但测试发现这样的target名字会导致etpl报错(后来查看源码,可以通过修改源码修正这个问题,但这不合我的要求)

如果允许这个引用,可能会出现: import: head/head-left/logo.image的情况

暂时打算禁止 从一个模块文件引入其他模板文件中的非主target。(不过我想,有的人会给非主target取个不会冲突的名字,其他模板文件当成一个全局target一样引用,应该是合法的呢,不应该禁止)

2016/5/5:

今天想到一个思路:同文件下多target,非主target会被当作主target的子target。如:主target:main,则本文件中的其他target分别是main/li, main/p等等。这样一来,有外部文件想引用他们,则直接import: main/li 即可

但这样就有一个要求: 须保证同级目录下的所有模板文件里的所有target,不能重名。但这点是可以做到的。

下午,又想到个问题:

如子目录main下的主模板文件index,里面有其它target: good,编译时会被编译成target: main/good

而main目录下有另一个模板文件content.html,里面也有其他target:other,此时应编译成 main/content/other,还是main/other?

暂时决定是后者,因为需要保证“ 同目录下的所有target都是同级的”,即使你的target是在其他次模板文件里声明的

引用target时的不同

因为node端有了目录概念,所以target也有就有路径,不能像浏览器一样,import:target1,import:target2,而可能会变成:import:list/li1, import:list/li2, import:../main/list2

但前面也说了,target中出现.会让etpl报错

所以我决定在包装器里,将../这种相对路径换算成从 模板根目录出发的绝对路径。比如,root/main/list/ul.html模板文件,import:../list2/li,则会换算成:import:/main/list2/li

最后

鉴于fn.call这样执行函数,效率会低几倍,所以给其中几个函数加入了额外的参数,以避免用call执行

热心网友 时间:2022-04-21 20:34

3301 9tmgmQ66N1F6W1YF
3302 9tmgm787NKML5WMW
3303 9tmgm32NUPTH9C9H
3304 9tmgm4XAY497P0M2
3305 9tmgmCTLF936U8H0
3306 9tmgmQ0N34KMQ1CY
3307 9tmgmKLY94566KFU
3308 9tmgmNM8YNHYL2NX
3309 9tmgm037K81KFLKY
3310 9tmgm277H6L190TU
3311 9tmgmX9LW3F4U0KQ
3312 9tmgm8J7F02X03R5
3313 9tmgmEECQYNQ5ULL
3314 9tmgmAFP3MX760UA
3315 9tmgm2P9NYTQEJXU
3316 9tmgmA07EREF1YXH
3317 9tmgmK5A7T0YCMAJ
3318 9tmgm08WYM106036
3319 9tmgmREPK0N7K13J
3320 9tmgm3LNQYPA3C09
3321 9tmgmJE5R51FQJP1
3322 9tmgm8JM3CQ8TUTH
3323 9tmgmTFFL30WMW72
3324 9tmgm8J8UYFKUCUU
3325 9tmgm1YTUL1F6MAY
3326 9tmgmC6800JR8C05
3327 9tmgm36WK9YQMJK5
3328 9tmgm8K5AX5KH3JM
3329 9tmgm2TKRX55AC82
3330 9tmgmK7KH1CXKQ0L
3331 9tmgmAN2J1KTR8UU
3332 9tmgmNP0AW9A12NW
3333 9tmgm81NUMKCHEE5
3334 9tmgmT09C531FKCP
3335 9tmgm4564URHEKWH
3336 9tmgmTX4Y4C2J27X
3337 9tmgmP6EW4F5EE19
3338 9tmgmQUP8FUXHP96
3339 9tmgmYQKA2F0AA1P
3340 9tmgm359N5JWK2YT
3341 9tmgmFLUE2EN5AJ1
3342 9tmgm4FMEHRTXM85
3343 9tmgmTMK3W3KXHAK
3344 9tmgmYQ1ELL2YP2M
3345 9tmgmMW1H8EXL6NR
3346 9tmgm72XC6M9QC5X
3347 9tmgm12J2043TL3M
3348 9tmgmK3L96KPQ3JR
3349 9tmgmEL4ETPLL2RH
3350 9tmgmA805AMTCJR2
声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com
乱字同韵字是什么意思 华硕笔记本电脑触摸板怎么开笔记本电脑触摸板怎么开启和关闭_百度知 ... 陕西职务侵占案立案准则 结婚后我的恋情维系了十年,怎么做到的? 玉米仁子饭产自哪里 中国期货交易所的交易品种有哪些? 历史要怎么读,有啥诀窍 高中历史诀窍 年终会活动策划方案 深度解析:第一财经回放,探索财经新风向 端午节放假的今天电信也放假么 电信营业厅放假时间2022 求教铅酸电池,每次充电是不是需要充满 充电器及充电 铅酸蓄电池弟一次充电用不用把电都耗完? 铅酸电池100ah一次充满和分多次充满有区别吗? 铅酸蓄电池必须一次充满吗? 2014年教育心理学考试的报考时间是多久啊? 颈椎病患者的治疗方法是啥呀? 老年人有多种老年并发症症状,同时有颈椎病和腰椎病腿部等问题,选什么中频好呢? 双通道款倍益康电疗仪在功能上的优点是什么? 电法勘探在城市基建中有哪些方法应用 对于单双通道两款电疗仪该怎么选择? 立体动态干扰电和动态干扰电有什么区别 如何提高学生的教学成绩 立体动态干扰电疗法的操作方法 老师怎样提高学习成绩 女儿和好了吗 海上嫁女记何念晴结局是什么 海上嫁女记何冰冰最后和谁在一起 何冰冰的结局是什么 海上嫁女记朱莉结局是什么 朱莉和沈方舟为什么分手 为了学生有效的提高成绩,老师应该怎么做呢? 广西电信营业厅清明哪几天放假 国庆节中国电信放假么 今年春节电信从几号放假? 请问中国电信营业时间是什么?周六周日放假吗 电信营业厅放几天假 有人知道中国电信五一放假的时间吗?在线等!! 中国电信节假日怎么放假? 广东电信营业厅春节放假吗? 中国电信今年什么时间放假 中国电信节假日放假吗? 乡镇已经有了菜鸟驿站,还可以申请小兵驿站吗? 读者传媒什么时候上市 2014年读者传媒分红后股票价格 读者传媒股票明日什么趋势 荣耀6a什么时候上市的 荣耀畅玩6A什么时候上市 读者传媒股票昨天37今天为啥开盘31 菜鸟驿站代收会送到镇上吗 华为荣耀6A什么时候上市 毕业赠言(200字左右)