Extension: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 | GitHub:
Note: |
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
Mustachein yourextensions/folder. - Add the following code at the bottom of your LocalSettings.php file:
wfLoadExtension( 'Mustache' );
- Run
composer update --no-devto install the mustache.php library.
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
$wgMustacheCacheTypeis '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 ajs-*filter (js-stringorjs-identifier). Variables inside<style>tags must use acss-*filter (css-selectororcss-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-*, andaria-*. The appropriate filter must be applied:urlforhref/src,css-valueforstyle, andattributefor 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]- Extension:Widgets. This extension aims to be a substitute for Widgets because some wikifarms refuse to support it citing security reasons.
- Mustache Template extension (Chinese) on Huijiwiki. A proprietary extension that inspired the approaches of this extension.
