首页 理论 架构 工程 文档 白皮书 著作 研究 案例 下载 博客 关于 开始使用 →

第58章 Template Engine

第58章 Template Engine

SATE(SAI Template Engine)中的 TemplateEngine 是模板系统的运行核心。

第57章已经定义了 Template 的组成:

Template
├── Object
├── Variable
├── Property
├── Method
├── Condition
├── Loop
└── Context

本章进一步建立 Template 从加载、解析、编译、缓存、注册到执行的完整运行机制。

核心流程:

Template Source
      ↓
TemplateLoader
      ↓
TemplateParser
      ↓
TemplateCompiler
      ↓
TemplateCache
      ↓
TemplateRegistry
      ↓
TemplateEngine
      ↓
Template Context
      ↓
Template Execution
      ↓
Rendered Output

1. TemplateEngine

1.1 TemplateEngine 定义

TemplateEngine 是 SATE 中负责组织和执行整个模板处理流程的核心引擎。

可以定义为:

TemplateEngine
=
Load
+
Parse
+
Compile
+
Cache
+
Registry
+
Execute

它不是单独负责解析模板,而是负责协调各个模板组件。

TemplateEngine
│
├── TemplateLoader
├── TemplateParser
├── TemplateCompiler
├── TemplateCache
├── TemplateRegistry
└── Template Executor

1.2 TemplateEngine 的职责

TemplateEngine 主要完成:

  1. 获取模板
  2. 加载模板
  3. 解析模板
  4. 编译模板
  5. 缓存编译结果
  6. 注册模板
  7. 创建 Template Context
  8. 执行模板
  9. 输出 Render Result

因此:

TemplateEngine

是一个模板运行协调器


1.3 TemplateEngine 不负责什么

TemplateEngine 不应该负责:

认知
推理
决策
学习
知识形成
事实判断
行为决策

也就是说:

ReasoningEngine
→ 负责推理

Decision
→ 负责决策

Behavior
→ 负责行为

ActionExecutor
→ 负责行动

Expression
→ 负责表现

TemplateEngine
→ 负责模板执行

这样能够保持 SAI/ICAI 各模块职责清晰。


2. TemplateLoader

2.1 TemplateLoader 定义

TemplateLoader 负责获取模板源。

基本流程:

Template Name
      ↓
TemplateLoader
      ↓
Template Source

例如:

company.html

通过 Loader 获取:

<div>
    <h1>{{Company.name}}</h1>
</div>

2.2 Template 来源

SATE 可以允许不同的模板来源:

File
String
Database
Memory
Package
Remote Source

但不同来源不应该改变 TemplateEngine 的核心执行流程。

例如:

File
 ↓
Loader
 ↓
Template Source

或者:

String
 ↓
Loader
 ↓
Template Source

最终都进入:

TemplateParser

2.3 TemplateLoader 基本结构

TemplateLoader
{
    source
    path
    encoding
    state
}

主要方法:

load()
exists()
getSource()
getPath()
validate()

例如:

TemplateLoader.load("company.html")

返回:

TemplateSource
{
    name: "company.html",
    source: "...",
    state: "LOADED"
}

2.4 Loader 状态

可以定义:

NEW
LOADING
LOADED
NOT_FOUND
INVALID
ERROR

其中:

LOADED

才允许进入 Parser。


3. TemplateParser

3.1 TemplateParser 定义

TemplateParser 负责把模板源代码解析成 SATE 可以识别的模板结构。

Template Source
      ↓
TemplateParser
      ↓
Template Structure

例如:

<h1>{{Company.name}}</h1>

解析成:

Template
│
└── Element
    ├── Text
    └── Variable
        └── Company.name

3.2 Parser 的作用

Parser 不执行模板。

它只负责:

读取
识别
拆分
组织
验证

因此:

Parser ≠ Executor

3.3 Token

Parser 可以首先将模板拆成 Token。

例如:

<h1>{{Company.name}}</h1>

可以解析为:

TEXT      "<h1>"
VARIABLE  "Company.name"
TEXT      "</h1>"

