预过滤器 Prefilter

预过滤器 Prefilter

DouView 在编译前对模板源执行预过滤(Prefilter),前台与后台各一套。预过滤器在 DouView::compileSource 里、真正编译之前运行。

一、前台 FrontPrefilter

  1. 主题静态资源烘焙为绝对路径:把模板里的相对资源引用(images/、css/、js/,含 ../ 前缀)替换为当前主题的绝对 URL。主题路径优先取 $GLOBALS['_THEME_PATH'],其次取已 assign 的 theme_path,再次由 site.site_theme + ROOT_URL 拼接。
  2. 移除旧式 meta:删除行首的 meta http-equiv="Content-Type" 声明。
  3. 还原 HTML 注释包裹的标签:把注释内的模板标签激活(见第三节)。

因为是编译期字面烘焙,前台编译产物与主题强绑定,切主题 / 升级引擎须清缓存(靠 COMPILE_REVISION 自动失效),详见「编译流程与缓存 Compile Cache」篇。

二、后台 AdminPrefilter

  1. 静态资源加后台前缀:css/ / js/ / images/ 分别前缀为 {$admin_url}view/css/ 等({$admin_url} 渲染期解析,含 host),使后台在伪静态深路径下不受相对基准目录影响;
  2. 裸链接绝对化:仅限 href / action 属性里的裸 index.php?route= 链接,前缀为 {$admin_url}index.php?route=(避免误伤 {url ... back='index.php?route=...'} 这类标签参数);
  3. 移除旧式 meta:同前台;
  4. 还原 HTML 注释包裹的标签:同前台。

三、HTML 注释包裹标签的还原

两份预过滤器都会把「HTML 注释里的模板标签」还原为真正生效的标签。这使得模板可以用 HTML 注释包裹标签,在未渲染时(如直接用浏览器打开)仍保持合法 HTML 结构,渲染时注释被去掉、标签被执行:

<ul>
    <!-- {foreach from=$list item=item} -->
    <li>{$item.title}</li>
    <!-- {/foreach} -->
</ul>

这是 DouPHP 模板的常见写法。还原算法(restoreCommentTags)的三条关键规则:

  1. 注释体内全部 {..} 标签都要激活:只保留首个标签会丢 {/foreach} 等闭合配对,导致编译期报 mismatched tag;
  2. 文本只保留在成对块内部:如 <!-- {if !$first}、{/if} --> 中成对 {if}/{/if} 之间的「、」会保留;而成对结构之外的说明文字(如 <!-- {if $rec eq 'default'} 起始页 --> 的「起始页」)丢弃,避免泄漏为页面可见文本(与旧 remove_html_comments 口径一致);
  3. 块标签全集:参与配对判定的块标签集合 = Parser 入栈容器 if / foreach / list / category / strip 加上 Lexer 保护区 literal(漏 literal 会把注释内 {literal} 块的内部文本误处理)。

若注释体内没有任何完整 {..} 标签,restoreCommentTags 返回 null,调用方保留原注释不动。

四、工程约定

  • 前台与后台的 restoreCommentTags 逐字一致,任何改动都要同步两份,否则会前后台行为漂移;
  • 改动预过滤语义必须同步 bump DouView::COMPILE_REVISION,否则模板源 mtime 未变时旧编译缓存不会重编。
添加日期: