扩展webman原生模版 Raw类-支持Layout布局

wzj177

扩展

视图类

class LayoutRaw extends Raw
{
    public static function render(string $template, array $vars, ?string $app = null, ?string $plugin = null, ?string $layout = null): string
    {
        $request = request();
        $plugin = $plugin === null ? ($request->plugin ?? '') : $plugin;
        $configPrefix = $plugin ? "plugin.$plugin." : '';
        $viewSuffix = config("{$configPrefix}view.options.view_suffix", 'html');
        $app = $app === null ? ($request->app ?? '') : $app;
        $baseViewPath = $plugin ? base_path() . "/plugin/$plugin/app" : app_path();
        $__template_path__ = $template[0] === '/' ? base_path() . "$template.$viewSuffix" : ($app === '' ? "$baseViewPath/view/$template.$viewSuffix" : "$baseViewPath/$app/view/$template.$viewSuffix");
        $layoutPath = $layout ? $baseViewPath . "/view/$layout" : null;
        $viewCache = config("{$configPrefix}view.options.view_cache", true);
        if ($viewCache) {
            $cacheKey = md5($__template_path__);
            $viewPath = runtime_path('views');
            !is_dir($viewPath) && mkdir($viewPath, 0755, true);
            $cachePhpFile = runtime_path('views') . "/$cacheKey.php";
            $cachePhpTimeFile = runtime_path('views') . "/$cacheKey.php.txt";
            if (is_file($cachePhpFile) && is_file($cachePhpTimeFile)) {
                $cachePhpTime = intval(file_get_contents($cachePhpTimeFile));
                // 缓存文件是否过期
                if ($cachePhpTime === filemtime($__template_path__)) {
                    ob_start();
                    try {
                        include $cachePhpFile;
                    } catch (Throwable $e) {
                        ob_end_clean();
                        throw $e;
                    }

                    return ob_get_clean();
                }
            }
        }

        if (isset($request->_view_vars)) {
            extract((array)$request->_view_vars);
        }

        extract($vars);

        ob_start();
        try {
            include $__template_path__;
        } catch (Throwable $e) {
            ob_end_clean();
            throw $e;
        }

        $page_body_content = ob_get_clean();
        if ($layout) {
            if (file_exists($layoutPath)) {
                preg_match_all('/<style.*?>(.*?)<\/style>/is', $page_body_content, $styleMatches);
                preg_match_all('/<script\s+src=["\'](.*?)["\'].*?><\/script>/is', $page_body_content, $scriptMatches);
                preg_match_all('/<link\s+rel=["\'].*?["\'].*?href=["\'](.*?)["\'].*?>/is', $page_body_content, $linkMatches);
                $block_link = implode("\n", $linkMatches[0]) . "\n";
                $block_style = implode("\n", $styleMatches[0]) . "\n";
                $block_script = implode("\n", $scriptMatches[0]);
                $page_body_content = preg_replace('/<style.*?<\/style>/is', '', $page_body_content);
                $page_body_content = preg_replace('/<script\s+src=["\'].*?["\'].*?><\/script>/is', '', $page_body_content);
                $page_body_content = preg_replace('/<link\s+rel=["\'].*?["\'].*?href=["\'].*?["\'].*?>/is', '', $page_body_content);

                ob_start();
                // 提取布局和视图的内容
                extract(compact('page_body_content', 'block_link', 'block_style', 'block_script'));
                include $layoutPath;
                $renderedContent = ob_get_clean();
                if ($viewCache) {
                    file_put_contents($cachePhpFile, $renderedContent);
                    file_put_contents($cachePhpTimeFile, filemtime($__template_path__));
                }

                return $renderedContent;
            }
        }
        return $page_body_content;
    }
}

模板 _layout.html

根据上面的改造,布局文件放在应用的view目录下

<!DOCTYPE html>
<html lang="zh-cn">
<head>
    <meta charset="utf-8">
    <title><?= $page_title ?? '管理后台' ?></title>
    <link rel="stylesheet" href="/app/admin/component/pear/css/pear.css"/>
    <link rel="stylesheet" href="/app/admin/component/jsoneditor/css/jsoneditor.css" />
    <link rel="stylesheet" href="/app/admin/admin/css/reset.css"/>
    <?= isset($block_link) ? $block_link : '' ?>
    <?= isset($block_style) ? $block_style : '' ?>
</head>
<body class="pear-container">
<?= $page_body_content ?? '<div class="content"><img src="/app/admin/admin/images/404.svg" alt=""><div class="content-r"><h1>404</h1><p>抱歉,你访问的页面不存在或仍在开发中</p></div></div>' ?>
<script src="/app/admin/component/layui/layui.js?v=2.8.12"></script>
<script src="/app/admin/component/pear/pear.js"></script>
<script src="/app/admin/component/jsoneditor/jsoneditor.js"></script>
<script src="/app/admin/admin/js/common.js"></script>
<?= isset($block_script) ? $block_script : '' ?>
</body>
</html>

特性

  • 支持layout布局
  • 支持模板缓存

案例:single-vue-cms-admin

98 3 0
3个评论

liziyu

感觉是个好东西,但没看懂!哈哈

  • wzj177 2天前

    就和tp那些框架的layout的一样。做一个统一的layout。其他视图文件只需要编写代码块(比如:列表就只有查询表单、列表、分页、业务js的代码;form表单就是表单内容和业务js),在layout里面统一引入公共css、公共js,视图里面就少了些代码,
    其他也没啥。主要是看个人习惯是否习惯。

  • liziyu 1天前

    哦哦,类似之前layui的“单页版”的,谢谢!~

xianrenqh

感觉是个好东西,但没看懂!哈哈

  • wzj177 2天前

    就和tp那些框架的layout的一样。做一个统一的layout。其他视图文件只需要编写代码块(比如:列表就只有查询表单、列表、分页、业务js的代码;form表单就是表单内容和业务js),在layout里面统一引入公共css、公共js,视图里面就少了些代码,
    其他也没啥。主要是看个人习惯是否习惯。

efnic

666,已购买。

  • wzj177 1天前

    感谢支持,有问题可以找我

  • wzj177 1天前

    如果下载不是1.0.1版本,请重新下载

wzj177

236
积分
0
获赞数
0
粉丝数
2019-06-03 加入
×
🔝