形成:

Template Source
 ↓
Tokenization
 ↓
Tokens
 ↓
Template Structure

3.4 Condition Token

例如:

{{if Product.state == "active"}}
    Available
{{/if}}

可以形成:

IF
 ├── Condition
 │   ├── Object: Product
 │   ├── Property: state
 │   ├── Operator: ==
 │   └── Value: active
 │
 └── Body
     └── TEXT: Available

3.5 Loop Token

例如:

{{foreach Products as Product}}
    {{Product.name}}
{{/foreach}}

可以解析为:

FOREACH
 ├── Collection: Products
 ├── Variable: Product
 └── Body
     └── Variable: Product.name

4. TemplateCompiler

4.1 TemplateCompiler 定义

Parser 得到的是结构。

Compiler 将模板结构转换为更适合执行的内部结构。

Template Source
 ↓
Parser
 ↓
Template AST / Structure
 ↓
Compiler
 ↓
Compiled Template

这里的 Compiler 并不是把模板编译成机器代码。

它主要是:

把模板结构转换为 SATE 可快速执行的内部表示。


4.2 为什么需要 Compiler

如果每一次输出都重新解析:

Load
 ↓
Parse
 ↓
Resolve
 ↓
Execute

重复成本较高。

因此可以:

第一次
Template
 ↓
Parse
 ↓
Compile
 ↓
CompiledTemplate

之后:

Data
 ↓
CompiledTemplate
 ↓
Execute

4.3 CompiledTemplate

可以定义:

CompiledTemplate
{
    id
    name
    nodes
    variables
    conditions
    loops
    methods
    version
    state
}

例如:

CompiledTemplate
{
    name: "company",
    nodes: [
        TEXT,
        VARIABLE,
        TEXT,
        CONDITION,
        LOOP
    ],
    state: "READY"
}

4.4 Compiler 的基本过程

Template Structure
 ↓
Node Analysis
 ↓
Variable Mapping
 ↓
Property Mapping
 ↓
Condition Mapping
 ↓
Loop Mapping
 ↓
Method Mapping
 ↓
CompiledTemplate

5. TemplateCache

5.1 TemplateCache 定义

TemplateCache 用于保存已经加载、解析或编译后的模板资源。

最常见的是缓存:

CompiledTemplate

流程:

Template
 ↓
Compile
 ↓
Cache

再次使用:

Template Name
 ↓
Cache
 ↓
CompiledTemplate
 ↓
Execute

5.2 Cache 的目的

主要目的:

减少重复加载
减少重复解析
减少重复编译
提高执行效率

例如第一次:

company.html
 ↓
Load
 ↓
Parse
 ↓
Compile
 ↓
Cache

第二次:

company.html
 ↓
Cache Hit
 ↓
CompiledTemplate
 ↓
Execute

5.3 Cache Hit / Miss

可以定义:

Cache Hit
→ 缓存存在且有效

Cache Miss
→ 缓存不存在或已经失效

执行:

Request
 ↓
Cache?
 ├── HIT → Execute
 │
 └── MISS
      ↓
    Load
      ↓
    Parse
      ↓
    Compile
      ↓
    Cache
      ↓
    Execute

5.4 Cache 状态

EMPTY
VALID
EXPIRED
INVALID
DELETED

如果模板文件发生变化:

Old Cache
 ↓
INVALID
 ↓
Reload
 ↓
Parse
 ↓
Compile
 ↓
New Cache

因此缓存不能凌驾于模板源文件的真实性之上。


6. TemplateRegistry

6.1 TemplateRegistry 定义

TemplateRegistry 是 SATE 中用于登记和管理模板的注册表。

例如:

TemplateRegistry
{
    company
    product
    product_list
    error
    status
}

它解决的问题是:

系统当前有哪些可用模板?


6.2 Registry 与 Cache 的区别

二者必须区分。

TemplateRegistry
→ 管理模板登记信息

TemplateCache
→ 保存模板运行缓存

例如:

