ftml uses the term "block" to refer to the syntactical construction beginning in [[
, containing some text, and ending in ]]
. Examples include [[div]]
, [[module]]
, and [[span]]
.
The text after the [[
is the name of the block. This is always case-insensitive.
Blocks have five variable properties worth noting:
- The block may start with
[[*
rather than[[
. This is referred to as the "star" flag. - Their name may end in
_
. This is referred to as the "score" flag. This underscore is ignored if found in the foot. - The block may have some arguments before ending in
]]
. - The block may accept delimited newlines. This is explained in more detail below.
- The block may have a body. It has contents that are terminated by
[[/name]]
(wherename
is the block name), referred to as the block footer or tail.
Whether particular blocks accept these variables is noted in the table below. If a block does not permit that variance, then it will fail to parse.
Blocks may have one of the following approaches when parsing arguments:
Name | Example block | Method | Description |
---|---|---|---|
None | [[CSS]] |
BlockParser::get_head_none() |
Accepts no arguments. Tokens which are not ]] will result in parsing failure. |
Value | [[size 50%]] |
BlockParser::get_head_value() |
All of the text until ]] is interpreted as a single text value. |
Map | [[span id="abc"]] |
BlockParser::get_head_map() |
Accepts an arbitrary mapping of key="value" arguments. Values must be double-quoted, and may contain escapes (e.g. \" , \n ). |
Value + Map | [[iframe https://example.com/ style="width: 100%;"]] |
BlockParser::get_head_name_map() |
Accepts a single text value terminated by a space, then an arbitrary mapping as described above. |
Like block names, argument keys are case-insensitive.
Blocks may accept deliminated newlines. While these blocks can be used inline, separating them on their own lines will not produce line breaks. For instance:
The [[div]]
block accepts separate newlines. These two constructions are the same:
[[div]]Apple[[/div]]
[[div]]
Apple
[[/div]]
The [[span]]
block does not accept separate newlines. These two constructions are different, as the latter will add line breaks for each newline in the source:
[[span]]Banana[[/span]]
[[span]]
Banana
[[/span]]
How the bodies of a block are interpreted depends on its type. They fall into one of the following categories:
Name | Example block | Description |
---|---|---|
None | [[iframe]] |
Has no body. This block terminates at its head. |
Raw text | [[code]] |
Interprets the entire block body as raw text. Syntax is not parsed. |
Nested elements | [[div]] |
Interprets block contents as elements in a certain context. These are then nested in the block. |
Other | N/A | Uses some other means of interpreting its body. Some Wikidot blocks allow passing YAML for instance. |
Of note that while [[module]]
is its own block, it requires specifying a module name, and this behaves similarly to other blocks in that their attributes are determined by the module name.
See Modules for information on each module currently implemented.
A list of all blocks and their attributes is available at conf/blocks.toml
(with an explanation of the format in conf/blocks.schema.toml
. Our continuous integration system enforces that it is always up-to-date.
Alternatively you may look here for a formatted list: (though it may not be updated as consistently)
Block Name | Accepted Names | Star? | Score? | Newlines? | Argument Type | Body Type |
---|---|---|---|---|---|---|
Anchor | a , anchor |
No | Yes | No | Map | Elements |
Bibliography Citation | bibcite |
No | Yes | No | Value | None |
Bibliography | bibliography |
No | No | Yes | Map | (See below) |
Blockquote | blockquote , quote |
No | No | Yes | Map | Elements |
Bold | b , bold , strong |
No | No | No | Map | Elements |
Char | char , character |
No | No | No | Value | None |
Checkbox | checkbox |
Yes | No | No | Map | None |
Code | code |
No | No | Yes | Map | Raw |
Collapsible | collapsible |
No | No | Yes | Map | Elements |
Date | date |
No | No | No | Value + Map | None |
Deletion | del , deletion |
No | No | No | Map | Elements |
Div | div |
No | Yes | Yes | Map | Elements |
Embed | embed |
No | No | Yes | Value + Map | None |
Equation Reference | equation , eref , eqref |
No | No | No | Value | None |
Footnote | footnote |
No | No | No | None | Elements |
Footnote Block | footnoteblock |
No | No | Yes | Map | None |
Hidden | hidden |
No | No | Yes | Map | Elements |
HTML | html |
No | No | Yes | Map | Raw |
IfCategory | ifcategory |
No | No | Yes | Value | Elements |
IfTags | iftags |
No | No | Yes | Value | Elements |
Iframe | iframe |
No | No | Yes | Value + Map | None |
Image | image |
No | No | No | Value + Map | None |
Include (Elements) | include-elements |
No | No | Yes | Value + Map | None |
Include (Messy) | include-messy |
No | No | Yes | Value + Map | None |
Insertion | ins , insertion |
No | No | No | Map | Elements |
Invisible | invisible |
No | No | Yes | Map | Elements |
Italics | i , italics , em , emphasis |
No | No | No | Map | Elements |
Lines | lines , newlines |
No | No | Yes | Value | None |
List Blocks | ul , ol , li |
No | Yes | Yes | Map | Elements |
Mark | mark , highlight |
No | No | No | Map | Elements |
Math | math |
No | No | Yes | Value | Raw |
Math (Inline) | (See below) | No | No | No | (See below) | (See below) |
Module | module |
No | No | Yes | (See below) | (See below) |
Monospace | tt , mono , monospace |
No | No | No | Map | Elements |
Paragraph | p , paragraph |
No | No | Yes | Map | Elements |
Radio | radio , radio-button |
Yes | No | No | Value + Map | None |
Ruby | ruby |
No | No | Yes | Map | Elements |
Ruby text | rt , rubytext |
No | No | Yes | Map | Elements |
Ruby (short) | rb , ruby2 |
No | No | Yes | Value | None |
Size | size |
No | No | No | Value | Elements |
Span | span |
No | Yes | No | Map | Elements |
Strikethrough | s , strikethrough |
No | No | No | Map | Elements |
Subscript | sub , subscript |
No | No | No | Map | Elements |
Superscript | sup , super , superscript |
No | No | No | Map | Elements |
Tables | table , row , cell , hcell |
No | No | Yes | Map | Elements |
Tab Views | tabview , tabs |
No | No | Yes | None | Elements |
Tabs | tab |
No | No | Yes | Value | Elements |
Target | target , anchortarget |
No | No | Yes | Value | None |
TOC | toc |
No | No | Yes | Map | None |
Underline | u , underline |
No | No | No | Map | Elements |
User | user |
Yes | No | No | Value | None |
Each of the blocks will be described in more detail below:
Outputs: Element::Anchor
/ <a>
Body: Elements
Accepts score (_
): Strips leading and trailing newlines.
Arguments:
- All accepted attributes
Example:
[[a href="/scp-4000/noredirect/true" target="_blank" class="dual-link"]]Fae[[/a]]
Wikidot's syntax is to use ((bibcite ...))
, but ftml also supports [[bibcite ...]]
, as that is more customary.
By default, the block version ([[bibcite]]
) adds brackets around it, this can be disabled by using [[bibcite_]]
.
Outputs: Element::BibliographyCitation
/ <a class="wj-bibcite">
Body: None
Accepts score flag. (Block form only)
Arguments: Value — (String) The label name. (No spaces unless in block form)
Example:
On March 16, 1926,((bibcite rocket-1)) Robert H. Goddard launched his first liquid-fueld rocket.[[bibcite rocket-2]]
Outputs: Element::BibliographyBlock
/ <div class="wj-bibliography">
Body: A definition list with the references.
Arguments:
title
— (String) An alternate title for the bibliography block.hide
— (Boolean)true
means to not render this element. Default isfalse
.
Example:
[[bibliography]]
: rocket-1 : Smith, John (June 2000). "An informative article about Robert Goddard".
: rocket-2 : Doe, Jane. //The Rocket Which Can Fly//, book.
: impact : Another reference, you get the idea, you can have arbitrary wikitext here.
[[/bibliography]]
Outputs: Element::Container(ContainerType::Blockqote)
/ <blockquote>
Body: Elements
Accepts newline separation.
Arguments:
- All accepted attributes
Example:
[[blockquote]]
Some text here.
[[/blockquote]]
Outputs: Element::Container(ContainerType::Bold)
/ <strong>
Body: Elements
Arguments:
- All accepted attributes
Example:
Some [[b]]text![[/b]]
Outputs: Element::Text
Body: None
Arguments: Value — (String) The HTML entity to place here.
Example:
This file is [[char copy]] 2019-2024 Team Wikijump.
Outputs: Element::CheckBox
/ <input type="checkbox">
Body: None
Accepts star (*
): Element starts checked.
Arguments:
- All accepted attributes
Example:
[[checkbox]] Apple
[[*checkbox]] Blueberry
[[checkbox]] Cherry
[[checkbox]] Durian
Outputs: Element::Code
/ <pre class="wj-code"><code>
Body: Raw
Accepts newline separation.
Arguments:
type
— (String) What language this block is in, both for its Content-Type and syntax highlighting.
Example:
[[code]]
This text is **not** rendered as Wikitext, but output as-is!
[[/code]]
Output: Element::Collapsible
/ <div class="wj-collapsible-block">
Body: Elements
Accepts newline separation.
Arguments:
show
— (String) The text to present when text is collapsed (i.e. can be shown).hide
— (String) The text to present when text is expanded (i.e. can be hidden).folded
— (Boolean)true
means start collapsed (default),false
means start expanded.hideLocation
— (Enum: One oftop
(default),bottom
,both
, orneither
) Shows in what locations the hide collapsible link in.
Example:
[[collapsible show="+ Spoilers for Ouroboros" hide="- Spoilers!" hideLocation="bottom"]]
Overseers die.
[[/collapsible]]
Output: Element::Date / <span class="wj-date">
Body: None
Arguments:
format
— (String) What format to output the date in. Seechrono::format::strftime
for more information. Has a default format string if unspecified.tz
— (String) What timezone to put the date in. Either a string like+08:00
or-430
, or an integer representing the number of seconds to offset.hover
— (Boolean) Whether to show the amount of time until / since a date on hover.
Example:
The EN SCP Wiki was created on [[date 1216502818 hover="false"]].
Output: Element::Container(ContainerType::Deletion)
/ <del>
Body: Elements
Arguments:
- All accepted attributes
Example:
I [[del]]don't[[/del]] like that haircut.
Output: Element::Container(ContainerType::Div)
/ <div>
Body: Elements
Accepts score (_
): Strips leading and trailing newlines.
Accepts newline separation.
Arguments:
- All accepted attributes
Example:
[[div_ class="blockquote" style="border: none;"]]
Some text __here!__
[[/div]]
Output: Element::Embed
/ <div class="wj-embed"> (varies)
Body: None
This embeds a portion of another site. The following embeds are currently supported (names are case-insensitive):
YouTube
Vimeo
GitHub-Gist
GitLab-Snippet
For YouTube:
Arguments:
video
— The ID of the video. Forhttps://youtube.com/watch?v=dQw4w9WgXcQ
, then pass indQw4w9WgXcQ
.
For Vimeo:
Arguments:
video
— The ID of the video. Forhttps://vimeo.com/221821296
, then pass in221821296
.
For GitHub Gist:
Arguments:
username
— The user or organization who created the Gist.hash
— The hash representing this particular Gist.
For GitLab Snippet:
Arguments:
id
— The ID of this Snippet.
Example:
Check out my cool video!
[[embed youtube video="dQw4w9WgXcQ"]]
Output: Element::EquationReference
/ <span>
Body: None
Arguments:
- None
Example:
You can take the area of the circle[[eref Area-Circle]] and use it to find the object's volume.
Output: Element::Footnote
Body: Elements
Arguments:
- None
Example:
The author of The Dark Tower series[[footnote]]Did you know that world-renowned writer Stephen King was once hit by a car? Just something to consider.[[/footnote]] began work in the late 1970s.
Output: Element::FootnoteBlock
Body: None
Arguments:
hide
— (Boolean) Whether to hide the footnote block, effectively not rendering it.title
— (String) An alternate title to the footnote block. In English, the default isFootnotes
.
Hidden
Output: Element::Container(ContainerType::Hidden)
/ <span class="wj-hidden">
Body: Elements
Accepts newline separation.
Arguments:
- All accepted attributes
Example:
This text is **visible**.
[[hidden]]
This text is not.
[[/hidden]]
Output: Element::Html
/ <iframe>
Body: Raw
Accepts newline separation.
Arguments:
- None
Example:
[[html]]
<h2>Exciting!</h2>
<p>
This HTML will appear in an iframe hosted on wjfiles!
</p>
[[/html]]
Output: Element::IfCategory
Body: Elements
Accepts newline separation.
Arguments:
- A list of space separated category names, optionally prefixed with
+
or-
Example:
[[ifcategory +_default -component]]
This text won't appear in the component: category!
[[/ifcategory]]
Output: Element::IfTags
Body: Elements
Accepts newline separation.
Arguments:
- A list of space separated category names, optionally prefixed with
+
or-
Example:
[[iftags -admin -hub +scp +euclid]]
This appears if tagged {{scp}} and {{euclid}}!
[[/iftags]]
Output: Element::Iframe
/ <iframe>
Body: None
Accepts newline separation.
Arguments:
- All accepted attributes
Example:
My website:
[[iframe https://example.com/ class="website"]]
Output: Element::Image
/ <img>
Body: None
Arguments:
- Value — (String) The source of the image.
link
— (String) The link that this image should point to.- All accepted attributes.
This injects all elements gathered from another page into the current one. Because it deals with elements, it cannot "glue" syntax together or cause other hacky syntactical constructs.
Output: N/A
Body: None
Accepts newline separation.
Arguments:
- All arguments are passed as variables to the included page
Example:
[[include-elements component:some-bar
class="Keter"
classification="4"
taskforce="MTF-Eta-10 (\"See No Evil\")"
]]
This is not a typical block, as it is handled in the preprocessor. Parsing here is handled differently, but this block is still documented for completion sake.
This is a messy include, meaning that the page source is pasted directly in, prior to tokenization. It exists for compatibility with Wikidot.
Output: N/A
Body: None
Accepts newline separation.
Arguments:
- All arguments are passed as variables to the included page
Example:
[[include-messy theme:black-highlighter-theme]]
[[include-messy component:fancy-object-class
class=Keter |
classification=4 |
taskforce=MTF-Eta-10 ("See No Evil")
]]
Output: Element::Container(ContainerType::Insertion)
/ <ins>
Body: Elements
Arguments:
- All accepted attributes
Example:
I would like some [[ins]]anchovy[[/ins]] pizza please, thank you.
Output: Element::Container(ContainerType::Invisible)
/ <span class="wj-invisible">
Body: Elements
Accepts newline separation.
Arguments:
- All accepted attributes
Example:
This text appears [[invisible]]but still takes up space, and can be selected.[[/invisible]]
More correct and much more portable than setting the font color to "white".
Output: Element::Container(ContainerType::Italics)
/ <em>
Body: Elements
Arguments:
- All accepted attributes
Example:
This text is regular, but [[em]]this text is emphasized[[/em]].
Output: Element::LineBreaks
/ <br>
Body: None
Accepts newline separation.
Arguments: Value — (Positive integer) Number of line breaks to output
Example:
[[newlines 4]]
[!-- Much easier than spamming "@@@@"s --]
Input: [[ul]]
, [[ol]]
, [[li]]
Output: Element::List
/ <ul>
/ <ol>
/ <li>
Body: Elements
Arguments:
- All accepted attributes
Example:
[[ul]]
[[ol]]
[[li]] Item A [[/li]]
[[li]] Item B [[/li]]
[[/ol]]
[[li]] Item C [[/li]]
[[/ul]]
The parser will produce a warning if [[li]]
items are not within an [[ol]]
or [[ul]]
block.
Output: Element::Container(ContainerType::Mark)
/ <mark>
Body: Elements
Arguments:
- All accepted attributes
Example:
This text is [[mark]]highlighted![[/mark]]
Output: Element::Math
/ <div class="wj-math-block">
Body: Raw
Accepts newline separation.
Example:
[[math my-label
Output: Element::MathInline
/ <span class="wj-math-inline">
Special syntax: [[$ (LaTeX code here) $]]
.
Example:
This is actually equivalent to the exponential function, [[$ e^x $]]!
Output: Element::Module
/ Depends on module type
Body: Depends on module type
Accepts newline separation.
Arguments:
Example:
[[module NameOfModuleHere someArgument="yes"]]
Output: Element::Container(ContainerType::Monospace)
/ <tt>
Body: Elements
Arguments:
- All accepted attributes
Example:
[[tt]]This output looks like it came from a typewriter or computer terminal.[[/tt]]
Output: Element::Container(ContainerType::Paragraph)
/ <p>
Body: Elements
Arguments:
- All accepted attributes
Example
[[p]]My contents of a paragraph here.[[/p]]
Accepts star (*
): Element starts selected.
Body: None
Output: Element::RadioButton
/ <input type="radio">
Arguments:
- All accepted attributes
Example:
Favorite kind of music:
[[radio music]] Disco
[[radio music]] Dance
[[radio music]] Rap
[[*radio music]] Noise
See also: <ruby>
block on MDN
Output: Element::Container(ContainerType::Ruby)
/ <ruby>
Body: Elements
Arguments:
- All accepted attributes
Example:
[[ruby]]語 [[rt]]go[[/rt]][[/ruby]]
Only permitted within a [[ruby]]
block. See above for example.
Output: Element::Container(ContainerType::RubyText)
/ <rt>
Body: Elements
Arguments:
- All accepted attributes
A shorter form of [[ruby]]
and [[rt]]
, when specialized styling is not needed.
Output: Element::Container(ContainerType::Ruby)
/ <ruby><rt>
Body: None
Arguments:
- Takes a value, separated by a pipe. The main text is first, then the ruby annotation text after. Any spacing is trimmed.
Example:
[[rb 語|go]]
Output: Element::Container(ContainerType::Size)
/ <span style="font-size: XXX;">
Body: Elements
Arguments: Value — (String) The CSS string denoting what size should be used here.
Example:
This text is regular, but [[size 250%]]this text is much larger[[/size]].
Output:Element::Span
/ <span>
Body: Elements
Accepts score (_
): Strips leading and trailing newlines.
Arguments:
- All accepted attributes
Example:
This text is in a span: [[span class="fruit"]]banana[[/span]]
Output: Element::Container(ContainerType::Strikethrough)
/ <s>
Body: Elements
Arguments:
- All accepted attributes
Example:
This text is [[s]]struck through![[/s]]
Output: Element::Container(ContainerType::Subscript)
/ <sub>
Body: Elements
Arguments:
- All accepted attributes
Example:
Let this variable be called x[[sub]]A[[/sub]].
Output: Element::Container(ContainerType::Superscript)
/ <sup>
Body: Elements
Arguments:
- All accepted attributes
Example:
Thus, the result is n[[sup]]2[[/sup]].
Input: [[table]]
, [[row]]
, [[cell]]
, [[hcell]]
Output: Element::Table
/ <table>
/ <tr>
/ <td>
/ <th>
Body: Elements
Arguments:
- All accepted attributes
Example:
[[table]]
[[row]]
[[hcell]] Name [[/hcell]]
[[hcell]] Price [[/hcell]]
[[hcell]] Stock [[/hcell]]
[[/row]]
[[row]]
[[cell]] Banana [[/cell]]
[[cell]] $0.30 [[/cell]]
[[cell]] 87 [[/cell]]
[[/row]]
[[row]]
[[cell]] Cherry [[/cell]]
[[cell]] $0.80 [[/cell]]
[[cell]] 64 [[/cell]]
[[/row]]
[[/table]]
The parser requires a structure of [[table]]
containing only [[row]]
s, and
those containing only [[cell]]
s or [[hcell]]
s. Cells may contain other tables.
Input: [[tabview]]
, [[tabs]]
, [[tab]]
Output: Element::TabView
/ <div class="wj-tabview">
Body: Elements
Arguments:
- None — For
[[tabview]]
- Label — For
[[tab]]
Example:
[[tabview]]
[[tab Fruits]]
* Apple
* Banana
* Cherry
[[/tab]]
[[tab Reward]]A golden crown[[/tab]]
[[tab Empty!]]
[[/tab]]
[[/tabview]]
Input: [[#]]
, [[target]]
, [[anchortarget]]
Output: Element::AnchorName
/ <a id="[name]">
Body: None
Arguments:
- Anchor name
Creates an anchor at the given location, allowing local navigation to it.
For instance, creating an anchor foo-bar
allows jumping to it via page-name#foo-bar
.
Wikidot only supports the [[#name]]
syntax, the [[target]]
block was added to
make it less visually confusing with [#name ...]
syntax.
Example:
[[#apple]]
[[target banana]]
[[anchortarget cherry]]
Name: Table of Contents
Output: Element::TableOfContents
/ <div class="wj-toc">
Body: None
This permits alignment, you can specify this using [[f>toc]]
or [[f<toc]]
in addition to its base form.
Example:
[[toc]]
Output: Element::User
/ <div class="wj-user-info">
Body: None
Accepts star flag
Example:
Created by [[user michal-frackowiak]]! ;-)
Output: Element::Container(ContainerType::Underline)
/ <u>
Body: Elements
Arguments:
- All accepted attributes
Example:
[[u]]Testing log 7192-45:[[/u]]