yangweijie / think-stempler
Stempler Template Engine Driver for ThinkPHP 8.0
Fund package maintenance!
yangweijie
v0.9.0
2025-06-26 13:02 UTC
Requires
- php: >=8.0.0
- spiral/stempler: ^3.15
- topthink/think-view: ^2.0.4
Requires (Dev)
- mockery/mockery: ^1.4
- pestphp/pest: ^2.36
Suggests
- topthink/framework: ThinkPHP Framework for full integration
README
基于 Spiral Stempler 核心功能的 ThinkPHP 模板引擎扩展,提供现代化的模板特性。
🚀 特性
✅ 完全实现的功能
- 基本语法: 变量输出、转义控制、注释
- 指令系统: 条件、循环、判断、工具指令
- 布局继承: 完整的模板继承系统
- 栈系统: 强大的内容栈管理
- 组件系统: 可复用的 UI 组件
- ThinkPHP 集成: 完全兼容 ThinkPHP 框架
🎯 性能表现
- 渲染速度: 平均 1-2ms
- 内存使用: 优化的临时文件执行
- 安全性: 移除 eval,使用安全的文件执行
- 缓存机制: 智能的编译缓存
📦 安装
composer require yangweijie/think-stempler
🔧 配置
在 ThinkPHP 配置文件中添加:
// config/view.php return [ 'type' => 'Stempler', 'view_path' => app()->getRootPath() . 'view' . DIRECTORY_SEPARATOR, 'cache_path' => app()->getRuntimePath() . 'temp' . DIRECTORY_SEPARATOR, 'view_suffix' => '.dark.php', 'tpl_cache' => true, // Stempler 特性开关 'enable_layout' => true, 'enable_stack' => true, 'enable_component' => true, ];
📖 基本语法
变量输出
<!-- 自动转义输出 --> <h1>{{ $title }}</h1> <p>用户: {{ $user ?? '访客' }}</p> <!-- 原始输出(不转义) --> <div>{!! $htmlContent !!}</div> <!-- 转义 @ 符号 --> <p>邮箱格式: user@@domain.com</p>
条件指令
@if($user) <p>欢迎,{{ $user->name }}!</p> @elseif($guest) <p>欢迎,访客!</p> @else <p>请登录</p> @endif @unless($errors) <p>操作成功</p> @endunless @empty($items) <p>暂无数据</p> @endempty @isset($user->email) <p>邮箱: {{ $user->email }}</p> @endisset
循环指令
@foreach($users as $user) <div class="user"> <h3>{{ $user->name }}</h3> <p>{{ $user->email }}</p> </div> @endforeach @for($i = 1; $i <= 10; $i++) <span>{{ $i }}</span> @endfor @while($condition) <!-- 循环内容 --> @break @continue @endwhile
选择指令
@switch($status) @case('active') <span class="badge badge-success">活跃</span> @break @case('inactive') <span class="badge badge-warning">非活跃</span> @break @default <span class="badge badge-secondary">未知</span> @endswitch
工具指令
<!-- JSON 输出 --> <script> var config = @json($config); var users = @json($users); </script> <!-- PHP 代码 --> @php $computed = $price * $quantity; $total = number_format($computed, 2); @endphp <p>总计: {{ $total }}</p>
🏗️ 布局继承
定义布局
<!-- layout/base.dark.php --> <!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <title><block:title>默认标题</block:title></title> <block:head> <meta name="viewport" content="width=device-width, initial-scale=1.0"> </block:head> </head> <body> <header> <h1>网站头部</h1> <nav><block:nav>默认导航</block:nav></nav> </header> <main> <block:content> <p>默认内容</p> </block:content> </main> <footer> <p>网站底部</p> </footer> </body> </html>
继承布局
<!-- page/index.dark.php --> <extends:layout.base/> <block:title>首页 - 我的网站</block:title> <block:head> <block:parent/> <link rel="stylesheet" href="/css/home.css"> </block:head> <block:nav> <a href="/">首页</a> <a href="/about">关于</a> <a href="/contact">联系</a> </block:nav> <block:content> <h2>欢迎来到首页</h2> <p>这是首页内容</p> </block:content>
📚 栈系统
栈系统允许你在模板的任何地方推送内容,然后在指定位置收集和渲染。
收集栈内容
<!-- 在布局中定义栈收集点 --> <head> <stack:collect name="styles"> <link rel="stylesheet" href="/css/app.css"> </stack:collect> </head> <body> <!-- 页面内容 --> <stack:collect name="scripts"> <script src="/js/app.js"></script> </stack:collect> </body>
推送到栈
<!-- 在任何模板中推送内容 --> <stack:push name="styles"> <link rel="stylesheet" href="/css/page.css"> </stack:push> <stack:prepend name="styles"> <link rel="stylesheet" href="/css/reset.css"> </stack:prepend> <stack:push name="scripts"> <script src="/js/page.js"></script> </stack:push>
渲染顺序
<stack:prepend>
: 添加到栈顶(最先渲染)- 默认内容: 中间渲染
<stack:push>
: 添加到栈底(最后渲染)
🧩 组件系统
内置组件
Alert 组件
<ui:alert type="success" message="操作成功!"/> <ui:alert type="error" message="操作失败!"/> <ui:alert type="warning" message="请注意!"/>
Card 组件
<ui:card title="用户信息" class="user-card"> <p>姓名: {{ $user->name }}</p> <p>邮箱: {{ $user->email }}</p> </ui:card>
Button 组件
<ui:button type="submit" class="btn btn-primary" onclick="submitForm()"> 提交 </ui:button>
Input 组件
<ui:input type="text" name="username" placeholder="请输入用户名" class="form-control"/> <ui:input type="email" name="email" value="{{ $user->email }}" class="form-control"/>
Modal 组件
<ui:modal id="userModal" title="编辑用户" size="lg"> <form> <div class="form-group"> <label>用户名:</label> <ui:input type="text" name="username" class="form-control"/> </div> <div class="form-actions"> <ui:button type="submit" class="btn btn-primary">保存</ui:button> </div> </form> </ui:modal>
Table 组件
<ui:table striped bordered class="data-table"> <thead> <tr> <th>ID</th> <th>姓名</th> <th>邮箱</th> </tr> </thead> <tbody> @foreach($users as $user) <tr> <td>{{ $user->id }}</td> <td>{{ $user->name }}</td> <td>{{ $user->email }}</td> </tr> @endforeach </tbody> </ui:table>
自定义组件
你可以注册自定义组件:
// 在控制器或服务中 $engine = app('view')->getEngine(); $engine->registerComponent('my-component', function($attributes, $content) { return "<div class='my-component'>{$content}</div>"; });
🎮 控制器使用
基本使用
<?php namespace app\controller; use think\Controller; class Index extends Controller { public function index() { $data = [ 'title' => '首页', 'users' => [ ['name' => '张三', 'email' => 'zhangsan@example.com'], ['name' => '李四', 'email' => 'lisi@example.com'], ] ]; return view('index', $data); } }
使用布局
public function profile() { $user = $this->getUser(); return view('user/profile', [ 'user' => $user, 'pageTitle' => '个人资料', 'breadcrumbs' => ['首页', '用户中心', '个人资料'] ]); }
🔧 高级配置
组件路径
// config/view.php return [ 'type' => 'Stempler', 'component_path' => app()->getRootPath() . 'view/components/', // 其他配置... ];
功能开关
// 禁用某些功能 return [ 'type' => 'Stempler', 'enable_layout' => true, // 布局继承 'enable_stack' => true, // 栈系统 'enable_component' => false, // 组件系统(如果不需要) ];
🚀 性能优化
启用缓存
return [ 'type' => 'Stempler', 'tpl_cache' => true, 'cache_path' => app()->getRuntimePath() . 'temp/', ];
生产环境优化
return [ 'type' => 'Stempler', 'tpl_cache' => true, 'view_debug' => false, 'strip_space' => true, // 移除多余空白 ];
🐛 调试
启用调试模式
return [ 'type' => 'Stempler', 'view_debug' => true, ];
查看编译后的代码
$engine = app('view')->getEngine(); $compiled = $engine->compile($templateContent, $templateFile); echo $compiled;
📝 更新日志
v2.0.0 (2024-06-26)
- 🎉 完全重构,基于 Spiral Stempler 设计理念
- ✨ 新增布局继承系统
- ✨ 新增栈系统
- ✨ 新增组件系统
- 🚀 性能大幅提升
- 🔒 安全性增强
- 📚 完善的文档
📄 许可证
MIT License
🤝 贡献
欢迎提交 Issue 和 Pull Request!
📞 支持
如有问题,请提交 Issue 或联系维护者。