Registry
{
    product: "templates/product.html"
}

表示:

product 模板在哪里

而:

Cache
{
    product: CompiledTemplate
}

表示:

product 模板已经编译好的运行结构

因此:

Registry ≠ Cache

6.3 Registry 基本结构

TemplateRegistry
{
    templates
    aliases
    versions
    states
}

例如:

templates
{
    company: "company.html",
    product: "product.html",
    list: "product_list.html"
}

6.4 Registry 方法

可以提供:

register()
unregister()
exists()
get()
set()
list()
enable()
disable()

例如:

register(
    "product",
    "templates/product.html"
)

之后:

get("product")

即可获得模板登记信息。


7. Template 执行

现在将前面所有组件连接起来。


7.1 完整执行流程

Template Name
      ↓
TemplateRegistry
      ↓
TemplateLoader
      ↓
TemplateCache
      ↓
TemplateParser
      ↓
TemplateCompiler
      ↓
CompiledTemplate
      ↓
TemplateContext
      ↓
TemplateExecutor
      ↓
Rendered Output

注意:

Cache

应该在合理位置进行检查。

完整逻辑:

Request Template
      ↓
Registry
      ↓
Cache?
 ┌────┴────┐
 HIT      MISS
 ↓          ↓
Compile   Loader
 ↓          ↓
Execute   Parser
            ↓
          Compiler
            ↓
           Cache
            ↓
          Execute

7.2 创建 Context

模板执行之前,需要建立:

TemplateContext

例如:

TemplateContext
{
    Company,
    Products,
    current_date
}

然后:

CompiledTemplate
 +
TemplateContext

进入执行阶段。


7.3 Variable Resolution

例如:

{{Company.name}}

执行:

Context
 ↓
Company
 ↓
name
 ↓
Value
 ↓
Render

7.4 Condition Execution

例如:

{{if Company.state == "active"}}
    Active
{{/if}}

执行:

Company.state
 ↓
"active"
 ↓
Condition
 ↓
TRUE
 ↓
Render Body

7.5 Loop Execution

例如:

{{foreach Products as Product}}
    {{Product.name}}
{{/foreach}}

执行:

Products
 ↓
Collection
 ↓
Loop
 ├── Product A → Render
 ├── Product B → Render
 └── Product C → Render

8. 完整模板运行

下面建立一个完整的 SATE Template Engine 运行实例。


8.1 原始数据

系统已经拥有:

Company
{
    name: "Company A",
    city: "Shenzhen",
    state: "active"
}

以及:

Products
[
    {
        name: "Product A",
        price: 29.90,
        state: "active"
    },
    {
        name: "Product B",
        price: 39.90,
        state: "inactive"
    }
]

这些数据已经存在。

TemplateEngine 不负责产生这些数据。


8.2 Template

<div class="company">

    <h1>{{Company.name}}</h1>

    <p>City: {{Company.city}}</p>

    {{if Company.state == "active"}}
        <p>Status: Active</p>
    {{else}}
        <p>Status: Inactive</p>
    {{/if}}

    <ul>

        {{foreach Products as Product}}

            <li>
                <strong>{{Product.name}}</strong>
                <span>{{Product.price}}</span>

                {{if Product.state == "active"}}
                    <span>Available</span>
                {{else}}
                    <span>Unavailable</span>
                {{/if}}
            </li>

        {{/foreach}}

    </ul>

</div>

8.3 Registry

首先注册:

TemplateRegistry
{
    company:
        "templates/company.html"
}

执行:

get("company")

得到:

templates/company.html

8.4 Loader

Loader 加载:

templates/company.html

得到:

TemplateSource
{
    name: "company",
    state: "LOADED"
}

8.5 Cache 检查

第一次运行:

Cache
 ↓
MISS

因此继续:

Parser

8.6 Parser

Parser 得到:

Template
│
├── Text
├── Variable
│   └── Company.name
│
├── Variable
│   └── Company.city
│
├── Condition
│   └── Company.state == active
│
└── Loop
    └── Products
        └── Product
            ├── name
            ├── price
            └── state condition

