Jump to content

Extension:Mustache

From mediawiki.org
MediaWiki extensions manual
Mustache
Release status: experimental
Implementation Parser function
Description Allows trusted users to create raw HTML snippets and mustache templates that can be used on content pages with the {{#mustache and {{#html parser functions.
Author(s) PetraMagnatalk
Latest version 0.1.0
MediaWiki 1.45+
Database changes No
Licence GNU General Public License 2.0 or later
Download

The Mustache extension allows trusted users with editsitecss and editsitejs rights to create raw HTML snippets and mustache templates that can be used on content pages with the {{#mustache and {{#html parser functions.

Installation

[edit]
  • Download and place the file(s) in a directory called Mustache in your extensions/ folder.
  • Add the following code at the bottom of your LocalSettings.php file:
    wfLoadExtension( 'Mustache' );
    
  • Run composer update --no-dev to install the mustache.php library.
  • Yes Done – Navigate to Special:Version on your wiki to verify that the extension is successfully installed.

Permissions

[edit]

Editing Mustache templates and HTML pages requires both editsitecss and editsitejs rights. This is typically granted to interface administrators.

Using templates and HTML pages via the parser functions does not require any special rights and is available to all users who can edit.

Configurations

[edit]
$wgMustacheCacheType
Cache backend for compiled Mustache templates. Values: 'none' (disable caching), 'filesystem' (write PHP files to $wgMustacheCacheDir), 'mediawiki' (use MediaWiki's configured object cache via BagOStuff).
Default: none.
$wgMustacheCacheDir
Directory path for compiled Mustache template cache. Only used when $wgMustacheCacheType is 'filesystem'.
Default: ''
$wgMustacheDisableTemplates
When true, Mustache template rendering is disabled. Only raw HTML via {{#html: remains functional.
Default: true

HTML pages

[edit]

Creating HTML pages

[edit]

Users with the appropriate permissions can create and edit pages in the HTML namespace (ID 9210). HTML pages contain raw HTML with no template interpolation and are not validated or sanitized.

Example HTML page at Html:Button:

<div class="button-container">
  <button type="button" onclick="alert('button clicked')">Click me</button>
  <style>
    .button { padding: 4px 8px; }
  </style>
  <script>
    console.log("Button loaded");
  </script>
</div>

Using HTML Pages

[edit]

Any user can include HTML pages as a snippet in the current page using the {{#html: parser function. HTML snippets are rendered as-is with no validation or sanitization. They do not support variable interpolation.

Here is a button: {{#html:Button}}

The snippet above will transclude the HTML page verbatim.

Mustache templates

[edit]

Creating Mustache templates

[edit]

Users with the appropriate permissions can create and edit pages in the Mustache namespace (ID 9200).

Suppose we have a page on Mustache:Card:

<div class="card">
  <!-- simple Mustache variable -->
  <div style="font-size: larger">{{title}}</div>
  <div style="color: {{ color|css-value }}">You have set the text color to {{color}}</div>
  <!-- Mustache sections, which are similar to #if in that empty strings are treated as false -->
  <p>
    {{#show}}You have set <code>show</code> to true.{{/show}}
    {{^show}}You have set <code>show</code> to false.{{/show}}
  </p>
  <!-- nested structures, which accesses nested data structures in JSON or Lua -->
  <p>Name: {{ person.name }}</p>
  <p>Age: {{ person.age }}</p>
  <!-- loops, which accesses nested data structures in JSON or Lua -->
  {{#items}}
    <div class="item">{{name}}: {{value}}</div>
  {{/items}}
</div>
<style>
.card {
	width: 100%;
}
.item {
	padding-left: 4px;
}
</style>
<script>
console.log( {{ message|js-string }} );
</script>

Using Mustache Templates

[edit]

Any user can include Mustache templates using the {{#mustache:}} parser function.

{{#mustache:Card
|title=Example Mustache usage
|color=blueviolet
<!-- leaving this empty implies false; otherwise it would be true -->
|show=
<!-- this JSON structure enables {{ person.name }} to be inserted properly -->
|person={ "name": "Shiroko", "age": 17 }
<!-- this JSON structure enable looping -->
|items=[
	{"name": "Apple", "value": "$3 each"},
	{"name": "Banana", "value": "$1 each"},
	{"name": "Orange", "value": "$2 each"}
]
|message=Hello world!
}}

The output of the above invocation would be as follows. Note that comments would also be preserved but are removed for brevity.

<div class="card">
  <div style="font-size: larger">Example Mustache usage</div>
  <div style="color: blueviolet">You have set the text color to blueviolet</div>
  <p>

    You have set <code>show</code> to false.
  </p>
  <p>Name: Shiroko</p>
  <p>Age: 17</p>
    <div class="item">Apple: $3 each</div>
    <div class="item">Banana: $1 each</div>
    <div class="item">Orange: $2 each</div>
</div>
<style>
.card {
	width: 100%;
}
.item {
	padding-left: 4px;
}
</style>
<script>
console.log('Hello world!');
</script>

Passing JSON strings

[edit]

Because JSON strings have strict syntactical requirements, it's recommended to use an auxiliary template to construct the JSON string. See Miraheze Dev Wiki's Json module for an example.

Supported Mustache syntax

[edit]
  • Variables: {{variable}}
  • Filters: {{ variable|filter-name }} (see Security for available filters)
  • Sections (essentially #if): {{#section}}...{{/section}}
  • Inverted sections: {{^section}}...{{/section}}
  • Comments: {{! comment }}
  • Dotted names for nested access: {{user.name}}
  • Loops over arrays: {{#items}}...{{/items}}

Lua integration

[edit]

The Mustache extension provides a Lua library mw.ext.mustache that allows Scribunto modules to render Mustache templates programmatically. This is more ergonomic than producing JSON data.

To use the Lua library, invoke the render function with the page name and a Lua table containing the data. For example, to use Mustache:Card, write the following in a Lua function.

local data = {
    title = "Example",
    person = {
    	name = "Shiroko",
    	age = 17
    },
    items = {
    	{ name = "Banana", value = "$2" },
    },
}
local result = mw.ext.mustache.render("Card", data)

Security

[edit]

For detailed security considerations, see the SECURITY.md file.

When creating Mustache templates, it is important to understand how data passed from regular users is handled to avoid cross-site scripting (XSS) attacks. This extension aggressively rejects code patterns that may lead to XSS.

  • Special characters are automatically escaped in the default {{variable}} output: &, <, >, and ".
  • Raw interpolation using {{{ or {{& is not allowed.
  • Variables inside <script> tags must use a js-* filter (js-string or js-identifier). Variables inside <style> tags must use a css-* filter (css-selector or css-value). Templates that violate this are rejected on save.
  • Variables in HTML attributes are only allowed for whitelisted attributes: id, class, style, title, alt, name, for, href, src, value, placeholder, width, height, rowspan, colspan, tabindex, data-*, and aria-*. The appropriate filter must be applied: url for href/src, css-value for style, and attribute for all others.

Integrating with other extensions

[edit]

Mustache works with Extension:TemplateSandbox and Extension:CodeEditor. Note that Extension:CodeMirror is currently not supported due to CodeMirror 6 not yet supporting HTML.

See also

[edit]