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

第60章 SATE 自定义模板

第60章 SATE 自定义模板

SATE 的一个重要设计能力,是允许开发者根据自己的业务和表现需求创建 Custom Template(自定义模板)

前面已经建立:

第57章 → Template
第58章 → TemplateEngine
第59章 → Template Syntax

因此本章进一步解决:

开发者如何创建一个属于自己的 SATE Template,并让 TemplateEngine 能够注册、加载、执行,并通过自定义 Renderer 和 Adapter 输出到不同环境。

整体流程:

Custom Template
      ↓
Create
      ↓
Register
      ↓
Load
      ↓
Context + Data
      ↓
Execute
      ↓
Custom Renderer
      ↓
Custom Adapter
      ↓
Output

1. 创建模板

1.1 创建 Template

一个最简单的 SATE 模板:

<div class="product">
    <h1>{{Product.name}}</h1>
    <p>{{Product.price}}</p>
</div>

假设模板文件:

templates/product.html

模板本身只定义:

结构
变量
属性
条件
循环
表现规则

而数据由外部提供:

Product
{
    name: "Product A",
    price: 29.90
}

形成:

Data + Template
       ↓
      SATE
       ↓
     Output

1.2 Template 定义

可以进一步定义:

Template
{
    id
    name
    source
    path
    syntax
    version
    state
}

例如:

Template
{
    id: "tpl_product_001",
    name: "product",
    path: "templates/product.html",
    syntax: "SATE",
    version: "1.0",
    state: "ACTIVE"
}

1.3 自定义模板不等于修改 Engine

SATE 的重要原则是:

Custom Template
        ↓
使用 TemplateEngine

而不是:

Custom Template
        ↓
修改 TemplateEngine 核心代码

例如:

TemplateEngine
       ↑
       │
product.html
company.html
order.html
status.html

不同模板共享同一个 Engine。

这样能够保持:

Engine = 通用
Template = 可定制

2. 注册模板

创建模板以后,需要让 SATE 知道模板的存在。

这由:

TemplateRegistry

负责。


2.1 注册

例如:

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

注册后:

TemplateRegistry
{
    product:
        templates/product.html
}

之后可以:

TemplateRegistry.get("product")

得到:

templates/product.html

2.2 模板注册结构

可以定义:

TemplateRegistration
{
    id
    name
    path
    version
    renderer
    adapter
    state
}

例如:

{
    id: "tpl_product_001",
    name: "product",
    path: "templates/product.html",
    version: "1.0",
    renderer: "html",
    adapter: "web",
    state: "ACTIVE"
}

这样模板不仅登记自身,还可以声明:

使用什么 Renderer
使用什么 Adapter

2.3 注册状态

可以使用:

NEW
ACTIVE
DISABLED
INVALID
ARCHIVED

只有:

ACTIVE

状态的模板才允许正常执行。


3. 加载模板

注册完成以后:

Template Name
      ↓
TemplateRegistry
      ↓
TemplateLoader
      ↓
Template Source

例如:

load("product")

Registry 找到:

templates/product.html

然后 Loader 读取模板。


3.1 TemplateLoader

可以抽象为:

TemplateLoader
{
    load()
    exists()
    getSource()
    validate()
}

例如:

load("templates/product.html")

返回:

TemplateSource
{
    name: "product",
    source: "...",
    state: "LOADED"
}

3.2 加载之后解析

加载不是执行。

完整流程:

Load
 ↓
Parse
 ↓
Compile
 ↓
Cache
 ↓
Execute

所以:

TemplateLoader

只负责:

把模板源交给 SATE。


4. 模板变量

自定义模板可以使用 SATE 标准变量语法。

例如:

<h1>{{Product.name}}</h1>
<p>{{Product.price}}</p>
<p>{{Product.state}}</p>

Context:

TemplateContext
{
    Product
}

解析:

{{Product.name}}

得到:

Product
 ↓
name
 ↓
Product A

4.1 多对象模板

例如:

Context
{
    Company,
    Product,
    User
}

模板:

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

<h2>{{Product.name}}</h2>

<p>{{User.name}}</p>

形成:

Context
│
├── Company
├── Product
└── User

4.2 模板变量来自 Context

重要原则:

Template
    ↓
引用变量
    ↓
Context
    ↓
Data

模板不负责创建业务数据。

例如:

{{Product.name}}

如果 Context 没有:

Product

那么结果应该是:

MISSING

而不是 SATE 自己创建 Product。


5. 模板执行

模板执行由:

TemplateEngine

负责。

例如:

TemplateEngine.render(
    "product",
    Context
)

完整过程:

product
 ↓
Registry
 ↓
Loader
 ↓
Parser
 ↓
Compiler
 ↓
Cache
 ↓
Context
 ↓
Execute
 ↓
Renderer
 ↓
Output

5.1 完整执行实例

数据:

Product
{
    name: "Product A",
    price: 29.90,
    state: "active"
}

模板:

<div class="product">

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

    <p>Price: {{Product.price}}</p>

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

</div>

执行:

Product.name
    ↓
Product A

Product.price
    ↓
29.90

Product.state == active
    ↓
TRUE

最终:

<div class="product">

    <h1>Product A</h1>

    <p>Price: 29.90</p>

    <p>Available</p>

</div>

6. 自定义 Renderer

6.1 Renderer 定义

Renderer 负责把已经解析并执行的模板结构形成具体表现结果。

基本关系:

Template
+
Data
 ↓
TemplateEngine
 ↓
Renderer
 ↓
Rendered Result

例如:

HTML Renderer
JSON Renderer
XML Renderer
Text Renderer
Console Renderer

6.2 HTML Renderer

例如:

HTMLRenderer
{
    render()
}

输入:

Template Result

输出:

<div>
    <h1>Product A</h1>
</div>

6.3 JSON Renderer

同样的数据可以使用 JSON Template:

{
    "name": "{{Product.name}}",
    "price": "{{Product.price}}"
}

Renderer 输出:

{
    "name": "Product A",
    "price": 29.90
}

因此:

同一类结构化数据
        ↓
不同 Template / Renderer
        ↓
不同表现形式

6.4 自定义 Renderer

开发者可以定义:

ProductRenderer

例如:

ProductRenderer
{
    render(context, template)
}

处理:

Product

形成:

Product Output

Renderer 的职责仍然是:

表现

而不是:

认知
推理
决策
学习

7. 自定义 Adapter

7.1 Adapter 定义

Renderer 解决:

如何形成表现结果。

Adapter 解决:

如何把表现结果交给目标环境。

因此:

Renderer → 形成结果
Adapter  → 输出结果

7.2 Web Adapter

例如:

HTMLRenderer
      ↓
HTML
      ↓
WebAdapter
      ↓
HTTP Response

7.3 File Adapter

例如:

Renderer
 ↓
HTML
 ↓
FileAdapter
 ↓
product.html

7.4 API Adapter

例如:

JSONRenderer
 ↓
JSON
 ↓
APIAdapter
 ↓
API Response

7.5 Console Adapter

例如:

TextRenderer
 ↓
Text
 ↓
ConsoleAdapter
 ↓
Terminal

因此:

Renderer
    ↓
Rendered Result
    ↓
Adapter
    ↓
Target Environment

7.6 Adapter 结构

可以定义:

TemplateAdapter
{
    name
    target
    send()
    validate()
    state
}

例如:

WebAdapter
FileAdapter
APIAdapter
ConsoleAdapter

8. 自定义 Template

现在把前面的组件组合起来。

假设开发者需要一个自己的:

Product Template

8.1 创建

文件:

templates/product.html

内容:

<div class="product">

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

    <p>Price: {{Product.price}}</p>

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

</div>

8.2 注册

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