8.7 Compiler

Compiler 将其转换:

CompiledTemplate
{
    nodes: [
        TEXT,
        VARIABLE,
        TEXT,
        VARIABLE,
        CONDITION,
        LOOP
    ],
    state: "READY"
}

然后:

CompiledTemplate
 ↓
TemplateCache

8.8 Context

建立:

TemplateContext
{
    Company,
    Products
}

进入执行:

CompiledTemplate
+
TemplateContext

8.9 TemplateEngine 执行

第一步:

{{Company.name}}

得到:

Company A

第二步:

{{Company.city}}

得到:

Shenzhen

第三步:

Company.state == active

得到:

TRUE

因此表现:

<p>Status: Active</p>

8.10 Loop 执行

Products 有两个对象:

Product A
Product B

第一次:

Product = Product A

得到:

Product A
29.90
Available

第二次:

Product = Product B

得到:

Product B
39.90
Unavailable

8.11 最终 Render Result

最终输出:

<div class="company">

    <h1>Company A</h1>

    <p>City: Shenzhen</p>

    <p>Status: Active</p>

    <ul>

        <li>
            <strong>Product A</strong>
            <span>29.9</span>
            <span>Available</span>
        </li>

        <li>
            <strong>Product B</strong>
            <span>39.9</span>
            <span>Unavailable</span>
        </li>

    </ul>

</div>

TemplateEngine 完整架构

至此,SATE 的模板运行体系可以形成:

                    SATE
                     │
              TemplateEngine
                     │
        ┌────────────┼────────────┐
        │            │            │
   TemplateLoader  Parser      Registry
        │            │            │
        │        Template AST      │
        │            │            │
        │        Compiler          │
        │            │            │
        └────────────┼────────────┘
                     │
                TemplateCache
                     │
              CompiledTemplate
                     │
              TemplateContext
                     │
               Template Execute
                     │
                  Render
                     │
              Expression Result
                     │
                   Output

TemplateEngine 与 SATE 的关系

可以进一步明确:

SATE
│
├── Template
│
├── TemplateEngine
│
├── TemplateLoader
│
├── TemplateParser
│
├── TemplateCompiler
│
├── TemplateCache
│
├── TemplateRegistry
│
├── TemplateContext
│
└── Renderer

其中:

Template
→ 定义表现结构

TemplateLoader
→ 获取模板

TemplateParser
→ 解析模板

TemplateCompiler
→ 建立可执行模板结构

TemplateCache
→ 保存可复用模板结构

TemplateRegistry
→ 管理模板登记

TemplateContext
→ 提供执行环境

TemplateEngine
→ 组织整个运行过程

Renderer
→ 形成最终表现结果

本章核心模型

Template
 ↓
Registry
 ↓
Loader
 ↓
Cache
 ↓
Parser
 ↓
Compiler
 ↓
CompiledTemplate
 ↓
Context
 ↓
Engine
 ↓
Execute
 ↓
Render
 ↓
Output

其中第一次运行通常是:

Load
 ↓
Parse
 ↓
Compile
 ↓
Cache
 ↓
Execute

后续运行可以直接:

Registry
 ↓
Cache
 ↓
CompiledTemplate
 ↓
Context
 ↓
Execute

最终定义:

TemplateEngine 是 SATE 中负责组织 TemplateLoader、TemplateParser、TemplateCompiler、TemplateCache、TemplateRegistry、TemplateContext 与模板执行过程的核心运行引擎,用于将模板与已有结构化数据按照确定性的模板规则转换为表现结果。

最重要的边界仍然是:

Template       = 定义表现结构
TemplateEngine = 执行表现结构
Expression     = 表达结果
Output         = 外部表现

而不是:

TemplateEngine → 认知
TemplateEngine → 推理
TemplateEngine → 决策
TemplateEngine → 学习

这样,SATE 可以作为 ICAI Expression → Template → Output 这一层的独立、确定性表现引擎。

Leave a Reply

Your email address will not be published. Required fields are marked *