HFS: 模板宏

From rejetto wiki
Jump to: navigation, search

HFS 支持服务器端语言(指令),也叫做宏。这种语言在模板和事件脚本中的表现几乎相同。

请注意: 2.3 之前的版本不支持宏。

宏很强大,可以用于给 HFS 及其文件页面添加新的功能。

宏是如何工作的

与占位符的不同

您需要对模板如何工作有大概的了解。宏与占位符相似。输入的宏将在用户浏览页面时被替换为有实际意义的内容(我们称之“扩展”)。

占位符只代表一个名称,而宏有自己的功能及相应的参数。占位符只会被替换为文本(比如 %user% 替换为当前用户),而宏被用来在 HFS 服务器端进行指令操作(如 {.load.} 用以加载文件内容)。

您可以很简单地区分占位符与宏:占位符由 %百分号% 包围,而宏由 {.带点的大括号.} 包围.

更多

宏如何工作取决于输入的参数。一个宏根据输入的参数可进行不同的操作。

在一个模板中,宏 section 会复制位于该模板中所定义的一个 [节] 的内容——而您应该添加一个具体参数,使它知道应该读取哪一个节。

例如:{.section|style.} 将会读取节 [style] 的内容。该宏的快捷方式是 {.$style.}。

参数

在宏名称的后面,您可以添加管道字符“|”以添加参数,如:{.宏名称|参数.}. 如果需要更多参数,只需添加更多管道字符:{.宏名称 | 参数1 | 参数2 | 参数3.}.

可读性

宏是可以嵌套的。不过,这可能使得宏难以阅读。为了增加宏的可读性,您可以:

  • 将每个宏排列到独立的行并缩进.
  • 在一层宏的结尾添加: /宏名称 以提示自己关闭了一个宏。例如:{.load|{.section|stuff /section.} /load.}。最后的 /section/load 会被 HFS 忽略——这只是为了您的便利。

引用

某些情况下,您可能不希望 HFS 将某段文本当作宏处理。有一种不让 HFS 处理这种文本的方式,叫做“引用”。

要引用一段文本,只需用带冒号的大括号包围: {:这是一段普通文本,并且{.这个宏不会被执行.}:}

同时引用还可以让宏 setif 不提前执行其参数宏指令——您会在后面有所了解。

如果您需要在宏参数中使用管道字符而不分割参数,引用就是一种方法。 例如: {.add to log|输出一个管道字符:{:|:}.}。如此您可在日志中使用管道字符。您也可以使用宏 no pipe{.no pipe||.}

可用的指令

HFS 预置了许多实用指令。请参阅完整列表

执行次序

如果宏是嵌套的,那么它们的执行次序为:从里到外,从左到右。宏的嵌套格式就像 XHTML,以保证其不重叠。

比如:{.A {.B.} {.C.}.} {.D.}。在此例中,宏的执行顺序为: B, C, A, D。HFS 在处理 B 与 C 前不能处理 A——因为 HFS 仍不知道 B 与 C 的最终结果,而 B、C 的最终结果才是 A 要处理的。

问题与解决方案

除了被引用的宏之外,其他宏都会被扩展。不过,if{.if | A | B | C .} 根据 A 来判断执行(扩展为) B 还是 C,但是如果 B 与 C 本身是宏,那么 B 与 C 总是会被执行。

因此我们需要引用 B 与 C。引用后,B 与 C 不会被提前执行,而是会在 if 判断符合条件后解除引用,然后被正确执行。 当然,如果 B 与 C 都是常文本,那么它们不必被引用。

比如:

{.if| %user% | {.append|日志文件.txt|有用户登录了哦!.} .}

如前文所描述,无论占位符 %user% 扩展为何,{.append.} 宏总是会被执行——这不是我们想要的。

然而,当我们将宏引用后:

{.if| %user% | {:{.append|日志文件.txt|有用户登录了哦!.}:} .}

仅当 %user% 扩展为空时(值为假),{.append.} 宏才会被解除引用并执行。

在其他情况下,您需要使用宏 {.dequote.} 来解除引用。不过如 if 之类的特殊宏则不必。此类宏有:if, set, for, for each, switchbreadcrumbs。这允许您使用变量改变输出。

预处理

如果您需要在每份文件页面加载之前处理一些宏,那么您可以将宏放置在节 [special:begin] 下。如:

[special:begin]  
{.if| %user% | {:{.append|日志文件.txt|用户 %user% 登录了哦!.}:} .}