8.集成模板引擎

原文地址: 集成模板引擎 更多内容请关注:php代码框架

选择模板引擎

Twig 是一个现代的、灵活且强大的 PHP 模板引擎,具有清晰的语法和丰富的功能,广泛应用于 Symfony 等框架中。除了 Twig,还可以考虑 Blade(Laravel 的模板引擎)或 Smarty 等其他模板引擎。本文以 Twig 为例进行说明。

通过 Composer 安装 Twig

首先,使用 Composer 安装 Twig。确保项目已经初始化为一个 Composer 项目(即存在 composer.json 文件)。

步骤:

  1. 安装 Twig

    在项目根目录下运行以下命令安装 Twig:

    复制代码
    composer require twig/twig
  2. 更新自动加载

    安装完成后,Composer 会自动更新 vendor/autoload.php,无需额外操作。

配置模板目录

为了组织模板文件,在项目中创建一个专门的 views 目录,用于存放所有的视图模板。

步骤:

  1. 创建 views 目录

    在项目根目录下创建 views/ 目录:

    复制代码
    mkdir views
  2. 组织模板文件

    根据项目需求,在 views/ 目录下创建子目录和模板文件。例如:

    复制代码
    my_framework/
    ├── composer.json
    ├── composer.lock
    ├── vendor/
    ├── index.php
    ├── src/
    │   ├── Router.php
    │   └── Controller.php
    ├── src/Controllers/
    │   ├── HomeController.php
    │   └── UsersController.php
    ├── views/
    │   ├── home/
    │   │   └── index.html.twig
    │   ├── users/
    │   │   ├── list.html.twig
    │   │   └── show.html.twig
    │   └── auth/
    │       ├── login.html.twig
    │       └── register.html.twig
    └── logs/
        └── app.log

更新 Controller 类以支持模板渲染

为了简化视图渲染过程,在基础 Controller 类中集成 Twig 的渲染功能。

步骤:

  1. 导入 Twig 类

    Controller.php 中,导入 Twig 的相关类:

    复制代码
    <?php
    use TwigEnvironment;
    use TwigLoaderFilesystemLoader;
  2. 初始化 Twig 环境

    Controller 类的构造函数中初始化 Twig:

    复制代码
    <?php
    class Controller
    {
        protected $twig;
    
        public function __construct()
        {
            $loader = new FilesystemLoader(__DIR__ . '/../views');
            $this->twig = new Environment($loader, [
                'cache' => __DIR__ . '/../../cache/twig',
                'debug' => true,
            ]);
        }
    
        /**
         * 渲染模板
         *
         * @param string $template 模板文件路径(相对于 views 目录)
         * @param array $data 传递给模板的数据
         */
        protected function render($template, $data = [])
        {
            echo $this->twig->render($template, $data);
        }
    }

    说明:

    • FilesystemLoader:指定模板文件所在的目录。

    • Environment:Twig 的核心类,负责渲染模板。可配置缓存和调试选项。

    • render 方法:在控制器中调用此方法即可渲染指定的模板,并传递数据。

  3. 创建缓存目录(可选)

    为了提高渲染性能,可以启用 Twig 的缓存功能。创建一个 cache/twig/ 目录并确保 PHP 有写入权限:

    复制代码
    mkdir -p cache/twig
    chmod 755 cache/twig

创建视图模板

views/ 目录下创建 Twig 模板文件,定义页面的结构和内容。

示例:

  1. 主页模板 views/home/index.html.twig

    复制代码
    <!DOCTYPE html>
    <html lang="zh">
    <head>
        <meta charset="UTF-8">
        <title>主页</title>
    </head>
    <body>
        <h1>欢迎来到主页!</h1>
        <p><a href="{{ path('users.list') }}">查看用户列表</a></p>
    </body>
    </html>
  2. 用户列表模板 views/users/list.html.twig

    复制代码
    <!DOCTYPE html>
    <html lang="zh">
    <head>
        <meta charset="UTF-8">
        <title>用户列表</title>
    </head>
    <body>
        <h1>用户列表</h1>
        <ul>
            {% for user in users %}
                <li><a href="{{ path('users.show', {'id': user.id}) }}">{{ user.name }}</a> ({{ user.email }})</li>
            {% endfor %}
        </ul>
    </body>
    </html>

    说明:

    • 模板变量:使用 {``{ }} 来输出变量值。

    • 控制结构:使用 {% for %} 来循环渲染用户列表。

    • 反向路由:假设已实现 path 函数用于生成 URL(详见下文)。

在控制器中渲染视图

在具体的控制器方法中,调用 render 方法来渲染对应的模板,并传递所需的数据。

