视图与前端资源

Clara 视图约定、布局钩子点位、app.js / editor.js / admin.js 与 CSS 变量体系,插件前端注入参考。

07 · 视图与前端资源

1. 视图层(app/Views)

渲染机制见 [02 § View](02-核心框架.md#view)。约定:

  • 视图即 PHP 模板:`View::render` 先 `extract($vars, EXTR_SKIP)` 再 include;输出一律经 `e()` 转义防 XSS。
  • 布局:前台 `Views/layout.php`、后台 `Views/admin/layout.php`;`View::display` 自动把视图结果塞进布局的 `$content`。
  • 插件视图走 `View::renderFile(绝对路径)`(见 [06](06-插件系统.md))。

前台视图清单

视图页面
[layout.php](../app/Views/layout.php)主布局:导航(搜索/通知铃铛/用户菜单 + `nav_links` 钩子)、页脚(友链 + `footer_links` 钩子)、`window.CLARA` 注入、PWA manifest/sw 注册
[home.php](../app/Views/home.php)首页:置顶/最新主题流 + 侧栏(`sidebar_top`/`sidebar_bottom` 钩子 + 热门标签/统计);分类区块带 `id="cat-{id}"` 锚点(`.forum-cat` 的 `scroll-margin-top` 防 sticky 头遮挡,供面包屑分类项定位)
[forum.php](../app/Views/forum.php)版块页:两种布局(list 全屏通栏 / side 双栏侧栏),`forum_content_before/after`、`sidebar_*` 钩子均生效;JSON-LD 面包屑
[thread.php](../app/Views/thread.php)主题详情:五级面包屑(首页 › 分类(锚点定位首页区块) › 版块 › 子分类 › 标题,JSON-LD 同步)+ 返回上页/目录/全文阅读图标工具区、正文 `md_render` + TOC、楼层列表(引用预览 `quote_preview`、AI 徽章 `ai_tag_extract`)、回复框、`thread_content_before/after` 钩子、`data-replies` 轮询容器
[thread-new.php](../app/Views/thread-new.php) / [thread-edit.php](../app/Views/thread-edit.php)发帖 / 编辑(共用 partials/editor 编辑器;发帖页含悬赏金额/货币选择与投票选项折叠表单;编辑页含投票修改区——选项按行对应保票数/删行删票/清空删投票——与附件设置区——价格/货币/权限/网盘链接,仅本人上传或管理员的附件)
[user.php](../app/Views/user.php)用户主页:主题/回复/收藏记录、勋章墙、关注粉丝、`md_render` 输出
[uc.php](../app/Views/uc.php)用户中心(最大视图,约 26KB):多 tab(概览含经验卡片/货币/会员状态、主题、回复、收藏、关注、粉丝、勋章、头像框选择器 `frames_sorted_owned_first` 排序、资料设置、隐私、安全)
[checkin.php](../app/Views/checkin.php)签到日历:本月格子(已签/漏签/可补签)、连签统计、补签入口
[shop.php](../app/Views/shop.php)会员商城:会员套餐卡(`.vip-header`/`.vip-icon` 结构)+ 头像框货架
[login.php](../app/Views/login.php) / [register.php](../app/Views/register.php) / [forgot.php](../app/Views/forgot.php) / [reset.php](../app/Views/reset.php) / [admin-verify.php](../app/Views/admin-verify.php)认证页(admin-verify 为后台 2FA 验证码页)
[answers.php](../app/Views/answers.php)GEO 问答聚合页(悬赏已采纳问答列表,QAPage JSON-LD;菜单显示三条件见 [03 § GeoService](03-前台业务模块.md))
[transfer.php](../app/Views/transfer.php) / [levels.php](../app/Views/levels.php)用户转账 / 等级门槛公示(游客可看)
[pm-inbox.php](../app/Views/pm-inbox.php) / [pm-compose.php](../app/Views/pm-compose.php) / [pm-view.php](../app/Views/pm-view.php)私信收件箱 / 发起会话 / 会话详情(`pm_content_before/after` 钩子两页共用)
[banned.php](../app/Views/banned.php) / [maintenance.php](../app/Views/maintenance.php)封禁提示页 / 维护模式页(均独立全屏,不套 layout)
[report.php](../app/Views/report.php) / [forum-followers.php](../app/Views/forum-followers.php)举报提交 / 版块关注者列表
[search.php](../app/Views/search.php) / [tag.php](../app/Views/tag.php) / [gifts.php](../app/Views/gifts.php) / [redeem.php](../app/Views/redeem.php) / [notifications.php](../app/Views/notifications.php) / [announcements.php](../app/Views/announcements.php) / [announcement.php](../app/Views/announcement.php)搜索 / 标签聚合 / 礼物 / 卡密兑换 / 通知 / 公告
[error.php](../app/Views/error.php)统一错误页(404/403/500/419,套站点布局):大号描边状态码 + 返回上页/首页按钮;404 附加站内搜索框与最新讨论 6 条(权限过滤,DB 异常退化纯提示页);500 保持零 DB 查询(异常链里 DB 可能正是故障点)

partials 复用组件

组件用途
[editor.php](../app/Views/partials/editor.php)Markdown 编辑器:工具栏(加粗/H1-H3/引用/代码/列表/表格/颜色等)+ 镜像层表情渲染 + 实时预览 + 图片上传 + 文字颜色面板(24 预设色板 + 自定义取色,插入 `[color=值]`)+ 附件面板(白名单类型,可设价格/货币出售,插入 `[file]id[/file]`);前后台共用(后台帖子编辑页引入同一 partial + editor.css/editor.js)
[frame-picker.php](../app/Views/partials/frame-picker.php)头像框选择器(佩戴/拥有/未拥有分组,特效实时预览)
[gift-modal.php](../app/Views/partials/gift-modal.php)礼物打赏弹窗
[thread-row.php](../app/Views/partials/thread-row.php)主题列表行(头像/标题/标签/统计/最后回复)
[left-quick-nav.php](../app/Views/partials/left-quick-nav.php)三栏左栏快捷导航卡(按后台 nav_menu_* 开关渲染公告/问答/签到/礼物墙;`lq_links` / `lq_bottom` 钩子)
[cat-nav.php](../app/Views/partials/cat-nav.php)首页分类锚点导航

后台视图

[admin/layout.php](../app/Views/admin/layout.php)(六组菜单 + flash + 确认弹窗 + `window.CLARA_ADMIN`)+ 各管理页(users / user-edit / forums / forum-edit / settings / tools / plugins / plugin-settings / dashboard / threads / groups / group-edit / currencies / currency-logs / cards / cards-view / invites / memberships / membership-edit / medals / medal-edit / frames / frame-edit / gifts / gift-logs / announcements / announcement-edit / links / link-edit / mail / audit / reports / login-logs / ip-bans / attach-buys / credit-rules / restore)。

2. layout.php 与前端桥接

前台布局向 JS 注入全局对象:

<script>
window.CLARA = {
  base: '站点根URL',
  csrf: 'CSRF令牌',
  user: 当前uid或0,
  notifyRemindMin: 通知轮询提醒分钟数,
  notifySound: 提示音URL,
  pwa: PWA配置
};
</script>

app.js 全部能力基于 `window.CLARA` 初始化;后台同理注入 `window.CLARA_ADMIN = { csrf, iconUpload }`。

3. 前端 JS(assets/js)

app.js(约 64KB,无依赖原生 JS)

功能块说明
基础 UI`claraToast` / `claraConfirm` / `claraAlert` 统一组件(替代原生 alert/confirm)
通知系统`poll()` 每 15 秒 `GET /notifications/poll`;红点渲染;提示音(`ensureNtfAudio` 需用户交互解锁自动播放策略);`notifyRemindMin` 分钟内新通知才提醒
数据同步轮询容器 `data-sync` 区分 `forum`/`thread`/`home`:thread 页 10 秒 / forum 与 home 20 秒;检测 `data-replies` 变化(新回复含 AI 回复)→ 用户未在输入(userBusy 检测)时自动 reload 并保持滚动位置,输入中只 toast 提示并暂停轮询
AJAX 封装`post()` 统一带 `X-CSRF-Token` + `X-Requested-With` 头 + same-origin credentials
Markdown 编辑器交互逻辑已抽取至 editor.js(前后台共享):工具栏插入语法、[em] 表情镜像层渲染(自定义光标/输入法组词跟随)、表情面板懒构建、图片上传、附件面板(双模式 tab 切换 + 美化选择文件按钮 + 权限下拉联动组多选,POST `/upload/file` 可设价格/货币/perm\_type/perm\_groups,成功插入 `[file]id[/file]`)、预览;配置自适应(前台 CLARA / 后台 EDITOR_CFG 注入 base+csrf,上传/预览走前台路由)
点赞 / 收藏 / 关注 / 礼物 / 删除乐观 UI 更新 + fetch 提交
附件购买 / 网盘获取卡片按钮交互式:`data-attach-buy` 弹窗确认(claraConfirm)后 AJAX POST 购买、成功直达下载;`data-pan-get` 弹窗展示链接+提取码(escapeHtml 转义、execCommand 复制、打开网盘按钮、Esc/遮罩关闭);无 JS 时 `<a>` 分别走 GET 确认页 / 新窗口独立获取页兜底
布局切换版块页 list/side 切换按钮:`?layout=` 参数 + cookie `forum_layout`(一年,带后台默认值 md5 前 8 位版本戳——管理员改默认后旧 cookie 自动失效)
其它楼层引用回复、@提及、图片灯箱、代码块复制、返回顶部等

admin.js(约 13KB)

后台交互:统一确认弹窗、图标/图片上传(走 `CLARA_ADMIN.iconUpload`)、列表批量勾选、tab 切换记忆等。

editor.js(前后台共享)

编辑器交互逻辑(自 app.js 抽取为独立文件):工具栏插入语法、`[em]` 表情镜像层渲染(自定义光标 / 输入法组词跟随)、表情面板懒构建、图片上传(容器级 change 事件委托 + doingUpload 防重,规避 hidden input change 被浏览器吞的间歇性问题)、附件面板(双模式 tab + POST /upload/file)、实时预览(POST /preview 走 md_render)。CSRF 自愈:AJAX 遇 `csrf_expired` 自动 `GET /csrf/token` 拉新 token 重试一次。配置自适应:前台读 `window.CLARA`、后台读 `EDITOR_CFG`(注入 base + csrf,上传/预览走前台路由)。

4. CSS 体系(assets/css)

文件角色
[app.css](../assets/css/app.css)(约 96KB)前台全部样式:CSS 变量主题(`--bg/--soft/--tx/--bd/--ac/--radius-s` 等,主题色 `#D97757`)、头像框 20 种特效样式(`.avatar.has-frame.f-{effect}`,`--fc/--fc2` 驱动)、AI 徽章动画(`@property --ai-angle` 驱动 conic-gradient 流光,`mask-composite` 描边,`prefers-reduced-motion` 降级)、响应式断点(移动端 768px 级)
[editor.css](../assets/css/editor.css)编辑器 + .rich-text 排版(前后台共享单一来源):自 app.css 抽取(`.editor`/`.ed-*` 工具栏与表情面板/镜像层 + `.rich-text` 正文排版/代码块/复制按钮);两套布局 :root 变量同名同值故可直接共用;layout.php 与后台帖子编辑页均加载
[admin.css](../assets/css/admin.css)(约 29KB)后台样式:侧栏(248px,≤768px 抽屉化)、tab 栏、表格、表单;头像框特效样式与 app.css 双份同步维护(防止后台预览与前台不一致)

| [theme-trae.css](../assets/css/theme-trae.css) | 深色主题换肤层(`body.theme-trae` 覆盖 CSS 变量;判定链:访客 cookie > `theme_auto_current()` 时段自动(默认 07:00 亮 / 18:00 暗,可配)> 后台默认;含「绿底组件文字改深色」复合选择器组——新增纯 `--ac` 底组件需核对入组条件,下划线/描边式激活态禁止入组) |

样式约定:插件/模块页面级样式用内联 `<style>` 输出并加前缀类名,复用 app.css 的 CSS 变量保证主题一致。

5. 静态资源目录

目录内容
`assets/gif/`表情包(`表情` 引用)
`assets/img/`内置图片(favicon.png / icon-192.png 等 PWA 图标)
`assets/music/`通知提示音(后台设置中可选,`notify_sounds()` 扫描)

资源引用一律走 `asset('css/app.css')`:自动追加 mtime md5 版本号破缓存。

本文档随系统发布维护;如发现与当前版本不符,欢迎到社区反馈。