Stencil模板引擎语言详解:从基础语法到高级特性

Stencil模板引擎语言详解:从基础语法到高级特性

前言

Stencil是一款功能强大的模板引擎,专为Swift语言设计。它借鉴了Django和Jinja2等成熟模板语言的优秀特性,同时针对Swift生态进行了优化。本文将全面解析Stencil模板语言的核心概念和使用方法,帮助开发者快速掌握这一工具。

基础语法结构

Stencil模板语言提供了三种基本语法结构,每种结构都有其特定的用途和语法形式:

  1. 变量输出:使用双大括号{{ ... }}包裹变量或表达式,模板引擎会将其计算结果输出到最终生成的文本中。

  2. 控制标签:使用{% ... %}包裹控制语句,实现条件判断、循环等流程控制功能。

  3. 注释:使用{# ... #}包裹注释内容,这些内容不会出现在最终输出中。

变量处理机制

基本变量输出

最简单的变量输出形式是直接使用变量名:

{{ username }}

Stencil会从当前上下文中查找并输出username变量的值。

复杂变量查找

当变量名包含点号(.)时,Stencil会按照特定顺序进行多层次查找:

  1. 上下文查找
  2. 字典查找
  3. 数组和字符串查找(支持first、last、count等属性以及索引访问)
  4. 键值编码查找
  5. 动态成员查找(符合DynamicMemberLookup协议时)
  6. 类型内省(通过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提供了精细的空白字符控制机制:

  1. 全局设置:通过配置trimBehavior参数控制,可选值包括:

    • nothing:默认值,不自动修剪
    • smart:智能修剪
    • all:修剪所有空白
  2. 局部控制

    • {{+ 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 %}

继承特性说明

  1. 多级继承:支持无限级继承,形成base.html → section.html → page.html的层次结构
  2. 父内容引用:使用{{ block.super }}在子模板中引用父模板的块内容
  3. 块复用:定义后可通过{{ block.name }}多次输出块内容

最佳实践建议

  1. 项目结构

    • 将基础模板放在templates/base/目录
    • 按功能模块组织子模板
    • 公共组件提取为独立模板片段
  2. 性能优化

    • 对计算密集型数据使用LazyValueWrapper
    • 合理使用模板缓存
    • 避免在模板中进行复杂计算
  3. 可维护性

    • 为复杂模板添加注释
    • 保持模板简洁,将业务逻辑放在Swift代码中
    • 使用有意义的块名称

通过掌握这些核心概念和技巧,开发者可以充分利用Stencil模板引擎构建灵活、高效且易于维护的文本生成系统。

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值