Flexible Fields for MediaWiki

From Meta, a Wikimedia project coordination wiki

Rationale[edit]

A previous proposal for adding Field-value pairs to MediaWiki suggested a rationale which included potential uses:

  • categorization -- saying that particle physics is in the physics category, or that Lord of the Rings is in the fantasy books category
  • relationships between articles -- break up a single page into multiple chapters or sections, and note that they're all part of the same article
  • synopses -- providing a synopsis or description of an article
  • geography -- marking up pages to specify that they cover a particular geographical location
  • customizable per-installation metadata -- metadata that may make sense for different installations.

This proposal is appropriate for those uses, but attempts to be more general in its allowable values and rendering possibilities.

Design[edit]

Legal Names and Values[edit]

Fields have names much like those of PHP variables: they begin with a letter or underscore character, and continue with alphanumeric or underscore characters.

Examples of legal field names:

title
subhead2
legal_disclaimer
_relatedArticle

Legal field values may be any string (possibly including wikitext) or an associative array of field names ("keys") to values. A shorthand for referring to field values nested inside an associative array uses '.' to indicate indexing into the array. For example:

author.affiliation
footnote.1
edition.1.publishDate

Declaration Markup[edit]

Fields are defined by either the <ff> tag.

<ff> with no 'name' attribute allows multiple defines in a scripting-like syntax. One field is defined per line, in the form "name = value". No quoting of the value is required, and whitespace around the name or value is trimmed. Shell-style comment lines, beginning with '#', are allowed. Referring to a nested field value creates the implied enclosing associative array. For example:

<ff>
title = A Brief History of Time
author = Stephen Hawking
chapterTitle.1 = Our Picture of the Universe
chapterTitle.2 = Space and Time
# etc
</ff>

<ff> with a 'name' attribute allows the definition of a single field value spanning multiple lines or with significant leading or trailing whitespace. The 'name' attribute to the tag supplies the field name. For example:

 <ff name="synopsis"><i>A Brief History of Time</i> attempts 
 to explain a range of subjects in cosmology, including the Big Bang, 
 black holes, light cones and superstring theory, to the nonspecialist
 reader.</ff>
 

If field declarations are repeated with the same name, an associative array with numeric keys is created. Each declaration is considered to have an implied '.n' after it, with n beginning at 0 and incrementing for each declaration. For example:

 <ff>
 contributor = John Doe
 editor = Anonymous
 contributor = Alan Smithee
 contributor = Publius
 </ff>

...is equivalent to...

 <ff>
 contributor.0 = John Doe
 editor = Anonymous
 contributor.1 = Alan Smithee
 contributor.2 = Publius
 <ff>

Rendering[edit]

Simple Display[edit]

Field declarations are equivalent to whitespace for wikitext rendering -- they have no effect on display at the point of their appearance.

Field values may be expanded elsewhere in the article's wikitext by name, much like the existing variables. However, to avoid confusion with those other special values and templates, article-defined field names should be preceded with a '$' when expanded. For example:

  {{$synopsis}}

If a field name is used whose value is an associative array, the value of its first item is expanded in its place. (That is, a field name without an index into its associative array may be considered a shorthand for its first value.) For example:

<ff>
contributor.0 = John Doe
contributor.1 = Publius
</ff>
{{$contributor}}

The reference to $contributor will expand to "John Doe".

Wikitext formatting within the expanded field value works.

All field declarations are considered to have completed as a first step before other wikitext is interpreted. So, declarations late in the Wikitext can be expanded before they appear. For example, this wikitext would display the "Stephen Hawking" value inline:

 The author of this book is {{$author}}.

 The book was originally published in 1988.
 <ff>
 author = Stephen Hawking
 </ff>
 

Due to the order in which article components are parsed:

  • Fields declared in the enclosing article *are* visible to included templates.
  • Fields declared in included templates are *not* visible in the enclosing article.
  • Fields declared in templates *are* visible to templates that appear later.

Advanced Display[edit]

Conditional Display: is_set, is_unset, is_string, and is_array[edit]

The <is_set> tag provides a mechanism for including wikitext conditionally based on whether a field is defined. It takes one attribute, 'name'. For example:

 <is_set name="book">
 The author of this book is {{$book.author}}.
 The publication year of this book is {{$book.publicationYear}}.
 </is_set>

The <is_unset> tag is analogous.

The <is_string> tag provides a mechanism for including wikitext conditionally based on whether a field is defined and has a string (as opposed to array) value. For example:

 <is_string name="book.author">
 The author of this book is {{$book.author}}.
 </is_string>

The <is_array> tag is analogous.

Iterated Display: foreach[edit]

The <foreach> tag provides a mechanism for iterating over fields. It takes three optional attributes: 'field', 'key', and 'value'.

The 'field' attribute specifies the fields over which the <foreach> applies. If absent or zero-length, all fields in the article are included. If the referenced field is not an array, if <foreach> operates on its single value. If the referenced field is not defined, the <foreach> does nothing. (The <foreach> can essentially serve as an "if defined" operator for simple fields.)

The 'key' attribute specifies a temporary field name, whose scope is strictly within the <foreach> tag, which takes on the value of each item's field name or array key in turn.

The 'value' attribute specifies a temporary field value, whose scope is strictly within the <foreach> tag, which takes on the value of each item in turn.

For example:

<fields>
contributor.1.name = Professor Plum
contributor.1.affiliation = Miskatonic U
contributor.2.name = Colonel Mustard
contributor.2.affiliation = Kentucky National Guard
</fields>
<foreach field="contributor" value="c">
 {{$c.name}}, <i>{{$c.affiliation}}</i>
</foreach>

This <foreach> would expand to:

 Professor Plum, <i>Miskatonic U</i>
 
 Colonel Mustard, <i>Kentucky National Guard</i>
Example: Recursive Display of all Fields[edit]

[In progress; may need work. Intent of specification is to allow such a template to be made, if only for debugging purposes.]

It should be possible to include a template which displays all defined fields.

 {{fields|f=|indent=}}

Template 'fields':

 <foreach field="{{{f}}}" key="key" value="value">
  <is_string field="key">
   {{{indent}}}{{$key}}={{$value}}
  </is_string>
  <is_array field="key">
   {{{indent}}}{{$key}}:
   <foreach field="key"}
    {{fields|f={{$key}}|indent=  {{{indent}}} }}
   </foreach>
  </is_array>
 </foreach>

Implementation and Database[edit]

To be determined.

Future Directions[edit]

There should be a mechanism for MediaWiki skins to refer to the field values within an article being rendered.