模块暂不可用: 此动态功能尚未由只读迁移站支持。
[[embed]]
<iframe src="//interwiki.scpwikicn.com/styleFrame.html?priority=2
&type=sidebar
&override={$override}&theme=https://cdn.scpwiki.com/theme/en/basalt/normalize-min.css
&css={$css}" style="display: none"></iframe>
[[/embed]]
[[embed]]
<iframe src="//interwiki.scpwikicn.com/styleFrame.html?priority=2
&type=sidebar
&override={$override}&theme=https://oxygennine.github.io/Peroxide/CSS/Interwiki/Interwiki.css
&css={$css}" style="display: none"></iframe>
[[/embed]]
隐藏Saving Pages
数据表单(Data forms)是Wikidot最强大的功能之一,但对于大部分写作网站而言,一般的创作者并不需要用到这个功能。不过,在需要将数据结构化处理时(例如,在组队竞赛中填报队伍信息、上传特定格式的实验记录等),表单功能将变得非常实用。本文参考Wikidot的官方文档,将全面讲解表单系统的使用方法和应用场景。
创建表单
建立模板页面
简单来说,我们必须为一个表单系统建立一个专属分类。例如,假设我们将开办一场组队进行的征文竞赛“2026填表竞赛”,需要参赛队伍按格式上传信息并集中在中心页展示,那么第一步应该是建立formcon2026:_template这个页面。
_template是页面分类的专属模板页面,在模板页的修改会被自动同步至这个分类下的所有页面。这也意味着_template最好被管理员锁定以免遭受恶意破坏。
在formcon2026:_template中,使用[[form]]…[[/form]]就可以自动将整个分类转化为数据表单分类。这也意味着,不能在同一个分类中混合存放数据表单页面和普通维基页面。每个数据表单页面都属于某个特定分类下的单独页面。一个分类仅能设置一个数据表单,且该表单结构会应用到该分类下的所有页面。
设置数据结构
{{@@[[form]]…[[/form]]@@}}的内容类似[*https://www.runoob.com/w3cnote/yaml-intro.html YAML]。
YAML语法教程
+ 展开这部分
YAML是一种极度简洁的标记语言,用来描述有层级的数据。它的特点是:
- 使用空格数量来表示缩进层级,不使用缩进符(Tab)。空格的数量不重要,但一定要是最低一层的整倍数(例如,2、4、6个空格,或者3、6、9个空格都可以表示1、2、3级)。
- 使用
key: value来描述键和值,冒号后必须有空格。 - 大小写敏感。
没了。实际上,这就是Wikidot表单系统用到的YAML的全部了。
下面是一个简单的示例:
[[form]]
fields:
teamName:
label: 队伍名称
type: text
width: 30
teamNumber:
label: 人数
type: select
values:
1: 1
2: 2
3: 3
4: 4
5: 5
teamBoss:
label: 队长
type: text
width: 30
ifTeamNewbee:
label: 是否为新人队伍
type: checkbox
default: 1
teamLogo:
type: file
label: 上传LOGO图片
category: formcon2026-files
[[/form]]
在formcon2026这个分类下创建任何页面时,原来的编辑框会消失,代之以这样的、可填写的表格:

表格分为左侧列和右侧列。通常情况下,左侧列是需要填写的字段名称,右侧列是等待填写或选择的值。
对包含数据表单的类别启用自动编号可以消除页面名称重复的风险。此设置在站点管理器的“页面自动编号”功能中完成。
我们以此为例解释formcon2026:_template的内容。
字段
fields是开头的根字段,要被Wikidot识别,YAML必须有且只能有唯一一个fields顶级字段。在fields下,有一个或多个子字段,每个字段共有的属性包括:
label:用户在表单中看到的字段名称。随意填写字符串。type:字段类型。需要选择一个关键字(见后文)。[property]:根据字段类型定义的属性。
例如在
fields:
teamName:
label: 队伍名称
type: text
width: 30这个表单中,fields下有一个名为teamName的字段,它显示为“队伍名称”(见上图),类型是text(用户输入字符串),还有一个叫width的属性,属性的值是30,意味着这个输入框的长度是30。
适用于所有字段类型的属性
label
如果你指定了label属性,则该字段在左侧列中显示label属性的值,或对于合并字段则显示在字段之前。如果你未指定label,则该字段在左侧列中留空,或对于合并字段则紧贴在前一个字段之后。
join
如果你指定了join: true,则该字段会被放置在前一个字段的右侧列(如果存在前一个字段)。如果该字段是表单中的第一个字段,则此属性无效。例如:
city:
label: City
width: 20
postcode:
label: Postcode
width: 8
join: true
在这个例子中,postcode表现为city的一个子属性。
before和after
before提供一段纯文本字符串,显示在字段值之前。after提供一段纯文本字符串,显示在字段值之后。
phone:
label: 电话号码
width: 10
before: +(86)
price:
label: 竞赛奖金
width: 10
after: 元
字段类型(type)可选的值
text
定义文本或文本框字段。如果某个字段不指定type,则默认是这个类型的字段。允许使用width和height作为属性。如果不指定高度,则为普通的单行文本字段;如果指定高度,则为文本框。Wiki语法在文本字段中无效。
可在文本字段上使用的具体属性:
• width: 指定可见字段宽度(以列数计,大致为固定间距字符数)。
• height: 指定字段高度(以行数计),1为普通文本字段,2或以上为文本框。
• match: 指定字段值必须匹配的正则表达式。
• match-error: 指定自定义错误信息。
• hint: 提供字段为空时显示的提示文本。如需使用像#这样的特殊字符,需要使用\进行转义。
• default: 定义新页面上显示的字段默认值。需注意,default在大部分字段中都可以使用。
name:
label: 名字
type: text
width: 30
default: 小明
comment:
label: 评论
type: text
width: 50
height: 3
hint: 这里是评论区,不是无人区~
email:
label: 邮件地址
match: /^[_a-zA-Z0-9\-\+]+(\.[_a-zA-Z0-9-]+)*@[a-zA-Z0-9-]+(\.[a-zA-Z0-9-]+)+$/
match-error: 邮件格式错误!
wiki
和text类似,但是wiki允许用户输入维基语法。
select
定义一个多值选择字段。需要一组值。如果指定两到四个值,则会得到水平单选字段。如果指定五个或更多值,则会得到下拉选择字段。例如:
gender:
label: 性别
type: select
values:
0: 男
1: 女
2: 其他
3: 保密
type:
label: 喜欢的音乐种类
type: select
values:
0: 古典
1: 乡村
2: 民谣
3: 独立
4: 爵士
5: 流行
6: 摇滚
default: 6
在上述示例中,选择字段的属性为0到6,默认属性为6,将值设置为摇滚。不过,您也可以使用字符串作为属性,例如
cl: 古典
co: 乡村
fk: 民谣
in: 独立
jz: 爵士
po: 流行
ro: 摇滚注意:Yes、No、True和False的值是保留值,在驱动数据表单的YAML代码中具有特殊含义。要在数据表单中使用它们,需要将它们放在引号内,否则将无法正常工作。
done:
label: 是否完成?
type: select
values:
not: "No"
done: "Yes"
default: notcheckbox
checkbox定义一个复选框字段,在表单数据中存储为0或1。
onions:
label: 你喜欢洋葱吗?
type: checkbox
default: 1
pagepath
pagepath允许用户创建并在页面树中的某个页面内进行选择;“路径”指的是所有父级页面加上该页面本身的列表。它以“页面 / 页面 / 页面 / 页面”的形式可视化呈现,每个层级都提供查看该页面、更换页面或添加新子页面的选项。这不会影响实际的页面父级关系,且一个表单可以包含多个页面路径字段。页面路径字段的值以页面的完整名称形式存储。隐藏页面在用户选择和浏览页面树时不可见。
category:指定包含页面树的页面分类。default:定义新页面上显示的字段的默认值。max-level:设置可在页面路径树中创建的最大层级数。
hidden
向表单添加用户无法看到或编辑的数据。它在视觉上不占用任何空间。这是为了将数据放入页面,以便以后可以使用这些数据。该字段的值由value属性定义。例如,下面的例子让表单有一个值为1.0的隐藏字段,字段名为version。
version:
type: hidden
value: 1.0static
static显示为不可编辑文本,并允许表单设计者为表单添加文本和格式。static字段不会存储在页面中,值来自value属性。value可以使用大多数wiki语法,并且可以通过在开头添加一个竖线符号|,然后在接下来的内容保持缩进的方式构建连续的换行。value的所有内容都无需转义符号。
header-1:
type: static
label: 'Inline Formatting Docs'
value: |
//italic text// italic text
||~ what you type ||~ what you get ||
|| {{@@//italic text//@@}} || //italic text// ||
|| {{@@**bold text**@@}} || **bold text** ||
|| {{@@//**italic and bold**//@@}} || //**italic and bold**// ||
|| {{@@__underline text__@@}} || __underline text__ ||
|| {{@@--strikethrough text--@@}} || --strikethrough text-- ||
|| {{@@{{teletype (monospaced) text}}@@}} || {{teletype (monospaced) text}} ||
|| {{@@normal^^superscript^^@@}} || normal^^superscript^^ ||
|| {{@@normal,,subscript,,@@}} || normal,,subscript,, ||
|| {{@@[!-- invisible comment --]@@}} || [!-- invisible comment --] ||
|| {{@@[[span style="color:red"]]custom //span// element[[/span]]@@}} || [[span style="color:red"]]custom //span// element[[/span]] ||
|| {{@@##blue|predefined## or ##44FF88|custom-code## color@@}} || ##blue|predefined## or ##229966|custom-code## color ||
[[div class="alert alert-info"]]
You can use user-defined {{ID}} arguments in **@@[[span]]…[[/span]]@@** tags, which is extremely useful building sites using [http://getbootstrap.com Bootstrap]. Please note that every user-defined {{ID}} will have a {{"u-"}} prefix added in the output HTML for the security reasons.
[[/div]]
相同的代码也可以通过将整个字符串包裹在双引号中,并使用\n作为转义换行符来实现。
file
这允许用户直接从数据表单上传文件,并显示为文件的链接。
注意:文件不会上传到同一页面。相反,每个文件会在给定的页面分类(默认为“files”)中单独创建一个页面,页面名称为该附件的名称。通过指定category属性,可以指定页面创建时所处的页面类别,上传的文件将附加到此页面。在此示例中,每上传一个附件,就会在formcon2026-files这个页面分类下新开一个页面。
teamLogo:
type: file
label: 上传LOGO图片
category: formcon2026-files
若要展示图片,必须使用%%form_raw{字段名称}%%而非%%form_data{字段名称}%%来显示图片链接,然后嵌入到维基语法例如[[image]]中。
如果在数据表单的文件字段中没有上传图片,一些浏览器会显示错误标识。这看起来不美观,容易让人觉得操作有误。因此,您可以改为显示一张默认图片作为替代。这张图片可以是空白图像,也可以是与网站相关的通用图像。如果在数据表单的该字段中上传了图片,则会使用上传的图片进行展示。在上面的“2026填表竞赛”中,为团队LOGO设置默认值的CSS示例如下:
[[module CSS]]
.form-image-default%%form_raw{teamLogo}%%{ display: block !important; }
.form-image%%form_raw{teamLogo}%%{ display: none !important; }
[[/module]][[div class="form-image"]]
[[image %%form_raw{teamLogo}%%]]
[[/div]]
[[div class="form-image-default" style="display: none;"]]
[[image <默认logoURL>]]
[[/div]]url
让用户输入URL。该内容将以链接形式显示。可在此字段上使用的具体属性:
default:定义新页面上显示的字段默认值。default-schema:为URL定义默认协议(如未指定,默认为{{http://}})。match-error:指定自定义错误信息。required:指定该字段是否为必填项[true/false](如未指定,默认为false)。
password
允许用户输入“密码”——对用户而言,他们输入的每个字符都会被替换为星号。注意:保存页面后,密码以明文形式储存在源代码中,任何人都可以查看,没有任何加密措施。
这TM到底是要干嘛,搭钓鱼网站吗??
date
定义一个日期输入字段,使用jQuery UI日期选择器小部件来选择日期。可以使用options选项指定jQuery UI Datepicker Widget选项。例如:
showon: button:在输入字段后添加一个按钮,必须点击该按钮才能打开日期选择器。autoSize: true自动设置输入框的宽度,以适配dateFormat选项中定义的日期格式。changeYear: true:创建一个年份下拉选择器。如果你不希望用户点击上一年/下一年链接12次才能切换到其他年份,此功能非常有用。dateFormat: 'DD, d MM yy':将所选日期格式化为类似"Wednesday, 1 October 2014"的形式。firstDay: 1:告知日历将星期一作为小部件日历中每周的第一天,而非默认的星期日(0=星期日,1=星期一,……,6=星期六)。yearRange: '2026:2027':将年份选择限制在指定范围内。
mydate:
type: date
label: '日期'
options:
appendText: '请输入文本'
autoSize: true
changeYear: true
dateFormat: 'DD, d MM yy'
firstDay: 1
showOn: button
yearRange: '2026:2027'
日期字段中的日期以数字形式存储,并根据你指定的dateFormat选项进行显示。添加altFormat选项可为备用日期使用不同的日期格式。如果你想将日期保存为文本而非数字,可以使用altField选项将日期的文本版本放入数据表单的另一个字段中。有关此字段的完整说明见官方文档。
展示表单
格式化表单页面
如果你只保存[[form]]..[[/form]]结构,然后创建页面,每个页面都会有一个简单布局,每个字段按表单结构的顺序依次排列在前一个字段下方。在这种简单布局下,上传的图片也不会显示,只会显示一个图片链接。但你可以按照自己的喜好来布置显示的字段,并展示上传的图片和视频。为此,你需要将_template页面分成两个区域,中间用=====分隔符隔开。=====上方的内容可以随意设置,然后使用以下占位符表示表单内容:
%%form_data{字段名称}%%:显示所选字段的内容。除URL(图像、视频、电子邮件等)外,几乎所有内容均使用此变量。%%form_raw{字段名称}%%:显示所选字段的未格式化内容。用于URL信息(图像、视频等)以及需要高级Wikidot语法(包含、模块)的情况。%%form_label{字段名称}%%:显示字段label属性(如果有的话)。%%form_hint{字段名称}%%:显示字段的hint属性(如果有的话)。
以上面的“2026填表竞赛”为例,如果开头改成这样:
+ %%form_data{teamName}%%
你们是一个**%%form_data{teamNumber}%%**人的队伍。
[[#ifexpr %%form_raw{ifTeamNewbee}%%>0 | 你们是新人队伍。 | 你们不是新人队伍。]]
= 队长:[[*user %%form_data{teamBoss}%%]]
=====
[[form]]
fields:
…在提交表单后,每个表单页面就会呈现为类似这样的状态:

注意,ifTeamNewbee是复选框字段,所以勾选时值是1,不勾选就是0。这里先提取原数据,然后判断它是否大于0,展示对应的文本。
使用ListPages模块调取表单数据库内容
数据表单产生的数据可用于ListPages模块,详细用法参考Wikidot模块参考手册。它使用和上面完全一致的占位符。下面是一个创建所有参赛队伍的表格的示例。
[[module ListPages category="formcon2026" order="name" separate="false" prependLine="||~ 队伍名||~ 是否为新人队伍 ||~ 人数 ||" appendLine="||||||||~ ||"]]
|| %%title_linked%% || [[#ifexpr %%form_raw{ifTeamNewbee}%%>0 | 是 | 否]] || %%form_data{teamNumber}%% ||
[[/module]]在ListPages模块中,页面选择参数_<data-form-field-name>可以选择某个字段有特定值的页面。例如,要列出所有新人参赛队伍,请使用下划线开头的参数_ifTeamNewbee="1"。任何表单系统的字段名都可以用作ListPages模块的自定义参数名,下面给出筛选所有新人队伍且非独立参赛的队伍名单的示例:
[[module ListPages _ifTeamNewbee="1" _teamNumber=">1"]]若要按照某个字段的值排序,使用order="_<data-form-field-name>",例如order="_teamNumber desc"。注意:为了使排序正常工作,低于10的数字必须具有01、02、03等属性,尽管值仍然可以是1、2、3等,如下方的示例数据表单字段所示。在ListPages模块中显示的是正常的1、2、3等。由于01, 02, 03, …被视为八进制数字,您需要用分号将它们括起来("01", "02", "03", …),因为八进制中没有08和09,它们都会变成0。
albums:
label: Albums/CDs released
type: select
values:
"00": 0
"01": 1
"02": 2
"03": 3
"04": 4
"05": 5
"06": 6
"07": 7
"08": 8
"09": 9标签
目前无法在保存数据表单时根据表单中的值设置标签。但在标签字段实现之前,有一种变通方法可行:使用[[button set-tags]]。这是Wikidot提供的半自动为页面设置标签的方式,通过在_template页面添加类似{{@@[[button set-tags -* +%%form_raw{字段名称1}%% +%%form_raw{字段名称2}%% …]]@@}}的方式,可以让用户按下一个按钮,自动为页面添加他选择的字段对应的标签。相关讨论见[*http://community.wikidot.com/forum/t-402555/automatically-setting-tags-for-a-page-based-on-form-input 此处]。
相较于纯ListPages方案
许多竞赛和活动需要处理结构化的数据。例如,2026年部门毁灭竞赛的机制是这样的:通过在fragment分类建立格式化的页面,用户复制一个纯文本模板,并修改内容,用ListPages提取不同段落,再将内容注入中心页。这样做至少存在几个隐患:(1)Wikidot的ListPages模块现在已经出现明显的延迟,从几分钟到一小时甚至更长;(2)ListPages提取段落严格依赖于特定的格式,稍有错误就可能让中心页的排版产生严重混乱,甚至无法访问;(3)编辑界面不直观,严重依赖于注释说明。
在这方面,表单系统和ListPages的混合方案是纯ListPages的完美平替。表单系统目前仍然保持零延迟,任何改动都可以实时响应;由于可以使用无视维基语法的text纯文本字段,中心页排版不会被意外破坏,甚至可以防御恶意攻击;表单填写界面是自动生成的表格,所有位置一目了然。实际上,表单系统的本质是把作品和作品相关数据解耦合,这意味着它提供了设计机制更复杂的竞赛的可能性,例如:
- 通过提前注册表单实现随机用户/作品池;
- 在类似2026家具城,通过场外计算分数的基础上,在维基页面内实现按照场外分数排名;
- 在类似2026部门毁灭竞赛的基础上,直接在页面内上传附件;
- 在类似电子游戏竞赛的基础上,通过表单系统提供快速管理报名队伍的方式;
- ……
表单系统是Wikidot开放给每个人的数据库管理系统,但目前对它的功能开发远不如ListPages、CSS技巧等其它方面的内容深入。笔者乐意看到更多基于表单系统的、Wikidot特有的“戴着镣铐跳舞”式功能实现。
另请参见:






