第80章 自定义 Template
本章大纲
- Template 定义
- Template 创建
- Template 注册
- Template Engine
- Renderer 配合
- Adapter 配合
- 自定义模板实例
1. Template 定义
Template 是 SAI 模板系统中的输出结构定义。
它规定:
- 输出什么结构
- 数据放在哪里
- 属性如何映射
- 条件如何判断
- 数据如何循环
- 不同状态如何显示
- 最终由哪个 Renderer 进行表现转换
Template 本身不负责:
- 感知
- 认知
- 理解
- 推理
- 决策
- 学习
- 设备控制
因此:
Template ≠ Cognition
Template ≠ Reasoning
Template ≠ Decision
Template ≠ Renderer
Template ≠ Adapter
它处于 Expression → SATE → Renderer 之间的结构定义层。
核心关系:
ICAI Result
↓
Expression
↓
Template
↓
SATE Template Engine
↓
Renderer
↓
Rendered Result
可以定义:
Template = Structure + Data Mapping + Condition + Loop + Presentation Rules
2. Template 创建
自定义 Template 首先需要定义模板标识、名称、版本、类型以及模板内容。
例如创建一个设备状态模板:
Template ID:
device_status
Template Name:
Device Status Template
Version:
1.0.0
Type:
device_status
模板内容:
<div class="device-status">
<h2>{{device.name}}</h2>
<p>状态:{{device.state}}</p>
<p>温度:{{device.temperature}}</p>
{{if device.state == "ERROR"}}
<div class="error">
设备异常
</div>
{{else}}
<div class="normal">
设备正常
</div>
{{/if}}
</div>
这里:
{{device.name}}
表示读取:
device → name
而:
{{device.state}}
表示读取:
device → state
条件:
{{if device.state == "ERROR"}}
则由 Template Engine 进行条件判断。
3. Template 注册
创建 Template 后,需要把 Template 注册到 Template Registry。
可以定义:
class TemplateRegistry
{
protected $templates = array();
public function register($template)
{
$id = $template['id'];
$this->templates[$id] = $template;
return true;
}
public function get($id)
{
if (!isset($this->templates[$id])) {
return null;
}
return $this->templates[$id];
}
public function exists($id)
{
return isset($this->templates[$id]);
}
public function remove($id)
{
if (!isset($this->templates[$id])) {
return false;
}
unset($this->templates[$id]);
return true;
}
}
注册数据:
$template = array(
'id' => 'device_status',
'name' => 'Device Status Template',
'version' => '1.0.0',
'type' => 'device_status',
'format' => 'html',
'content' => '<h2>{{device.name}}</h2>'
);
注册:
$registry->register($template);
之后:
$registry->get('device_status');
即可取得模板。
因此:
Template
↓
TemplateRegistry
↓
Registered Template
Registry 负责 记录和查找,并不负责渲染。
4. Template Engine
Template Engine 是 Template 的运行组件。
它负责:
- 加载 Template
- 解析 Template
- 检查变量
- 映射数据
- 判断条件
- 执行循环
- 生成结构化模板结果
基本流程:
Template
↓
Load
↓
Parse
↓
Validate
↓
Data Mapping
↓
Condition
↓
Loop
↓
Render Structure
↓
Template Result
可以定义:
class TemplateEngine
{
protected $registry;
public function __construct($registry)
{
$this->registry = $registry;
}
public function render($templateId, $data)
{
$template = $this->registry->get($templateId);
if ($template === null) {
return array(
'state' => 'FAILED',
'error' => 'Template not found'
);
}
$content = $template['content'];
$content = $this->replaceVariables(
$content,
$data
);
return array(
'state' => 'SUCCESS',
'template' => $templateId,
'output' => $content
);
}
protected function replaceVariables($content, $data)
{
if (isset($data['device']['name'])) {
$content = str_replace(
'{{device.name}}',
$data['device']['name'],
$content
);
}
if (isset($data['device']['state'])) {
$content = str_replace(
'{{device.state}}',
$data['device']['state'],
$content
);
}
return $content;
}
}
这里 Template Engine 做的是确定性的模板处理。
例如:
{{device.name}}
如果数据是:
device.name = Motor_A
结果就是:
Motor_A
Template Engine 不会自己产生:
Motor_B
Motor_C
也不会根据不存在的信息进行推测。
5. Renderer 配合
Template 和 Renderer 是两个不同层次。
Template
负责:
输出结构是什么
Renderer
负责:
结构最终转换成什么表现形式
例如:
Expression
↓
Template
↓
Template Engine
↓
Renderer
↓
Rendered Result
假设 Expression:
$expression = array(
'type' => 'DEVICE_STATE',
'device' => array(
'name' => 'Motor_A',
'state' => 'RUNNING'
)
);
Template:
<div>
<h2>{{device.name}}</h2>
<p>{{device.state}}</p>
</div>
Template Engine 处理后:
<div>
<h2>Motor_A</h2>
<p>RUNNING</p>
</div>
然后交给:
WebRenderer
形成 Web 表现结果。
如果使用:
ApiRenderer
则可以形成:
{
"device": "Motor_A",
"state": "RUNNING"
}
因此,同一个内部 Expression 可以使用不同 Template / Renderer 组合。
核心关系:
Expression
↓
Template
↓
Template Engine
↓
├── WebRenderer
├── ApiRenderer
├── DeviceRenderer
└── CustomRenderer
Template 不决定 Renderer 的具体实现。
6. Adapter 配合
Renderer 负责形成结果以后,还需要 Adapter 将结果连接到具体环境。
因此完整关系是:
Expression
↓
Template
↓
Template Engine
↓
Renderer
↓
Rendered Result
↓
Adapter
↓
External Environment
例如:
ICAI
↓
Expression
↓
Device Status Template
↓
Template Engine
↓
DeviceRenderer
↓
Device Data
↓
DeviceAdapter
↓
External Device System
如果是 Web:
Expression
↓
Web Template
↓
Template Engine
↓
WebRenderer
↓
HTML
↓
WebAdapter
↓
Browser
如果是 API:
Expression
↓
API Template
↓
Template Engine
↓
ApiRenderer
↓
JSON
↓
ApiAdapter
↓
External System
因此三个组件的职责非常明确:
| 组件 | 主要职责 |
|---|---|
| Template | 定义输出结构 |
| Template Engine | 执行模板 |
| Renderer | 转换表现形式 |
| Adapter | 连接外部环境 |
可以进一步表示:
Template
= 怎么组织数据
Renderer
= 表现成什么形式
Adapter
= 发送到什么环境
7. 自定义模板实例
下面建立一个完整的 设备状态自定义模板。
7.1 Expression
首先 ICAI 已经产生结构化结果:
$expression = array(
'id' => 'exp_001',
'type' => 'DEVICE_STATE',
'device' => array(
'id' => 'device_001',
'name' => 'Motor_A',
'state' => 'RUNNING',
'temperature' => 65
)
);
这是已经存在的内部数据。
Template 不负责产生这些数据。
7.2 创建 Template
定义:
$template = array(
'id' => 'device_status',
'name' => 'Device Status',
'version' => '1.0.0',
'type' => 'DEVICE_STATE',
'format' => 'html',
'content' => '
<div class="device">
<h2>{{device.name}}</h2>
<p>
状态:
{{device.state}}
</p>
<p>
温度:
{{device.temperature}}℃
</p>
{{if device.state == "ERROR"}}
<div>
设备异常
</div>
{{else}}
<div>
设备运行正常
</div>
{{/if}}
</div>
'
);
7.3 注册 Template
$registry = new TemplateRegistry();
$registry->register($template);
此时:
Template Registry
│
└── device_status
7.4 Template Engine 执行
$engine = new TemplateEngine($registry);
$result = $engine->render(
'device_status',
$expression
);
Engine 获取:
device.name
device.state
device.temperature
并按照 Template 的结构进行映射。
结果类似:
<div class="device">
<h2>Motor_A</h2>
<p>
状态:
RUNNING
</p>
<p>
温度:
65℃
</p>
<div>
设备运行正常
</div>
</div>
7.5 Renderer
接下来:
Template Result
↓
WebRenderer
↓
Rendered Result
WebRenderer 负责把模板结果作为 Web 表现结构处理。
最终:
HTML
7.6 Adapter
最后:
HTML
↓
WebAdapter
↓
HTTP
↓
Browser
于是完整链路:
ICAI
↓
Expression
↓
Custom Template
↓
Template Engine
↓
WebRenderer
↓
HTML
↓
WebAdapter
↓
Browser
本章核心模型
第80章建立了自定义 Template 与 SAI 其他组件之间的完整关系:
ICAI
│
↓
Expression
│
↓
Custom Template
│
↓
Template Engine
│
↓
Render Structure
│
↓
Renderer
│
↓
Rendered Result
│
↓
Adapter
│
↓
External Environment
核心职责:
Template
↓
定义输出结构
Template Engine
↓
执行模板结构
Renderer
↓
转换表现形式
Adapter
↓
连接外部环境
因此:
Template ≠ Template Engine
Template ≠ Renderer
Template ≠ Adapter
四者共同形成 SAI 的结构化输出机制:
Expression
↓
Template
↓
Template Engine
↓
Renderer
↓
Adapter
↓
External Output
整个过程是确定性的结构处理与输出转换,不承担认知、推理、决策和学习功能。