Appearance
ThinkDH 模板开发文档
目录
- 模板开发概述
- 设计理念
- 应用场景
- 开发规范
- HTML标签规范
- 支持的自定义HTML标签
- 标签属性说明
- 标签嵌套规则
- 模板使用指南
- 模板创建步骤
- 模板引用、继承和复用
- 变量使用、条件判断、循环等模板语法说明
- 配置文件说明
- 所有配置项的详细说明
- 配置文件的加载顺序和优先级规则
- 示例模板
- 基础模板示例
- 复杂嵌套模板示例
- 动态数据绑定模板示例
- 示例配置文件
- 不同场景的配置示例
- 完整配置文件示例
1. 模板开发概述
1.1 设计理念
ThinkDH 模板系统采用了分离设计理念,将模板的结构、样式、配置和业务逻辑完全分离,使模板开发者可以专注于模板的设计和功能实现,而不需要关心系统层面的配置处理。
核心设计理念包括:
- 配置驱动:通过
config.json文件定义模板的配置项,系统自动生成可视化的配置表单 - 模块化:支持组件化开发,模板可以包含多个独立的组件
- 灵活性:模板开发者可以自由定义模板的结构和样式
- 可扩展性:支持自定义配置项,满足不同模板的个性化需求
- 易于使用:提供简洁明了的模板语法,降低开发门槛
1.2 应用场景
ThinkDH 模板系统适用于以下场景:
- 网站首页定制:通过模板系统可以快速定制网站首页的布局和内容
- 分类页面定制:为不同的分类页面创建不同的模板
- 专题页面创建:快速创建各种专题页面,如活动页面、推广页面等
- 多语言支持:通过模板配置可以实现多语言支持
- 个性化展示:根据不同的用户群体展示不同的内容
1.3 开发规范
模板开发应遵循以下规范:
- 目录结构:模板文件应按照规定的目录结构组织
- 文件命名:文件名应使用小写字母和下划线,避免使用特殊字符
- 代码规范:HTML代码应遵循标准的HTML5规范,保持代码整洁
- 性能优化:模板应考虑性能优化,避免过多的嵌套和复杂的逻辑
- 安全性:模板代码应注意安全性,避免XSS等安全问题
- 兼容性:模板应考虑不同浏览器的兼容性
2. HTML标签规范
2.1 支持的自定义HTML标签
ThinkDH 模板系统支持以下自定义HTML标签:
| 标签名 | 描述 | 用途 |
|---|---|---|
{volist} | 循环标签 | 用于遍历数组数据 |
{if} | 条件判断标签 | 用于条件判断 |
{else} | 条件判断标签 | 用于条件判断的else分支 |
{elseif} | 条件判断标签 | 用于条件判断的elseif分支 |
{/if} | 条件判断标签 | 用于结束条件判断 |
{php} | PHP代码标签 | 用于执行PHP代码 |
{$variable} | 变量输出标签 | 用于输出变量值 |
2.2 标签属性说明
{volist} 标签属性
| 属性名 | 类型 | 必填 | 默认值 | 描述 | |-------|------|--------|------| | name | string | 是 | 无 | 要遍历的变量名 | | id | string | 否 | 无 | 循环体中的变量名 | | offset | number | 否 | 0 | 起始偏移量 | | length | number | 否 | 无 | 循环长度 | | key | string | 否 | 无 | 循环的键名 | | mod | string | 否 | 无 | 取模运算 |
{if} 标签属性
| 属性名 | 类型 | 必填 | 默认值 | 描述 | |-------|------|--------|------| | condition | string | 是 | 无 | 条件表达式 |
2.3 标签嵌套规则
标签嵌套应遵循以下规则:
{volist}标签可以嵌套其他标签,包括{if}、{volist}等{if}标签可以嵌套其他标签,包括{if}、{volist}等- 标签必须正确闭合,如
{if}...{/if}、{volist}...{/volist} - 嵌套层次不宜过深,建议不超过3层,以保证模板的可读性和性能
3. 模板使用指南
3.1 模板创建步骤和最佳实践
模板创建步骤
- 创建模板目录:在
template目录下创建一个新的目录,作为模板的根目录 - 创建配置文件:在模板根目录下创建
config.json文件,定义模板的配置项 - 创建HTML文件:在模板根目录下创建
html目录,并在其中创建HTML文件 - 创建组件文件:在模板根目录下创建
components目录,并在其中创建组件文件 - 创建静态资源:在模板根目录下创建
css、js、img等目录,存放静态资源
最佳实践
- 模块化设计:将模板拆分为多个组件,提高代码的可维护性和复用性
- 配置驱动:充分利用
config.json文件,使模板具有更大的灵活性 - 性能优化:减少模板中的复杂逻辑,避免过多的嵌套
- 代码规范:保持代码整洁,添加必要的注释
- 测试:在开发过程中及时测试模板的效果
3.2 模板引用、继承和复用的具体方法
模板引用
在模板中引用其他模板文件:
html
{include file="template/dev/components/header.html"}模板继承
ThinkDH 模板系统支持模板继承,通过以下方式实现:
- 定义基础模板:创建一个基础模板文件,包含公共部分
- 继承基础模板:在子模板中继承基础模板,并覆盖需要修改的部分
模板复用
模板复用可以通过以下方式实现:
- 组件化:将重复使用的部分封装为组件,在多个模板中引用
- 配置化:通过配置文件控制模板的行为,实现模板的复用
- 变量化:使用变量代替硬编码的值,提高模板的复用性
3.3 变量使用、条件判断、循环等模板语法说明
变量使用
在模板中使用变量:
html
{$variable} <!-- 输出变量值 -->
{$thinkdh.path_tpl} <!-- 输出系统变量 -->
{$templateConfig.speaker.notice} <!-- 输出配置变量 -->条件判断
在模板中使用条件判断:
html
{if condition="$templateConfig.home.components['dating-zone']"}
<!-- 条件为真时显示的内容 -->
{else}
<!-- 条件为假时显示的内容 -->
{/if}
{if condition="$app.status == 1"}
<!-- 条件为真时显示的内容 -->
{elseif condition="$app.status == 2"}
<!-- 条件为真时显示的内容 -->
{else}
<!-- 条件为假时显示的内容 -->
{/if}循环
在模板中使用循环:
html
{volist name="templateConfig.banner" id="banner"}
<div class="swiper-slide">
<a href="{$banner.url}" target="_blank">
<img src="{$banner.img}" alt="">
</a>
</div>
{/volist}PHP代码执行
在模板中执行PHP代码:
html
{php}echo rand(100, 200);{/php}4. 配置文件说明
4.1 配置文件的标准格式和存储路径
配置文件格式
配置文件采用JSON格式,包含以下两部分:
_config:定义配置项的元数据,包括字段类型、标签、描述等- 根级别配置:定义配置项的默认值
存储路径
配置文件存储在模板根目录下,路径为:
template/{template_id}/config.json其中 {template_id} 是模板的唯一标识,如 dev、default 等。
4.2 所有配置项的详细说明
配置文件结构
配置文件的基本结构如下:
json
{
"_config": {
"group1": {
"label": "配置组标签",
"description": "配置组描述",
"fields": {
"field1": {
"label": "字段标签",
"type": "字段类型",
"description": "字段描述",
"required": true,
"default": "默认值"
}
}
},
"group1": {
"field1": "默认值"
}
}
}支持的字段类型
| 类型 | 描述 | 用途 |
|---|---|---|
text | 文本输入框 | 用于输入单行文本 |
textarea | 文本域 | 用于输入多行文本 |
number | 数字输入框 | 用于输入数字 |
boolean | 布尔开关 | 用于开启/关闭某个功能 |
array | 数组 | 用于存储多个值 |
object | 对象 | 用于存储复杂结构的数据 |
image | 图片上传 | 用于上传图片 |
配置项说明
| 配置项 | 类型 | 默认值 | 用途 |
|---|---|---|---|
speaker | object | {} | 公告设置 |
speaker.notice | string | "" | 公告内容 |
speaker.down | string | "" | 下载链接 |
banner | array | [] | 轮播图配置 |
banner[].id | string | "" | 轮播图ID |
banner[].url | string | "" | 轮播图链接 |
banner[].img | string | "" | 轮播图图片 |
options | object | {} | 选项设置 |
options.price | array | [] | 价格选项 |
options.service | array | [] | 服务选项 |
options.project | array | [] | 项目选项 |
subtitle | array | [] | 副标题设置 |
lf | object | {} | 随机数据设置 |
lf.like | object | {} | 点赞数范围 |
lf.like.min | number | 0 | 最小点赞数 |
lf.like.max | number | 0 | 最大点赞数 |
lf.add | object | {} | 添加数范围 |
lf.add.min | number | 0 | 最小添加数 |
lf.add.max | number | 0 | 最大添加数 |
home | object | {} | 首页设置 |
home.components | object | {} | 组件设置 |
home.components.dating-zone | boolean | false | 是否显示同城约会组件 |
categories | array | [] | 分类设置 |
categories[].id | number | 0 | 分类ID |
categories[].name | string | "" | 分类名称 |
categories[].icon | string | "" | 分类图标 |
categories[].components | object | {} | 分类组件设置 |
4.3 配置文件的加载顺序和优先级规则
配置文件的加载顺序和优先级如下:
- 默认配置:系统首先加载模板目录下的
config.json文件 - 用户配置:然后加载用户在后台修改后的配置
- 运行时配置:最后加载运行时生成的配置
- 优先级:运行时配置 > 用户配置 > 默认配置
5. 示例模板
5.1 基础模板示例
首页基础模板
html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{$title}</title>
<link rel="stylesheet" href="{$thinkdh.path_tpl}css/home.css">
<script src="{$thinkdh.path_tpl}js/rem.min.js"></script>
</head>
<body>
<div id="app">
<!-- 公告区域 -->
<div class="marquee-wrap">
<div class="marquee-box">
<div class="icon-speaker"></div>
<div class="container-main">
<p>{$templateConfig.speaker.notice}</p>
</div>
<a href="{$templateConfig.speaker.down}" target="_blank" class="btn-more">下载APP</a>
</div>
</div>
<!-- 轮播图 -->
<div id="swiper-banner" class="swiper">
<div class="swiper-wrapper">
{volist name="templateConfig.banner" id="banner"}
<div class="swiper-slide">
<a href="{$banner.url}" target="_blank">
<img src="{$banner.img}" alt="">
</a>
</div>
{/volist}
</div>
<div class="swiper-pagination"></div>
</div>
<!-- 导航 -->
<div class="nav-c">
<div class="item active">
<em>全部</em>
</div>
{volist name="templateConfig.categories" id="vo"}
<div class="item">
<em>{$vo.name}</em>
</div>
{/volist}
</div>
<!-- 内容区域 -->
<div class="content">
<!-- 内容区域 -->
</div>
</div>
<script src="{$thinkdh.path_tpl}js/swiper-bundle.min.js"></script>
<script>
// 初始化轮播图
var swiper = new Swiper('#swiper-banner', {
pagination: {
el: '.swiper-pagination',
},
autoplay: {
delay: 3000,
disableOnInteraction: false,
},
});
</script>
</body>
</html>5.2 复杂嵌套模板示例
分类页面模板
html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{$title}</title>
<link rel="stylesheet" href="{$thinkdh.path_tpl}css/home.css">
<script src="{$thinkdh.path_tpl}js/rem.min.js"></script>
</head>
<body>
<div id="app">
<!-- 导航 -->
<div class="nav-c">
<div class="item active">
<em>全部</em>
</div>
{volist name="templateConfig.categories" id="vo"}
<div class="item">
<em>{$vo.name}</em>
</div>
{/volist}
</div>
<!-- 分类内容 -->
<div class="swiper-c">
<div class="swiper-wrapper">
<!-- 全部部分类 -->
<div class="swiper-slide">
<div>
<div>官方推荐 <span class="f-title"> Recommend </span></div>
</div>
</div>
<div class="grid-cols-5">
{volist name="recommendApps[1]" id="app"}
<a class="grid-item" href="{$app.url}" target="_blank">
<img src="{$app.img}" alt="{$app.name}">
<div class="text">{$app.name}</div>
<div class="jgg-load">进入</div>
</a>
{/volist}
</div>
</div>
</div>
<!-- 各个分类 -->
{volist name="templateConfig.categories" id="category"}
<div class="swiper-slide">
<div>
<div>{$category.name} <span class="f-title"> Category </span></div>
</div>
<div class="grid-cols-5">
{volist name="categoryApps[$category.id]" id="app"}
<a class="grid-item" href="{$app.url}" target="_blank">
<img src="{$app.img}" alt="{$app.name}">
<div class="text">{$app.name}</div>
<div class="jgg-load">进入</div>
</a>
{/volist}
</div>
</div>
<!-- 同城约会组件 -->
{if condition="$category.components['dating-zone']"}
<div class="lf title-item">
<div>
<div>同城约会 <span class="f-title"> DatingZone </span></div>
</div>
</div>
<div class="zone-wrap">
{volist name="categoryApps[4]" id="app"}
<a class="zone-item" href="{$app.url}" target="_blank">
<img src="{$app.img}" alt="">
<div class="zone1-text-wrap">
<p class="zone1-item-name-wrap">
<span class="zone1-item-name">{$app.name}</span>
<span class="zone1-item-color1">
{php}echo $templateConfig['subtitle'][array_rand($templateConfig['subtitle'])];{/php}
</span>
</p>
</div>
</a>
{/volist}
</div>
{/if}
</div>
{/volist}
</div>
</div>
</div>
<script src="{$thinkdh.path_tpl}js/swiper-bundle.min.js"></script>
<script>
// 初始化分类轮播
var swiper = new Swiper('.swiper-c', {
slidesPerView: 1,
spaceBetween: 0,
freeMode: true,
});
</script>
</body>
</html>5.3 动态数据绑定模板示例
动态内容模板
html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{$title}</title>
<link rel="stylesheet" href="{$thinkdh.path_tpl}css/home.css">
<script src="{$thinkdh.path_tpl}js/rem.min.js"></script>
</head>
<body>
<div id="app">
<!-- 随机数据展示 -->
<div class="lf title-item">
<div>
<div>关注我们 <span class="f-title"> Stay in care </span></div>
</div>
</div>
<div class="zp-wrap">
{volist name="categoryApps[5]" id="app"}
<div class="zp-wrap-item">
<a href="{$app.url}" target="_blank">
<div class="item-s4">
<div class="header">
<div class="cover">
<img src="{$app.img}" alt="">
</div>
</div>
<div class="flex-1">
<div class="name">{$app.name}</div>
<div class="flex flex-middle">
<div class="icon-address"></div>
距离 {php}echo rand($templateConfig['lf']['add']['min'], $templateConfig['lf']['add']['max']);{/php}km
</div>
</div>
<div class="btn-detail">查看详细信息</div>
</div>
<div class="fc-gray">
{$app.description|default=''}
</div>
</div>
</a>
</div>
{/volist}
</div>
<!-- 价格和服务选项 -->
<div class="gt title-item">
<div>
<div>价格和服务 <span class="f-title"> Price & Service </span></div>
</div>
</div>
<div class="options-wrap">
<div class="options-item">
<h3>价格选项</h3>
<ul>
{volist name="templateConfig.options.price" id="price"}
<li>{$price}</li>
{/volist}
</ul>
</div>
<div class="options-item">
<h3>服务选项</h3>
<ul>
{volist name="templateConfig.options.service" id="service"}
<li>{$service}</li>
{/volist}
</ul>
</div>
</div>
</div>
</body>
</html>6. 示例配置文件
6.1 完整配置文件示例
基础配置文件示例
json
{
"_config": {
"speaker": {
"label": "公告设置",
"description": "公告和下载链接设置",
"fields": {
"notice": {
"label": "公告",
"type": "textarea",
"description": "网站公告内容",
"required": true
},
"down": {
"label": "下载链接",
"type": "text",
"description": "应用下载链接",
"required": true
}
}
},
"banner": {
"label": "轮播设置",
"description": "首页轮播图配置",
"type": "array",
"itemFields": {
"id": {
"label": "ID",
"type": "text",
"description": "轮播图ID"
},
"url": {
"label": "链接",
"type": "text",
"description": "轮播图点击链接"
},
"img": {
"label": "图片",
"type": "image",
"description": "轮播图图片"
}
}
},
"options": {
"label": "选项设置",
"description": "价格和服务选项配置",
"fields": {
"price": {
"label": "价格选项",
"type": "array",
"itemType": "text",
"description": "价格选项列表"
},
"service": {
"label": "服务选项",
"type": "array",
"itemType": "text",
"description": "服务选项列表"
},
"project": {
"label": "项目选项",
"type": "array",
"itemType": "text",
"description": "项目选项列表"
}
}
},
"subtitle": {
"label": "副标题设置",
"description": "副标题配置",
"type": "array",
"itemType": "text",
"description": "副标题列表"
},
"lf": {
"label": "随机数据设置",
"description": "随机数据生成配置",
"fields": {
"like": {
"label": "点赞数范围",
"type": "object",
"fields": {
"min": {
"label": "最小值",
"type": "number",
"description": "点赞数最小值"
},
"max": {
"label": "最大值",
"type": "number",
"description": "点赞数最大值"
}
}
},
"add": {
"label": "添加数范围",
"type": "object",
"fields": {
"min": {
"label": "最小值",
"type": "number",
"description": "添加数最小值"
},
"max": {
"label": "最大值",
"type": "number",
"description": "添加数最大值"
}
}
}
}
},
"home": {
"label": "首页设置",
"description": "首页组件显示配置",
"fields": {
"components": {
"label": "组件设置",
"type": "object",
"fields": {
"dating-zone": {
"label": "同城组件",
"type": "boolean",
"description": "是否显示同城约会组件"
},
"s-wrap": {
"label": "卡片组件",
"type": "boolean",
"description": "是否显示卡片组件"
}
}
}
}
},
"categories": {
"label": "分类设置",
"description": "网站分类配置",
"type": "array",
"itemFields": {
"id": {
"label": "分类ID",
"type": "number",
"description": "分类唯一标识"
},
"name": {
"label": "分类名称",
"type": "text",
"description": "分类显示名称"
},
"icon": {
"label": "分类图标",
"type": "text",
"description": "分类图标路径"
},
"components": {
"label": "组件设置",
"type": "object",
"fields": {
"dating-zone": {
"label": "同城组件",
"type": "boolean",
"description": "是否显示同城约会组件"
}
}
}
}
}
},
"speaker": {
"notice": "欢迎使用ThinkDH模板系统!",
"down": "https://thinkdh.com"
},
"banner": [
{
"id": "1",
"url": "https://thinkdh.com",
"img": "https://appimg-drcn.dbankcdn.com/application/screenshut1/619076b692a54c0483b3266bf8edfdb4.jpg"
},
{
"id": "2",
"url": "https://thinkdh.com",
"img": "https://appimg-drcn.dbankcdn.com/application/screenshut1/619076b692a54c0483b3266bf8edfdb4.jpg"
}
],
"options": {
"price": [
"1200/C 2000/Y",
"1800/C 2000/Y"
],
"service": [
"介绍相亲 上门提亲",
"在线预约 线下面谈"
],
"project": [
"全场督办 相亲 婚礼",
"酒席 婚礼 潦队"
]
},
"subtitle": [
"(168/45kg/D)",
"(168/51kg/C)"
],
"lf": {
"like": {
"min": 666,
"max": 3000
},
"add": {
"min": 10,
"max": 20
}
},
"home": {
"banner": 1,
"notice": 1,
"components": {
"dating-zone": 1,
"s-wrap": 1
}
},
"categories": [
{
"id": 1,
"name": "视频",
"icon": "",
"components": {
"dating-zone": 1,
"s-wrap": 1
}
},
{
"id": 2,
"name": "直播",
"icon": "",
"components": {
"dating-zone": 1,
"s-wrap": 1
}
},
{
"id": 3,
"name": "交友",
"icon": "",
"components": {
"dating-zone": 1,
"s-wrap": 1
}
},
{
"id": 4,
"name": "同城",
"icon": "",
"components": {
"dating-zone": 1,
"s-wrap": 1
}
},
{
"id": 5,
"name": "游戏",
"icon": "",
"components": {
"dating-zone": 1,
"s-wrap": 1
}
},
{
"id": 6,
"name": "阅读",
"icon": "",
"components": {
"dating-zone": 1,
"s-wrap": 1
}
}
]
}6.2 不同场景的配置示例
多语言配置示例
json
{
"_config": {
"language": {
"label": "语言设置",
"description": "多语言支持配置",
"fields": {
"default": {
"label": "默认语言",
"type": "text",
"description": "默认语言代码,如 zh-CN, en-US 等"
},
"supported": {
"label": "支持的语言",
"type": "array",
"itemType": "text",
"description": "支持的语言代码列表"
}
}
}
},
"translations": {
"zh-CN": {
"title": "ThinkDH 官方网站",
"description": "ThinkDH 是一个企业级应用导航系统"
},
"en-US": {
"title": "ThinkDH Official Website",
"description": "ThinkDH is an enterprise application navigation system"
}
},
"language": {
"default": "zh-CN",
"supported": ["zh-CN", "en-US"]
}
}专题页面配置示例
json
{
"_config": {
"topic": {
"label": "专题设置",
"description": "专题页面配置",
"fields": {
"title": {
"label": "专题标题",
"type": "text",
"description": "专题页面标题"
},
"description": {
"label": "专题描述",
"type": "textarea",
"description": "专题页面描述"
},
"banner": {
"label": "专题 banner",
"type": "image",
"description": "专题页面顶部 banner"
},
"items": {
"label": "专题内容",
"type": "array",
"itemFields": {
"title": {
"label": "项目标题",
"type": "text",
"description": "项目标题"
},
"image": {
"label": "项目图片",
"type": "image",
"description": "项目图片"
},
"description": {
"label": "项目描述",
"type": "textarea",
"description": "项目描述"
},
"url": {
"label": "项目链接",
"type": "text",
"description": "项目链接"
}
}
}
}
}
},
"topic": {
"title": "2026 新年专题",
"description": "庆祝 2026 新年,推出多项优惠活动",
"banner": "https://example.com/2026-new-year.jpg",
"items": [
{
"title": "优惠活动 1",
"image": "https://example.com/item1.jpg",
"description": "活动详情 1",
"url": "https://example.com/event1"
},
{
"title": "优惠活动 2",
"image": "https://example.com/item2.jpg",
"description": "活动详情 2",
"url": "https://example.com/event2"
}
]
}
}7. 总结
ThinkDH 模板系统是一个功能强大、灵活易用的模板开发系统,通过配置文件驱动的方式,使模板开发者可以快速创建各种类型的模板。本文档详细介绍了模板系统的设计理念、使用方法和最佳实践,希望能够帮助开发人员快速理解并正确使用模板系统。
如果您在使用过程中遇到任何问题,请参考本文档或联系技术支持。
文档版本:1.0
更新日期:2026-02-10
作者:ThinkDH 开发团队