本页面主要用于与晨翊策同学的代码知识交流,也为后来人提供参考。如有修改建议或疑惑,请前往本页面讨论页提出,并以--~~~~
署名。
课程名称 | Wiki语言进阶教程 | 课程状态 | 开课中 | 课时 | 待定 |
---|---|---|---|---|---|
面向人群 | 有一定Wiki语言知识和编辑基础,想进一步学习页面的制作和设计和高级功能的使用,开拓视野的编辑者 | ||||
先修要求 | 熟练掌握Wiki网站的使用,熟记常用Wiki标记语言和常用模板,已有一定编辑基础(有效编辑次数>50) | ||||
课程内容 |
| ||||
参考阅读 | W3school |
我相信,当你决定认真学习本页面以下内容时,应该已经有了一定的编辑基础,对自己充满信心,对Wiki的魅力感到兴趣十足,想要进一步深入到Wiki——这门奇妙的、跨世代的标记语言中去。我很高兴看到这样的你。曾经的我也是这样子的,想要提升自己的编辑水平,但当时网络上很难找到系统的Wiki语言的进阶教程,一路走来也是磕磕绊绊。今天和晨聊天,他说想学习进一步的Wiki语言使用;在那一瞬间,我瞥见了过去的记忆。于是我决定做这样一件我一直想做的事情:写一套系统详尽的,而又符合萌百本土情况的Wiki语言进阶教程。如有任何问题,可在每小节末尾提问或讨论;如对本人编写的内容有指正或者补充,请各位不吝指教。
本教程主要涉及三个方面的内容:HTML(含CSS),旨在讲解Wiki语言的底层基础,使编辑者对版面和格式的控制更加丰富化、多样化;Wiki表格,让编辑学会使用Wiki强大的表格功能;Wiki逻辑语言,讲解Wiki语言中较复杂的逻辑部分,用于构建较简单的模板。在教程的最后会介绍一些较为实用的技巧(主要用于VC区的编辑)。
由于笔者本人的业务范围限制,本教程可能会或多或少地偏向VC区的编辑需求与经验,还请理解。
—— 商火 2018.9.14 北京
2018.11.22 修正:可能出现不允许外来用户编辑用户页面的限制,故一切提问或者建议请移步讨论页。
即使你不是计算机专业,甚至没有接触过编程,你应该也听说过一些大名鼎鼎的计算机语言:C/C++,或者高级一点的JAVA、Python等等。但如果你有所接触,会发现虽然都叫“语言”,但他们和Wiki语言大相径庭。这是因为与这些程序性语言不同,Wiki本质上是一种标记性语言,它其实是HTML(HyperText Markup Language,超文本标记语言)的一个高度简化的变种[1]。
也许这是你第一次听说HTML,但我相信在之前的编辑中你其实已经不知不觉地使用了大量的HTML代码。如用于强制换行的<br />
,用于大段文字排版的<poem></poem>
,和书写喜闻乐见内容的<del></del>
,等等。这些就是HTML里面很基础的东西,统称为标签。更普遍一点,你在网络上浏览的99%的页面,无论多么简洁抑或花哨,其实都是一个个HTML文档,你使用的“浏览器”,本质上就是解读这些文档的解释器。
事实上,一个Wiki文档,一般就是由Wiki语言和HTML混写而成的,只不过一般不做区分,统一划分到Wiki语言中去。但当你访问一个词条时,你访问的其实还是一个HTML文档。Wiki系统在后台把Wiki源码转化为普通HTML文档,才能被你的浏览器读取。理论上,你可以用纯粹的HTML撰写每一个词条,但一来是给自己找罪受,二来出于安全考虑,有些HTML的功能被Wiki系统禁用了,只能通过Wiki语言间接调用。这些我们在本讲最后一节会提到。
之前提到了,作为一种标记性语言,HTML最基础的不是变量、运算符和表达式,而是标签(label/tag)。要从根本上去理解标签这个东西:一般的文本只是文本本身,而标签则是告诉“读者”(这个读者可以是人类,也可以是浏览器),这一段文本/这个部分是什么,以及它应该如何被表示(对于浏览器而言)。
让我们从Wiki出发去理解这个理念:我们都知道'''这是Wiki语言中粗体的标记方式'''
,但是从语义学的角度:这个标记被理解为,中间被标记的文字,是一段“粗体文字”。在这个定义中,我们会发现,它只是指明了被标记文本的类型——“粗体文字”,但并没有指明,“粗体文字”是什么样子的。在一般的浏览器中,这个被默认定义为笔画粗细度(font-weigh)为800个单位的文字(普通字体是400个单位),但这是不一定的;事实上,甚至可以对“粗体文字”这个标签进行重新定义,更改它的外观。
以上这一段对于初学者可能过于艰深,他们可能尚不能很好地理解“标签”这个事物的本质。没关系,因为这里只是一个预先的提醒。许多初学者容易在之后陷进一个误区,即把标签的表现形式当成标签的内在属性和作用,这是片面的,应尽量避免。等到进一步的学习结束后,自然会明白这段话的含义。
与Wiki语言中形形色色的标记不同,HTML中的标签具有统一的格式。一般来说,HTML的标签是成对出现的,分别是<标签名>形式的开始标签(start tag)和</标签名>形式的结束标签(end tag),或者叫开放标签和闭合标签。从一个开始标签到其对应结束标签的所有文本(含标签本身)叫做一个元素(element),元素除开标签剩下的文本叫做这个元素的内容(content)。一般来说,标签和内容组成了一个元素,元素之间的相互组合嵌套构成了一整个HTML文档。
元素的嵌套是指,一个元素(或几个元素的并列)可以作为另一个元素的内容,如:
<body> //元素body开始标签 <h1> //元素h1开始标签 /* 标题文本 //元素h1内容 * 元素body内容 </h1> //元素h1结束标签 */ </body> //元素body结束标签
这种情况下,外层的元素称为内层元素的父元素;反过来,内层元素是外层元素的一个子元素。这是因为当把元素的嵌套并列关系绘成一张图时,呈现出一种树状结构。HTML文档的这个结构被称为HTML DOM 树。这里了解一下就可以了。
注:下面这种写法是不规范的,虽然很多浏览器能理解:
<body> <h1> 标题文本 </body> </h1>
有少数标签是单独出现的,它们本身就是一个元素,具有空内容。这种标签相当于在开始标签处就被关闭了。如强制换行的<br />,和分割线<hr />。
在规范的HTML中,所有元素都应该被正确关闭。就算是单独出现的<br />,也应该像这样关闭,而不是采用不规范的<br>写法。类似地,虽然浏览器对标签名大小写不敏感,但标准的HTML规范推荐使用全小写标签。
附常用HTML标签一览(含萌百使用的插件) | ||
---|---|---|
名称 | 描述 | 在Wiki中 |
a | 定义锚/链接 | 内部链接:[[]] 外部链接:自动识别或用[]标记 |
b | 定义粗体文本 | '''文本''',但无法处理多行文本 |
big | 定义加大字体 | 相同 |
blockquote | 定义长引用文本 | 一般用更加美观的{{Cquote}}模板 |
br | 定义强制换行 | 相同 |
center | 定义居中元素 | 相同 |
code | 显示源代码(内联元素) | 相同 |
del | 定义删除线文本 | 相同(也有“-文本-”的写法,萌百已弃用) |
div | 定义文档的节(块级元素) | 非必需 |
h1 h2 ... h6 | 定义各级标题 | =标题= to ======标题======,但使用位置受限 |
hr | 定义分割线 | ---- |
i | 定义斜体文本 | ''文本'',但无法处理多行文本 |
img | 插入图像 | 内部图像:[[File:文件名|其他参数]] 外部图像:{{Outer_image}} |
li | 定义列表项 | 位于开头的*或#,对应无序列表与有序列表 |
p | 定义段落 | 文章部分两次换行 |
poem | 无定义 | 插件,取消换行合并,用于大段文本排版 |
pre | 显示为源代码(块级元素) | 相同 |
ruby | 定义注音文本 | 一般用{{Ruby}}模板 |
small | 定义缩小字号 | 相同 |
span | 定义文档的节(内联元素) | 非必需 |
sub/sup | 定义上/下标 | 相同 |
table(以及th、tr等) | 描述表格 | 详见第二讲Wiki表格 |
通过将各种HTML元素合理地进行嵌套组合,我们可以写出一个条理清晰,层次分明的HTMl文档。但显然,没有读者会愿意在像Word文档一样单调的网页上花费时间;同时,仅仅靠单纯的HTML标签并不能向文本提供足够的附加信息。为了使页面内容更加美观丰富,同时增强HTML的信息附加能力,HTML为标签增加了属性(attribute)。
属性是写在开始标签中,形如“属性名="值"”的键-值结构体。一个标签可以拥有任意多个属性,彼此之间以空格分隔。属性用于对元素的分类、外观、内容、特性等进行补充说明;在一些特殊的元素中,如果不添加必要的属性进行说明,该元素甚至是无意义的。
有一类属性是几乎所有元素共有,即可以赋予几乎任何一种元素的,这种属性称为全局属性。常见的全局属性有id、class、style和title等,这些我们会在接下来的章节中进行详细说明。而有的标签拥有一系列专有属性,它们仅在这类标签中有意义。还有一类特殊的属性,称为事件属性,用于控制文档的动态效果,这里涉及浏览器脚本等,故不在我们的讨论范围内。
标签、属性和内容,组成了HTML文档的基本单位——元素;而元素间的相互嵌套组合,则构成了HTML文档。本讲接下来的内容,都是在其基础上展开的。
本节我们将会了解两种使用最广泛的,也是最重要的全局属性:ID(id)和类(class)。两者在某种意义上是相近的:都是全局属性;都是用于给元素标注类别;都能被CSS选择器选择(见下节);都拥有完全由用户自定义的值。所以我们放在一起讲。
ID的特点在于其特称性,在于给元素一个独一无二的名字。就好比用户的用户名,一个用户只能有一个用户名,而在整个平台上,叫这个用户名的用户也只能有一个(至少在萌百是这样的)。也就是说,一个元素和它的ID是一一对应的,一个元素只允许有一个ID,而一个ID在整个HTML文档中只能出现一次。如果使用了两次或以上,不仅在文档逻辑上是混乱的,也可能引起冲突或达不到预期的结果。
类则是一种较宽松的属性。它的意义在于将某些元素标记为同一类。一个类中可以有任意多个元素,一个元素也可以属于任意多个类(一般写在同一个类属性的值中,彼此之间用空格间隔)。
示例:
<div id="sample-id-1" class="sample-class-1"> <li class="sample-class-2">我是sample-class-2类li元素</li> <li class="sample-class-2" id="sample-id-2">我也是sample-class-2类li元素,但我有一个ID叫“sample-id-2”</li> <li class="sample-class-3">我和你们都不一样,我是sample-class-3类li元素</li> <li class="sample-class-2 sample-class-3">我既是sample-class-2类li元素,也是sample-class-3类li元素</li> </div>
需要注意的是,ID和类均不会继承。即父元素(见上一节元素的嵌套部分)拥有某个ID或类,不意味着其子元素也拥有相同的ID和类。
ID和类为文档提供了更加严谨清晰的逻辑结构。它们真正发挥巨大作用是在CSS和DOM中,使得文档变得简洁而易于操控。在更加严谨规范的HTML(即XHTML中),每一个元素都必须拥有ID或者类中的至少一个。当你查看一些大网站(如bilibili)的源代码时,会发现它们几乎摒弃了其他所有的属性,只留下了ID和类(与此同时它们摒弃了大量用于描述元素外观的标签),把剩下的工作交给了CSS和JavaScript。这是一种先进的理念,即还原HTML的本质功能:描述文档逻辑结构。
当然在Wiki,这种要求是没有必要的。词条内容部分只是一段不完整的HTML,普通用户也不能控制全局CSS和JavaScript脚本。一般来说,我们不需要考虑ID,更具有实用意义的是类。
CSS(Cascading Style Sheets,层叠样式表)是Web的一个重要组成部分。它的意义在于为HTML元素设置表观样式。
一般来说,有四种CSS——或者说,四重CSS,这也是名称中“层叠”一词的由来。它们分别是:
在Wiki,由于权限的原因,一般编辑者能够控制的只有内联样式。但因为这四重样式是向上覆盖的,即后面的样式设置会覆盖前面的样式设置,所以这并不影响我们对页面内容的操控。所以我们将着重讲解内联样式。
内联样式是作为全局属性style的值,写在每一个被操控的元素开始标签内的,它由一连串CSS属性及其相应的值,以“CSS属性名:值”的形式连接而成,CSS属性之间以半角分号间隔。所以在这里,CSS属性,是属性里的“属性”。 示例:
<div style="font-size:20px; color:red; text-shadow: 0 0 8px yellow;">示例</div>
效果是这样的:
CSS属性与HTML属性有相似的地方,它们都可以控制元素的表现形式,但在这一点上CSS比HTML强大了太多。使用CSS控制元素表观已经成为了绝对的主流,许多旧的HTML标签和属性都被摒弃,以CSS代替。例如bgcolor属性,就可以用CSS属性background代替,而且使用后者时,还可以用渐变色、图片作背景,功能强大了许多。
CSS属性数量很多,绝大部分可以参考W3school CSS手册。利用常见的一些CSS属性,可以轻松地解决词条的字体设置和对齐排版等工作。由于这里只是一个简单的入门教程,不作详细介绍,读者可自行查询上述手册,掌握字体、背景、边框、文本属性的基础内容即可。如需进一步了解,可以选读下一节HTML元素的方盒模型,从而对HTML、CSS等有更深入的认识。
本节我们将了解HTML元素的通用模型与排版原则,属于比较内层的东西,大概了解一下即可,除非要进行比较复杂的设计,否则在实际生产中应用不多。
第一个内容是块级元素和内联元素;div元素和span元素。
大部分元素都可以被分为块级元素(block level element)和内联元素(inline element)。用通俗的语言描述的话,块级元素是文章里的一个自然段,内联元素是某一段里的一个字或者一句话。对于前者,浏览器会在其前后强制换行,而内联元素则不作处理。它们的排版方式很像打字:当你不主动输入换行符时,只要页面宽度允许,字(内联元素)会一个接一个地由左向右排列。当页面宽度不足时,将会自动换行。这种换行和强制换行不同,它是根据页面宽度自适应的,某个位置换行与否是不确定的。但当你输入换行符时,这一行就强制结束了,新的一段在新的一行重新开始。比如说Vocaloid中文殿堂曲页面使用的{{China_Temple_Song}}原型就具有内联元素的特征,在手机上看,一行只能显示两首曲目,而在一般的显示器上为三首,在宽屏显示器上甚至是四首。而块级元素,如标题元素,则会独占一行(不考虑其他定位效果)。
它们的另一个差别在于,块级元素可以设置width和height属性,而一般内联元素无效。此外,块级元素可以包含块级元素或者内联元素,但是内联元素不能包含块级元素。
常见的块级元素有h1...6、p、table、li等,内联元素则是img、b、a等(这点Wiki编辑者应该体验很深,就是有的时候你不空一行,它也给你换行了;但有的时候你如果不空一行,它就当成是连续的内容。这也和一些模板的设计有关)。不过大多数元素都可以通过设置display属性进行两种元素的转化。
然后我们就可以开始说div标签和span标签了。这两个标签与其他标签不一样,它们是没有实际意义的,因为它们是一种几乎没有预设样式的标签,唯一的预设是,div元素被认为是一个块级元素,span元素被认为是一个内联元素,除此之外不会对内容的样式作出任何改变。你在文本中作如下使用 文本1<span>文本2</span>文本3
不会对文本有任何外观上的改变。这种设计是很不寻常的,因为大部分的标签,都会对内容的显示样式作出控制,比如说 h1 预设下就会把文本显示为加大加粗的标题样式。
那这种标签的存在意义是什么?正如我之前提到的,有些标签在不定义属性的情况下,是无意义的,这种标签也与此类似。我们不仅可以通过设置style属性来控制整个元素和内容的外观,还可以设置id和class属性来将元素命名、分类,便于样式表或者浏览器脚本的动态控制。
事实上,div代表一个空白的块级元素,span代表一个空白的内联元素,它们是类似于通用模板的存在。通过对style的控制,div和span几乎可以模拟其他任何一个元素的表现形式;换句话说,其他的元素,只不过是在div或span的基础上,添加了若干属性或样式后再封装起来而已。因此在许多现代大型网站上,我们会发现前端工程师在设计网页主体(body)的部分时,已经摒弃了绝大多数的标签,广泛使用div和span体系,只辅以诸如a标签(显示超链接)和img标签(显示图片)等很少的几个不方便替代的标签。
第二个内容是方盒模型(box model),虽然官方翻译是框模型,但我认为直接用英文原义更好。方盒模型是CSS处理HTML元素整体外观显示时使用的一种模型。这里涉及四个概念:
图片来自W3School |
关系如右图所示。你可以这样理解:整个元素是一幅装潢好的画,最中间是元素的主体内容,相当于画纸,你想呈现的内容都在上面;padding是指这张画的衬底,衬底可能会比画作要更大一点,四周突出来没有被画纸覆盖的部分就成了内边距;border就是画框,画框可以很细或者很粗,甚至你可以不要画框;margin则是画作外面的防护玻璃罩,一般是透明的你看不见,但占据了实际的空间。这种理解方式可能是官方最终翻译为框模型的原因之一:padding、border和margin是三层框,框住了元素。而原义“方盒模型”则是从另一个角度去解释:element、padding、border和margin是几个大小不等的盒子,逐个嵌套起来成为整个元素。
通常的浏览器是这样处理方盒模型的:
更多关于方盒模型的解释见W3School CSS框模型。
于是我们明白,在一般的文档流中(即不使用特殊的定位模式),网页排版就是在往墙上挂画(方盒/框模型)。有时我们横着排过去(内联元素),有时我们挂一幅画就换下一行(块级元素)。当然,有的画本身也是一面墙。
本着实用性原则,本节介绍一部分生产生活中常用的特殊标签(含萌百安装的插件)的使用方法。本节将不定期更新。
references是萌百安装的一个Wiki插件,含两种标签:<ref>和<references>。作用是实现类似于章节脚注的功能。大体上,ref是用于插入注释文本,references是将注释文本汇总在一起。
文本1<ref name="wenben">引用自xxx</ref> 文本2<ref name="wenben" />
本节简单介绍一下HTML表格,不过不需要太了解,因为在Wiki有新的一套表格语义符号,更为简洁且易读写。本节是在具体讲Wiki表格之前,简要介绍一下底层原理作为铺垫。
HTML表格是由一系列标签实现的。比较基础的包括:
可以在table/tr/th/td处设置style来控制整个表格/整行/单个表头或方格的样式。
一个简单的表格:
表头1 | 表头2 |
---|---|
内容11 | 内容12 |
内容21 | 内容22 |
<table border="1"> <tr> <th>表头1</th> <th>表头2</th> </tr> //第一行结束 <tr> <td>内容11</td> <td>内容12</td> </tr> //第二行结束 <tr> <td>内容21</td> <td>内容22</td> </tr> //第三行结束 </table>
关于表格还有一些有趣而实用的性质,但略为复杂而且可能令人困惑,所以这些我们留到第二讲,在一个相对简化的环境下介绍。
在互联网的早期,很长一段时间里,HTML表格曾经统治了网页排版,即便是为了取代它的CSS标准出现很久以后。当时网络上的几乎所有网页都是用表格编排的,美工把预想图给设计师,设计师用层层嵌套的表格把网页划分成一个个大大小小的格子,把文字、图片和别的东西填进它们应该在的地方。当时的网页都是静态的,没有太复杂的需求,而且表格式排版确实直观而简单,故很快就成为了行业惯例,甚至最后发展到了,专门有人编写了一种程序,能够直接把美工给出的概念图变成表格式的HTML代码。
但随着时代的发展,这种方法的弊端暴露出来了。比如说,这种方式会令代码臃肿不堪,混乱而难以阅读的标签代码充斥了整个文件。再比如说,当你想更改网页内容时,你可能需要更改大量代码,甚至需要重新制作一个新的网页,这非常不利于网站的更新和维护。其他还有语义学等方面的问题,更不用说动态页面的实现。总之,进入新千年后,在新锐设计师的倡导下,各大公司逐渐放弃了表格式排版,DIV+CSS的排版模式开始成为主流标准,表格终于回归到本职工作:数据和信息的直观表示。
你可能没有注意到,事实上在萌百,表格负责了大部分的信息汇总工作。{{Navbox}}和{{Infobox}}是萌百和类维基网站最具代表性的模板,前者衍生出无数的大家族模板;后者衍生出无数的信息介绍模板,就连高度变形的{{Vocaloid_Songbox}}也是由后者衍生出来。而这两个模板都是用表格实现排版的,而它们的用途也确实近似于表格。
以上介绍的HTML知识虽然已经有所侧重并大大简化,但仍然是通用的HTML语言。但是当我们回到Wiki,会发现事情有一点不太一样。出于安全性的考虑,Wiki上的HTML使用是有限制的。比如说,Wiki上禁用了部分的HTML标签和功能,或者要求通过Wiki语言的形式转述。比如说,<a>元素,用于声明锚/链接的重要元素就是如此,编辑者只能通过标准的内/外部链接的格式生成链接。更多被禁用的HTML标签参见Help:HTML——不过一般确实不会用到这些。除此之外,Wiki可能还禁用了部分功能,包括在元素背景插入图片等。
同时,虽然HTML很强大,但实际生产中一般还是要避免滥用。许多样式已经有现成的封装好的模板,可以直接调用。这是为了简化页面,提高可读性和降低编辑门槛,毕竟Wiki的初衷是提供一种简单易学的网页语言。但不可否认的是,合理使用HTML可以做出很多奇妙的效果。
同时,本讲中介绍的HTML知识仅是非常简化的部分,事实上并不足以撰写一个完整的HTML文档,但应该足够应对日常的编辑需求。如需更完整的HTML教程,请参阅W3School。
此前我们曾就HTML表格进行了非常表层的说明,本讲正式介绍在Wiki语言系统下的表格撰写。为了方便理解,我们从一个大部分人都比较熟悉的软件开始——Excel。
打开一个Excel或者类似软件的文件,你会注意到它们最突出也最典型的特征:文档是由一个个格子整齐排列出来的。这些格子,叫单元格。希望大家记住我们在这里的定义,因为当我们以后谈论一些复杂表格的时候,还是要回到这样的一个个小格子上面。
每个单元格都可以标记一个行号和列号,按照习惯是从上到下,从左到右的。一组行号和列号唯一确定了某个单元格,所以我们以后用有序对<a, b>来代表第a行第b列的单元格。
因为表格在外观上要求对齐,所以在同一行的单元格有着相同的高度(height),同一列的单元格有着相同的宽度(width)。所以每一个单元格,其高度和宽度,是由所处的行的行高和所处列的列宽决定的。
在实际应用中,情况变得复杂起来,为了更好地表现数据的组织形式,人们需要进行单元格合并,表现上就是把它们之间的隔线擦除,并且数据可以自由地填充在剩下的整片空白处。这样的合并有横向的,即被合并的单元格在同一行且连续;也有纵向的,被合并的单元格在同一列且连续。关于复杂表格和单元格合并我们将会在后续章节深入介绍。
Wiki表格本质上是HTML表格,在不添加样式的时候是没有边框也没有底色的,这样对于初学者不直观,所以我们以后的表格都将带有Wiki系统自带的wikitable类。
Wiki表格的结构和HTML表格是一样的。撰写一个最简单的表格,首先你要用"{|"和"|}"来声明一个表格的代码域,正如<table>;用"|-"来声明每一行,正如<tr>;用"||"来在同一行内分隔单元格(这点有点不同)。别忘了在表格的抬头里加上wikitable类。例:
11 | 12 | 13 |
21 | 22 | 23 |
31 | 32 | 33 |
{| class="wikitable" // 表格抬头 |- // 声明第一行 | 11 || 12 || 13 // 第一行有三个单元格 |- // 声明第二行 etc. | 21 || 22 || 23 |- | 31 || 32 || 33 |} // 表格闭合
也可以这样写:
{| class="wikitable" // 表格抬头 |- // 声明第一行 | 11 | 12 | 13 // 第一行有三个单元格 |- // 声明第二行 etc. | 21 | 22 | 23 |- | 31 | 32 | 33 |} // 表格闭合
这两种写法是可以混用的。