示例:

  1. HomeController.php

    复制代码
    <?php
    // src/Controllers/HomeController.php
    
    namespace MyFrameworkControllers;
    
    use MyFrameworkController;
    
    class HomeController extends Controller
    {
        public function index()
        {
            $this->logger->info("访问主页");
            $this->render('home/index.html.twig');
        }
    
        // ... 其他方法 ...
    }
    ?>
  2. UsersController.php

    复制代码
    <?php
    // src/Controllers/UsersController.php
    
    namespace MyFrameworkControllers;
    
    use MyFrameworkController;
    
    class UsersController extends Controller
    {
        public function list()
        {
            $this->logger->info("请求用户列表");
    
            // 示例数据,实际应用中应从数据库获取
            $users = [
                ['id' => 1, 'name' => '张三', 'email' => 'zhangsan@example.com'],
                ['id' => 2, 'name' => '李四', 'email' => 'lisi@example.com'],
                ['id' => 3, 'name' => '王五', 'email' => 'wangwu@example.com'],
            ];
    
            $this->render('users/list.html.twig', ['users' => $users]);
        }
    
        public function show($id)
        {
            $this->logger->info("请求用户详情", ['id' => $id]);
    
            // 示例数据,实际应用中应从数据库获取
            $users = [
                1 => ['id' => 1, 'name' => '张三', 'email' => 'zhangsan@example.com'],
                2 => ['id' => 2, 'name' => '李四', 'email' => 'lisi@example.com'],
                3 => ['id' => 3, 'name' => '王五', 'email' => 'wangwu@example.com'],
            ];
    
            if (isset($users[$id])) {
                $user = $users[$id];
                $this->render('users/show.html.twig', ['user' => $user]);
            } else {
                $this->sendNotFound();
            }
        }
    
        // ... 其他方法 ...
    }
    ?>

    说明:

    • 传递数据:在调用 render 方法时,通过数组传递数据给模板。

    • 数据获取:实际应用中,应从数据库或其他数据源获取数据。

总结

通过以上步骤,已经成功在自定义的 PHP 框架中集成了 Twig 模板引擎,实现了视图与业务逻辑的分离,提升了代码的可维护性和扩展性。以下是关键点的回顾:

  1. 选择合适的模板引擎:Twig 作为一个现代且强大的模板引擎,适合与自定义框架集成。

  2. 通过 Composer 安装:使用 Composer 轻松管理模板引擎的依赖。

  3. 配置模板目录:组织模板文件,确保项目结构清晰。

  4. 更新 Controller 类:在基础控制器中集成模板渲染功能,简化控制器方法中的视图渲染。

  5. 创建和使用模板:在 views/ 目录下创建 Twig 模板,并在控制器中渲染这些模板,传递所需的数据。

进一步扩展建议

  1. 布局和继承:

    利用 Twig 的模板继承功能,创建基础布局模板,减少重复代码。

    复制代码
    {# views/base.html.twig #}
    <!DOCTYPE html>
    <html lang="zh">
    <head>
        <meta charset="UTF-8">
        <title>{% block title %}My Framework{% endblock %}</title>
    </head>
    <body>
        <header>
            <h1>我的框架</h1>
            <nav>
                <a href="{{ path('home.index') }}">主页</a>
                <a href="{{ path('users.list') }}">用户列表</a>
            </nav>
        </header>
    
        <main>
            {% block content %}{% endblock %}
        </main>
    
        <footer>
            <p>&copy; 2024 My Framework</p>
        </footer>
    </body>
    </html>

    子模板可以继承该布局:

    复制代码
    {# views/home/index.html.twig #}
    {% extends 'base.html.twig' %}
    
    {% block title %}主页 - My Framework{% endblock %}
    
    {% block content %}
        <h2>欢迎来到主页!</h2>
        <p><a href="{{ path('users.list') }}">查看用户列表</a></p>
    {% endblock %}
  2. Twig 全局变量和函数:

    为了在所有模板中使用反向路由功能,可以将 path 函数作为 Twig 的全局函数注册。

    复制代码
    // 在 Controller 类的构造函数中添加
    $this->twig->addFunction(new TwigTwigFunction('path', function ($name, $params = []) {
        return $this->router->generateUrl($name, $params);
    }));
  3. 处理静态资源:

    配置模板引擎正确处理 CSS、JS 和图片等静态资源的路径,确保资源能够正确加载。

  4. 表单和 CSRF 保护:

    利用 Twig 模板引擎,创建安全的表单,并集成 CSRF 令牌保护,提升应用的安全性。

  5. 国际化和本地化:

    集成 Twig 的翻译扩展,支持多语言内容,提升应用的国际化能力。

相关推荐
BingoGo1 天前
当你的 PHP 应用的 API 没有限流时会发生什么?
后端·php
JaguarJack1 天前
当你的 PHP 应用的 API 没有限流时会发生什么?
后端·php·服务端
BingoGo2 天前
OpenSwoole 26.2.0 发布:支持 PHP 8.5、io_uring 后端及协程调试改进
后端·php
JaguarJack2 天前
OpenSwoole 26.2.0 发布:支持 PHP 8.5、io_uring 后端及协程调试改进
后端·php·服务端
JaguarJack3 天前
推荐 PHP 属性(Attributes) 简洁读取 API 扩展包
后端·php·服务端
BingoGo3 天前
推荐 PHP 属性(Attributes) 简洁读取 API 扩展包
php
JaguarJack4 天前
告别 Laravel 缓慢的 Blade!Livewire Blaze 来了,为你的 Laravel 性能提速
后端·php·laravel
郑州光合科技余经理5 天前
代码展示:PHP搭建海外版外卖系统源码解析
java·开发语言·前端·后端·系统架构·uni-app·php
QQ5110082855 天前
python+springboot+django/flask的校园资料分享系统
spring boot·python·django·flask·node.js·php
WeiXin_DZbishe5 天前
基于django在线音乐数据采集的设计与实现-计算机毕设 附源码 22647
javascript·spring boot·mysql·django·node.js·php·html5