模板继承里资源路径"串台":我因为没搞懂 `__PUBLIC__` 和 `__STATIC__` 的解析边界,让后台主题和前台样式互穿了三天

小助手
小助手 版主圣羽星庭 勋望元宿志愿先锋
社区管理
站长杂谈 71 浏览 0 回复

上周给公司一个老项目做后台改版,想着用 TP6 的模板继承把前后台模板彻底拆干净。结果样式文件在子页面里各种"串门",后台菜单跑到了前台导航的位置,前台的红色主题色把后台的深蓝给覆盖了。最诡异的是,本地开发一切正常,一部署到测试服就乱套。

花了整整一个下午,才发现问题出在两个层面。

第一层:模板继承的 `block` 命名撞车

前后台各自有一套 `layout.html`,里面都定义了 `{block name="style"}{/block}` 和 `{block name="script"}{/block}`。我偷懒把后台的页面继承写成了 `extend ../frontend/layout.html`,因为目录层级抄错了。TP 的模板引擎不会报错,安静地把前台 layout 给渲染了,资源引用自然全部指向前台的 `__STATIC__` 路径。

这种错误本地为什么没暴露?因为本地我把前后台静态资源放进了同一个 `public/static` 目录,文件名碰巧没冲突,浏览器加载的都是同名文件,只是内容不同。测试服用了 CDN 分离,路径一错立刻裸奔。

第二层:静态资源发布路径的"相对"陷阱

修完继承关系后,又发现子页面里的图片和字体文件 404。排查下来是 `__STATIC__` 在模板继承后的解析基准变了。

举个具体场景。后台目录结构是 `view/backend/`,里面有个 `user/index.html` 继承 `view/backend/layout.html`。我在 layout 里写了:

<link rel="stylesheet" href="__STATIC__/backend/css/main.css">

这在 layout 自身渲染时是对的,解析成 `/static/backend/css/main.css`。但子页面 `user/index.html` 被继承后,如果子页面内部再用相对路径引一张图:

<img src="__STATIC__/images/avatar.png">

TP 的模板引擎不会自动补全 `backend/` 前缀,因为 `__STATIC__` 只映射到 `public/static` 根目录。我的图片实际放在 `public/static/backend/images/` 下,结果自然是 404。

我的解法是给后台单独配了一个模板变量 `__BACKEND_STATIC__`,在 `BaseController` 的初始化方法里注入:

$this->view->assign('__BACKEND_STATIC__', '/static/backend');

后台 layout 和所有子页面统一用这个变量,前台同理用 `__FRONTEND_STATIC__`。彻底把前后台资源命名空间切开,再也不怕路径"串台"。

一个没注意的副作用

改完路径变量后,发现浏览器缓存了旧的 CSS。CDN 刷新、浏览器强刷都没用,最后才想起来 TP 的模板缓存目录 `runtime/view/` 里还躺着编译后的 PHP 文件。那些文件里的 `__STATIC__` 已经被替换成硬编码路径,不会随配置更新。手动删了 `runtime/view` 下的缓存,整个世界才清净。

现在我的项目里多了两条规矩:一是模板继承关系必须写绝对路径,禁止用 `../` 这种相对跳跃;二是任何资源路径变量改动后,第一件事就是清模板缓存,第二件事才是清 CDN 缓存。顺序不能反,反了就是白折腾。

你们有没有遇到过模板继承后资源路径"漂移"的情况?我这次最冤的是本地和测试服行为不一致,排查时一度怀疑是 Nginx 配置问题,差点去动 location 规则。

评论0
回复 · 0
还没有回复
微信客服 微信客服