模板

Finch 使用 Jinja(Python 模板引擎)进行服务端 HTML 渲染。模板文件位于 widgetsPath 目录中,通常使用 .j2.html 扩展名。

渲染模板

在控制器中使用 rq.renderView()

return rq.renderView(
  path: 'home/index',     // 相对于 widgetsPath,不含扩展名
  params: {
    'title': '首页',
    'items': ['苹果', '香蕉'],
  },
);

Jinja 语法速查

概念 语法
变量 {{ variable }}
注释 {# 这是注释 #}
条件 {% if condition %} … {% endif %}
循环 {% for item in list %} … {% endfor %}
引入 {% include 'partial.j2.html' %}
继承 {% extends 'layout.j2.html' %}
定义块 {% block content %} … {% endblock %}
填充块 {% block content %} … {% endblock %}
过滤器 {{ value | upper }}
多行注释 {# ... #}

示例:基础模板

{# lib/widgets/layout/base.j2.html #}
<!DOCTYPE html>
<html>
<head>
  <title>{{ title }}</title>
</head>
<body>
  {% block content %}{% endblock %}
</body>
</html>

示例:子页面

{# lib/widgets/home/index.j2.html #}
{% extends 'layout/base.j2.html' %}

{% block content %}
  <h1>{{ title }}</h1>
  {% for item in items %}
    <p>{{ item }}</p>
  {% endfor %}
{% endblock %}

引入局部模板

{% include 'shared/navbar.j2.html' %}

内置模板

Finch 提供默认布局。您可以用 widgetsPath 中的自定义模板覆盖它。

本地事件

模板可以注册在渲染前执行的 Dart 事件:

// 在控制器中:
rq.localEvents.add(MyEvent());
class MyEvent extends LocalEvent {
  @override
  Future<void> run(Request rq) async {
    rq.addParam('currentUser', await UserModel().getCurrent(rq));
  }
}

本地布局过滤器

通过 rq.localLayoutFilters 添加自定义 Jinja 过滤器:

rq.localLayoutFilters['shorten'] = (value, args) {
  return value.toString().substring(0, 50);
};

在模板中使用:

{{ longText | shorten }}

内置变量

Finch 在每次模板渲染时自动注入以下变量:

变量 描述
$language 当前语言代码('en''zh'、...)
$e 包含辅助方法的模板事件对象
$t 翻译函数 — {{ $t('key') }}
$n 嵌套导航