[[iftgs -版式]]
[[iftags]]
[[/iftags]][[/iftgs]]
[[iftgs -版式]]
[[iftags]]
[[/iftags]][[/iftgs]]
[[iftgs -版式]]
[[iftags]]
[[/iftags]][[/iftgs]]
[[iftgs -版式]]
[[iftags]]
[[/iftags]]
[[/iftgs]]
[[iftgs -版式]]
[[iftags]]
[[/iftags]][[/iftgs]]
经常有人问我,形同下面的代码有什么作用,原理是什么:
>[[ift####blue|gs -版式]]
>[[iftags]]
[[module CSS]]
一段 CSS 代码……
[[/module]]
>[[/iftags]]
>[[/ift####blue|gs]]
我在很多组件与版式里都使用过这一技巧,包括更好的空白、超阈限、岛屿分级组件等。不过需要先说明的是,这不是我原创的——我第一次看到此技巧是在 SCP Wiki 的 Basalt 版式。至于它起源于哪里,由谁创造,无法考证。
它的作用很好理解:当你在其他页面通过 [[include]] 引用此页面时,如果添加上 |option=a 的参数,就会使其中的 CSS 代码激活,启用样式;如果没有添加,则默认被包裹的
[[module CSS]]不会生效。
要理解它的原理,首先要知道以下几件事:
① Wikidot 的古早 Parser Bug
Parser,即语法分析器,是 Wikidot 用于解析 Wiki 语法的自动工具。可以这么理解:当你使用 Wiki 语法(例如用“//”包裹文本使其斜体)后,Wikidot 的 Parser 会自动分析写入的内容,将之翻译为浏览器使用的语言(HTML)并回传;这也是 Wiki 语法生效的原因。
而在 Wikidot 不可知、不可探的神秘古早代码中,存在一个原因不明的 Bug:
当你在“>”后面直接写入一段文本时,这一整段文本都会被注释掉。
虽然不知道它究竟为何出错,但可以推测可能与注释块(> )的解析相关1。例如下列内容:
>一段文本。
是完全不会解析的。它返回的是空白。
你可以在沙盒测试这一点。
② 高贵的 [[iftags]]
上文提到,“>”在 Parser 的 Bug 下可能成为万能注释符——注释其后的所有内容。但有一个例外:[[iftags]]。
[[iftags]] 区别于其他 Wiki 语法,它不会被翻译为任何内容。它是一个条件判断:是否满足标签条件,满足则解析其内内容,不满足则不解析。例如,
[[iftags -版式]]
内容
[[/iftags]]
仅当当前页面没有“版式”标签时,其中的内容才会生效。否则,被 [[iftags]]……[[/iftags]] 包裹的内容会被直接注释。这也是所有版式的介绍部分的原理——它们使用了 [[iftags +版式]],确保介绍内容只会在有“版式”标签的地方显示。因而,在其他页面正式引用版式时,由于没有“版式”标签,版式介绍的内容就不会显示。
这一点很像 C 语言中的条件编译(#if,#ifdef,#ifndef 等),如果有学过相关内容的同学会很熟悉。因其特殊性,Wikidot 对 [[iftags]] 的识别先于任何语法——在 Parser 开始解析任何 Wiki 语法之前。这也就意味着,上面提到的 Bug 不会对 [[iftags]] 生效。简单理解即:
>[[iftags -版式]]
一些东西……
>[[/iftags]]
等价于:
[[iftags -版式]]
一些东西……
[[/iftags]]
能够正常运作。
③ [[iftags]] 不应缺省
这一点很好理解。如果你使用了 [[iftags]],应该至少在其中加上一些标签条件。如果你什么都不加,就像下面这样:
[[iftags]]
一些东西……
[[/iftags]]
那么,[[iftags]] 会变为一个空条件判断,默认取否,即无论你的页面有什么标签,被 [[iftags]] 包裹的内容都会被注释。可以理解为:在条件空置的情况下,[[iftags]] 可以被视作注释符。
④ [[iftags]] 不可嵌套
很多自己做过版式、组件的同学大概对此深有体会。如果嵌套使用 [[iftags]],则内层会直接失效,被解析成普通文字。也就是说,如下代码:
[[iftags +原创]]
[[iftags +版式]]
这个页面是版式,并且为原创!
[[/iftags]]
[[/iftags]]
即便在同时打了“原创”、“版式”的页面,它也会被渲染如下:
[[iftags +版式]]
这个页面是版式,并且为原创!
[[/iftags]]
当 Wikidot 检测到 [[iftags]] 中还嵌套着 [[iftags]] 时,它压根不会理睬。不像 C 语言的条件编译,在检测到第一个 [[iftags]] 之后,Wikidot 只会傻乎乎地开始寻找位于最后方的、在下一个 [[iftags]] 前的 [[/iftags]],试图封闭这个代码块。因此,位于嵌套内的 [[iftags]] 会被直接忽略——转交给下层 Parser。
而 Parser 不会解析 [[iftags]],这不是它的职责。对它来说,这只是一行普通的文本,不属于任何语法。于是,这个内层嵌套的 [[iftags]] 会被直接翻译为普通的文本。
在了解以上所有知识后,我们再回过头来分析这段代码:
>[[ift####blue|gs -版式]]
>[[iftags]]
[[module CSS]]
一段 CSS 代码……
[[/module]]
>[[/iftags]]
>[[/ift####blue|gs]]
在版式页 / 引用版式却未填写 |option=a 的页面时:
首先分析最外层嵌套:
>[[ift####blue|gs -版式]]
>[[/ift####blue|gs]]
因为没有传参,[[iftgs -版式]] 的格式被完整保留。这不是一个合法的 [[iftags]],实际上,在 Wikidot 语法中,这不属于任何标记。因此,它被翻译为一行普通文本。而 Parser 检测到这行普通文本前存在一个“>”——这直接触发了神秘 Bug(①),导致内容被注释。
这两行等同于不存在。
然后再分析内层:
>[[iftags]]
[[module CSS]]
一段 CSS 代码……
[[/module]]
>[[/iftags]]
这次,是正常的 [[iftags]]。如 ② 所述,[[iftags]] 的执行优先级远高于任何 Wiki 语法,因此它等价于:
[[iftags]]
[[module CSS]]
一段 CSS 代码……
[[/module]]
[[/iftags]]
然而,根据 ③,我们得知,条件空缺的 [[iftags]] 永远不会被解析。因此,其中的所有内容都被忽略了——是的,此时,这一整段代码等价于空白。它不会有任何效果。
一切都消失了!
引用版式且使用参数 |option=a 的页面时:
首先,[[include]] 会直接传递参数。因此,代码变为如下:
>[[ift####blue|ags -版式]]
>[[iftags]]
[[module CSS]]
一段 CSS 代码……
[[/module]]
>[[/iftags]]
>[[/ift####blue|ags]]
原本的占位符 填入了参数 a。然后我们再解析外层:
>[[ift####blue|ags -版式]]
>[[/ift####blue|ags]]
因为填入了参数,外层 [[iftags]] 得以补全,成为了正式的 [[iftags]]。于是根据 ②,此 [[iftags]] 不受“>”影响,正确运行。又因为它具备条件“-版式”,所以会在一切没有“版式”标签的页面被判定为真,即:
外层 [[iftags]] 有效,效果为:解析内层内容。
接下来,我们再看内层:
>[[iftags]]
[[module CSS]]
一段 CSS 代码……
[[/module]]
>[[/iftags]]
由于 ④ [[iftags]] 不可嵌套,内层的 [[iftags]] 退化为普通文本。根据 ①,它们会因为前方的“>”而被 Parser 错误注释。于是此时内层等价于:
[[module CSS]]
一段 CSS 代码……
[[/module]]
也就是 [[module CSS]] 及其内容!此时,Wikidot 解析 [[module CSS]],并将其中样式应用在页面上。
