2026-09-30 00:49:53 +08:00
|
|
|
|
<?php
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 视图渲染。
|
|
|
|
|
|
*
|
|
|
|
|
|
* 流程:render() 把数据展开 → 把「本页模板文件路径 / 当前页标识 / 标题」交给
|
|
|
|
|
|
* layout.php → layout 在正文位置 require 本页模板。
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
declare(strict_types=1);
|
|
|
|
|
|
|
|
|
|
|
|
namespace App;
|
|
|
|
|
|
|
|
|
|
|
|
final class View
|
|
|
|
|
|
{
|
|
|
|
|
|
public static function render(string $tpl, array $data = [], string $page = ''): void
|
|
|
|
|
|
{
|
|
|
|
|
|
$file = dirname(__DIR__) . '/templates/' . $tpl . '.php';
|
|
|
|
|
|
if (!is_file($file)) {
|
|
|
|
|
|
throw new \RuntimeException('模板不存在:' . $tpl);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
$tplFile = $file;
|
|
|
|
|
|
$pageKey = $page ?: $tpl;
|
|
|
|
|
|
$pageTitle = $data['title'] ?? '家书';
|
|
|
|
|
|
$extraHead = $data['extraHead'] ?? '';
|
|
|
|
|
|
|
|
|
|
|
|
extract($data, EXTR_SKIP);
|
|
|
|
|
|
require dirname(__DIR__) . '/templates/layout.php';
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-10-10 22:13:20 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* 只渲染**模板本身**,返回字符串(不套 layout)。
|
|
|
|
|
|
*
|
|
|
|
|
|
* 🔴 v40(用户 2026-10-10):「观影详情里面的编辑按钮应该也是弹出的,和新增是一样的,
|
|
|
|
|
|
* 编辑完以后,页面动态更新。」
|
|
|
|
|
|
* ⇒ AJAX 保存**校验失败**时,必须把这同一个表单**原样重画**回去
|
|
|
|
|
|
* (字段报错、`old()` 回填、附件/海报面板全靠模板自己产出)。
|
|
|
|
|
|
* 如果不重画而只回一个错误文案,用户就会看到"值全丢了、红字也没有"——
|
|
|
|
|
|
* 与整页路径(`View::render`)行为不一致,那种"两条路各说各话"的 bug 最难查。
|
|
|
|
|
|
*
|
|
|
|
|
|
* ⚠️ 与 `render()` 的唯一区别:不 require layout.php。
|
|
|
|
|
|
* layout 会输出 `<html>`/顶栏,塞进一段 innerHTML 里会直接坏掉结构。
|
|
|
|
|
|
*/
|
|
|
|
|
|
public static function renderPartial(string $tpl, array $data = []): string
|
|
|
|
|
|
{
|
|
|
|
|
|
$file = dirname(__DIR__) . '/templates/' . $tpl . '.php';
|
|
|
|
|
|
if (!is_file($file)) {
|
|
|
|
|
|
throw new \RuntimeException('模板不存在:' . $tpl);
|
|
|
|
|
|
}
|
|
|
|
|
|
extract($data, EXTR_SKIP);
|
|
|
|
|
|
ob_start();
|
|
|
|
|
|
require $file;
|
|
|
|
|
|
return (string)ob_get_clean();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-09-30 08:13:07 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* 独立的整页(登录、安装、错误),不套顶栏 —— 但**仍然要是一份完整 HTML**。
|
|
|
|
|
|
*
|
|
|
|
|
|
* ⚠️ 曾经这里直接 require $file,输出里没有 doctype / head / CSS,
|
|
|
|
|
|
* 浏览器拿默认样式渲染,登录页看起来就像「完全没样式」。
|
|
|
|
|
|
* 现在统一套一层 layout-bare.php(无顶栏的最小骨架)。
|
|
|
|
|
|
*/
|
2026-09-30 00:49:53 +08:00
|
|
|
|
public static function renderBare(string $tpl, array $data = []): void
|
|
|
|
|
|
{
|
|
|
|
|
|
$file = dirname(__DIR__) . '/templates/' . $tpl . '.php';
|
|
|
|
|
|
if (!is_file($file)) {
|
|
|
|
|
|
throw new \RuntimeException('模板不存在:' . $tpl);
|
|
|
|
|
|
}
|
2026-09-30 08:13:07 +08:00
|
|
|
|
$tplFile = $file;
|
2026-09-30 00:49:53 +08:00
|
|
|
|
$pageTitle = $data['title'] ?? '家书';
|
2026-09-30 08:13:07 +08:00
|
|
|
|
$extraHead = $data['extraHead'] ?? '';
|
2026-09-30 00:49:53 +08:00
|
|
|
|
extract($data, EXTR_SKIP);
|
2026-09-30 08:13:07 +08:00
|
|
|
|
require dirname(__DIR__) . '/templates/layout-bare.php';
|
2026-09-30 00:49:53 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|