Dentrado, read-only mode: mirroring http://backrooms-wiki-cn.wikidot.com/about-iftagsAbout Dentrado
用 iftags 为你的版式、组件设置可选项

[[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]],并将其中样式应用在页面上。