Stencil模板引擎语言详解:从基础语法到高级特性
前言
Stencil是一款功能强大的模板引擎,专为Swift语言设计。它借鉴了Django和Jinja2等成熟模板语言的优秀特性,同时针对Swift生态进行了优化。本文将全面解析Stencil模板语言的核心概念和使用方法,帮助开发者快速掌握这一工具。
基础语法结构
Stencil模板语言提供了三种基本语法结构,每种结构都有其特定的用途和语法形式:
-
变量输出:使用双大括号
{{ ... }}
包裹变量或表达式,模板引擎会将其计算结果输出到最终生成的文本中。 -
控制标签:使用
{% ... %}
包裹控制语句,实现条件判断、循环等流程控制功能。 -
注释:使用
{# ... #}
包裹注释内容,这些内容不会出现在最终输出中。
变量处理机制
基本变量输出
最简单的变量输出形式是直接使用变量名:
{{ username }}
Stencil会从当前上下文中查找并输出username
变量的值。
复杂变量查找
当变量名包含点号(.)时,Stencil会按照特定顺序进行多层次查找:
- 上下文查找
- 字典查找
- 数组和字符串查找(支持first、last、count等属性以及索引访问)
- 键值编码查找
- 动态成员查找(符合DynamicMemberLookup协议时)
- 类型内省(通过Mirror机制)
例如,对于数组类型的people
变量:
共有{{ people.count }}人。{{ people.first }}是第一位,接着是{{ people.1 }}。
动态属性访问
Stencil支持使用下标运算符进行动态属性访问,方括号内的表达式会先被求值:
// 上下文示例
[
"item": ["name": "张三"],
"key": "name"
]
模板中可以这样使用:
{{ item[key] }} <!-- 等同于 {{ item.name }} -->
延迟求值
对于计算成本较高的值,可以使用LazyValueWrapper
实现延迟求值:
[
"magic": LazyValueWrapper(heavyCalculation())
]
这样heavyCalculation()
只会在模板首次访问magic
时执行,结果会被缓存供后续使用。
布尔表达式与逻辑运算
Stencil支持在变量输出标签中直接使用布尔表达式:
{{ age >= 18 }} <!-- 输出true或false -->
{{ isActive && hasPermission }}
过滤器系统
过滤器是Stencil中强大的值转换工具,使用管道符(|)连接:
{{ title|uppercase }} <!-- 将标题转为大写 -->
{{ content|truncate:50 }} <!-- 截断内容为50个字符 -->
Stencil内置了丰富的过滤器,包括大小写转换、字符串截断、日期格式化等。
控制标签详解
控制标签为模板提供了流程控制能力,以下是几个核心标签:
条件判断
{% if score >= 90 %}
优秀
{% elseif score >= 60 %}
及格
{% else %}
不及格
{% endif %}
循环迭代
{% for product in products %}
<div>{{ forloop.counter }}. {{ product.name }}</div>
{% empty %}
<p>暂无产品</p>
{% endfor %}
循环体内可以使用特殊变量如forloop.counter
(当前迭代次数)等。
变量定义
{% let total = items|count %}
{% var discount = 0.9 %}
模板注释
注释内容不会出现在最终输出中:
{# 这是不会被渲染的注释 #}
空白字符控制
Stencil提供了精细的空白字符控制机制:
-
全局设置:通过配置trimBehavior参数控制,可选值包括:
nothing
:默认值,不自动修剪smart
:智能修剪all
:修剪所有空白
-
局部控制:
{{+ if ... }}
:保留标签前的空白{{ if ... -}}
:修剪标签后的空白
模板继承系统
模板继承是Stencil最强大的特性之一,允许创建可复用的模板结构。
基础模板(base.html)
<!DOCTYPE html>
<html>
<head>
<title>{% block title %}默认标题{% endblock %}</title>
</head>
<body>
{% block content %}{% endblock %}
</body>
</html>
子模板(child.html)
{% extends "base.html" %}
{% block title %}子页面标题{% endblock %}
{% block content %}
<h1>欢迎</h1>
<p>这是自定义内容区域</p>
{% endblock %}
继承特性说明
- 多级继承:支持无限级继承,形成
base.html → section.html → page.html
的层次结构 - 父内容引用:使用
{{ block.super }}
在子模板中引用父模板的块内容 - 块复用:定义后可通过
{{ block.name }}
多次输出块内容
最佳实践建议
-
项目结构:
- 将基础模板放在
templates/base/
目录 - 按功能模块组织子模板
- 公共组件提取为独立模板片段
- 将基础模板放在
-
性能优化:
- 对计算密集型数据使用LazyValueWrapper
- 合理使用模板缓存
- 避免在模板中进行复杂计算
-
可维护性:
- 为复杂模板添加注释
- 保持模板简洁,将业务逻辑放在Swift代码中
- 使用有意义的块名称
通过掌握这些核心概念和技巧,开发者可以充分利用Stencil模板引擎构建灵活、高效且易于维护的文本生成系统。
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考