形成:

Registry
└── product
    └── templates/product.html

8.3 加载

TemplateLoader.load("product")

得到:

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

8.4 解析

Parser 识别:

Template
│
├── Variable
│   └── Product.name
│
├── Variable
│   └── Product.price
│
└── Condition
    └── Product.state == active

8.5 编译

Compiler:

Template Structure
       ↓
CompiledTemplate

然后:

TemplateCache

保存:

product → CompiledTemplate

8.6 建立 Context

TemplateContext
{
    Product
}

数据:

Product
{
    name: "Product A",
    price: 29.90,
    state: "active"
}

8.7 执行

TemplateEngine
      ↓
CompiledTemplate
      +
TemplateContext
      ↓
Renderer

HTML Renderer:

HTMLRenderer

产生:

<div class="product">

    <h1>Product A</h1>

    <p>Price: 29.90</p>

    <p>Available</p>

</div>

8.8 Adapter

最后:

HTML
 ↓
WebAdapter
 ↓
HTTP Response

或者:

HTML
 ↓
FileAdapter
 ↓
product.html

同一个 Template 可以根据需要使用不同 Adapter。


自定义 Template 完整架构

                  SATE
                   │
            TemplateEngine
                   │
        ┌──────────┴──────────┐
        │                     │
 TemplateRegistry       TemplateLoader
        │                     │
        └──────────┬──────────┘
                   ↓
             TemplateParser
                   ↓
            TemplateCompiler
                   ↓
             TemplateCache
                   ↓
           CompiledTemplate
                   ↓
            TemplateContext
                   ↓
               Execute
                   ↓
             CustomRenderer
                   ↓
           Rendered Result
                   ↓
             CustomAdapter
                   ↓
             Target Output

Renderer 与 Adapter 的核心区别

这一点在 SATE 中非常重要:

Renderer
→ 结果怎么表现

Adapter
→ 结果送到哪里

例如:

Product Data
     ↓
Product Template
     ↓
HTMLRenderer
     ↓
HTML
     ↓
WebAdapter
     ↓
Browser

也可以:

Product Data
     ↓
Product Template
     ↓
HTMLRenderer
     ↓
HTML
     ↓
FileAdapter
     ↓
HTML File

所以:

Renderer ≠ Adapter

SATE 自定义模板完整运行链

最终形成:

创建 Template
      ↓
注册 Template
      ↓
Registry
      ↓
Loader
      ↓
Parser
      ↓
Compiler
      ↓
Cache
      ↓
Context
      ↓
TemplateEngine
      ↓
Execute
      ↓
Renderer
      ↓
Rendered Result
      ↓
Adapter
      ↓
External Output

本章核心定义

SATE 自定义模板是开发者按照 SATE 模板语法创建的独立表现模板,可以通过 TemplateRegistry 注册、TemplateLoader 加载、TemplateParser 解析、TemplateCompiler 编译、TemplateCache 缓存,并由 TemplateEngine 在 TemplateContext 中执行,再通过自定义 Renderer 形成表现结果,通过 Adapter 输出到目标环境。

核心关系:

Custom Template
       ↓
TemplateEngine
       ↓
Custom Renderer
       ↓
Custom Adapter
       ↓
Custom Output

最终形成 SATE 的开放结构:

Template
   │
   ├── Syntax
   ├── Context
   ├── Renderer
   └── Adapter

这意味着 SATE 不需要修改核心 Engine,就可以通过新增 Template、Renderer 和 Adapter 扩展表现能力

同时保持最重要的系统边界:

ICAI
 ↓
Cognition
 ↓
Reasoning
 ↓
Decision
 ↓
Behavior
 ↓
Action
 ↓
Expression
 ↓
SATE
 ↓
Template
 ↓
Renderer
 ↓
Adapter
 ↓
Output

SATE 负责表现,不负责认知;自定义模板负责结构,不负责产生智能。

Leave a Reply

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