etpl-wrap的产生_html/css_WEB-ITnose
这周发了个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执行

핫 AI 도구

Undresser.AI Undress
사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover
사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool
무료로 이미지를 벗다

Clothoff.io
AI 옷 제거제

Video Face Swap
완전히 무료인 AI 얼굴 교환 도구를 사용하여 모든 비디오의 얼굴을 쉽게 바꾸세요!

인기 기사

뜨거운 도구

메모장++7.3.1
사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전
중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기
강력한 PHP 통합 개발 환경

드림위버 CS6
시각적 웹 개발 도구

SublimeText3 Mac 버전
신 수준의 코드 편집 소프트웨어(SublimeText3)

뜨거운 주제











HTML은 간단하고 배우기 쉽고 결과를 빠르게 볼 수 있기 때문에 초보자에게 적합합니다. 1) HTML의 학습 곡선은 매끄럽고 시작하기 쉽습니다. 2) 기본 태그를 마스터하여 웹 페이지를 만들기 시작하십시오. 3) 유연성이 높고 CSS 및 JavaScript와 함께 사용할 수 있습니다. 4) 풍부한 학습 리소스와 현대 도구는 학습 과정을 지원합니다.

HTML은 웹 구조를 정의하고 CSS는 스타일과 레이아웃을 담당하며 JavaScript는 동적 상호 작용을 제공합니다. 세 사람은 웹 개발에서 의무를 수행하고 화려한 웹 사이트를 공동으로 구축합니다.

anexampleStartingtaginhtmlis, whithbeginsaparagraph.startingtagsareessentialinhtmlastheyinitiate rements, definetheirtypes, andarecrucialforstructurituringwebpages 및 smanstlingthedom.

WebDevelopmentReliesonHtml, CSS 및 JavaScript : 1) HtmlStructuresContent, 2) CSSSTYLESIT, 및 3) JAVASCRIPTADDSINGINTERACTIVITY, BASISOFMODERNWEBEXPERIENCES를 형성합니다.

GiteEpages 정적 웹 사이트 배포 실패 : 404 오류 문제 해결 및 해결시 Gitee ...

웹 주석 기능에 대한 Y 축 위치 적응 알고리즘이 기사는 Word 문서와 유사한 주석 기능을 구현하는 방법, 특히 주석 간격을 다루는 방법을 모색합니다 ...

이미지를 클릭 한 후 주변 이미지를 산란 및 확대하는 효과를 얻으려면 많은 웹 디자인이 대화식 효과를 달성해야합니다. 특정 이미지를 클릭하여 주변을 만들 수 있습니다 ...

vue 응용 프로그램을 개발할 때 라우터 폴더 아래에 index.js 파일에 vuerouter를 등록해야 할 필요성이 있으면 종종 라우팅 구성에 문제가 발생합니다. 특별한...
