FarBox 的模板引擎采用的改良过的 Jade 语法, 并最终编译为 HTML 形态的 Jinja 模板结构。
为了保证语法的一致性以及更加的简洁,我们呈现的的模板文件仅仅支持 .jade
后缀的 Jade 语法,并且所有的表述中涉及到的代码也都是 Jade
语法。
当然,在某些场合,如果你比较了解 Jinja 的模板语法,HTML 和 Jade 两者是可以同时混用的。
FarBox将我们常见的文件目录结构转化为了可快速查询的数据库调用,而 API 的主要功能在于渲染页面(HTML)。
如果用传统的角度看待,那么,一个是后端
,一个是前端
。所以,我们一直在寻找可以融合前后端的API语法,经过改造的Jade
语法,基本上满足了我们的设计需求。
Jade是Node.js世界中的一种Python式缩进的模板语法,经过改造后,FarBox 可以将.jade
文件转化为Jinja2
的语法。
为了更好地进行编写,你可能需要为自己的代码编辑器/IDE增加Jade
语法的支持插件。
.class_name this is content
// 默认会创建div标签,最终结果为<div class="class_name">this is content</div>
tag_name.class_name
// 最终结果为<tag_name class="class_name"></tag_name>
p.class1.class2.class3
// 多个class,最终结果为<p class="class1 class2 class3"></p>
a.a_class(href="#", title="this is a link")
// 多个属性,用`,`隔开,最终结果为<a class="a_class" href="#" title="this is a link"></a>
span#dom_id.class_name_1.class_name_2 this is content
// 最终结果为<span id="dom_id", class="class_name_1 class_name_2">this is content</span>
.class_name this is line 1
| this is line 2
//
| 可以在跨行中使用 (一般也不会用,代码看起来不好看),最终结果为
<div class="class_name">
this is line 1
this is line 2
</div>
如果直接将具体的变量与HTML标签关联起来,可参照如下语法。
node post.content
//等同于<node>post.content</node>
var = post.content
// 等同于 {%set var = post.content %}, 是一个变量的赋值
node= post.content
// =号左前无空格,则是将变量转为HTML标签,等同于<node>{{ post.content }}</node>
node= 'post.content'
// 等同于<node>post.content</node>
如果HTML标签中有其它属性定义的。
a(href=post.url)= post.title
// 等同于 <a href={{post.url}}>{{post.title}}</a>
a(href='/post/{{post.url_path}}')= post.title
// 这混合了Jinja2语法,等同于 <a href='/post/{{post.url_path}}'>{{post.title}}</a>
head
if site.title == 'test'
title= site.title
elif site.title == 'a test too'
title= site.title + '!!!'
else
title= 'blank'
body
for post in posts
h1= post.title
不要将 if/else/for 跟其它逻辑混合, 以下语法都是错误的,会导致模板编译无法成功。
if post
+post.content
else no content
// 这样写的else是无效的,既不是HTML标签,也不是逻辑判断; 要空一行先。
+resposne.raise_404()
当代码比较长的时候,可以在行尾输入\
,然后重起一行,在最终编译的过程中,会自动重新合并为一行。
有些时候,过度的缩进语法,会让模板看起来有些错乱,特别是if / else / for
等逻辑下。那么在简单逻辑下,可以使用 :
进行分割,并不会影响最终的效果。
.posts: .posts_container
for post in posts: .post
.title= post.title
实际等价于:
.posts
.posts_container
for post in posts
.post
.title= post.title
这分别对应Jinja2语法中的extends
与include
,但跟Jinja2不一样的是,不要增加单引号/或双引号。
extends base.jade
// 等价于 Jinja 中的 {% extends 'base.jade' %}
include include/comments.jade
// 等价于 Jinja 中的{% include 'include/comments.jade' %}
macro
是Jinja2的概念,mixin
则是Jade的概念; 在 FarBox 中两者基本等价。
macro
相当于自定义一个函数,然后在模板中进行调用,另外,我们也支持对这个函数产生的数据进行缓存,前提是使用cache_
为开头的函数名。
Jinja2是Python语言创建的模板框架,所以macro
的定义方式,基本接近Python语言中函数的定义。
mixin sidebar(name)
h1= name
p this is sidebar
// 等价于 Jinja 中
{% macro sidebar(name) %}
<h1>{{ name }}</h1>
<p> this is sidebar </p>
{% endmacro %}
如果macro的定义与调用,都在同一个模板页,则后面可以直接使用这个定义出来的函数。
from "mixins.jade" import get_url
// 等价于 Jinja 中的 {% from "mixins.jade" import get_url %}
macro相对于include而言,它的性能其实更高,include不可避免地会带入一个变量空间,从而造成混乱的概率增加;而macro的内容如果不调用外部变量,则可以有效地防止变量空间混乱的情况。
但一般情况下,视自己如何方便,如何来即可。
在.jade的模板文件中,可以在单独一行中使用Jinja2的语法。
extends base.jade
from "mixins" import make_posts_list
{{ site.title }}
FarBox 对.jade后缀的模板文件进行编译过程中,会进行以下的自动补全:
doctype html
utf8