Extension:Monstranto

From mediawiki.org
MediaWiki extensions manual
Monstranto
Release status: unstable
Latest version 0.1
MediaWiki >= 1.36
License GNU General Public License 2.0 or later
Download
README
Translate the Monstranto extension if it is available at translatewiki.net

Demo site: http://bawolff.net/monstranto/index.php/Main_Page

The Monstranto extension allows you to use Scribunto to create illustrations. Please note, this is still in the proof of concept stage, and not everything is implemented yet. However, enough is that you can install it, play with it, and perhaps develop an opinion on whether this is a good idea, or a terrible idea.

This extension is inspired by meta:User:Yurik/I Dream of Content. MediaWiki does not have a good story around using interactive multimedia. The main previous attempt to rectify this was Extension:Graph. However, in practice it seems like this has only seen limited use so far. As of September 2022, its used on a mere 15,000 main-space pages of English Wikipedia. More to the point, the vast majority of those uses are either simple line/bar graphs or simple map overlays. If you exclude {{Historical populations}}, {{Graph:Chart}},{{Graph:Map}},{{Television_ratings_graph}}, {{Graph:Lines}}, {{Map_with_marks}}, there are only 477 usages. Standard bar graphs of course fill an important need, but they are also far from being active learning experiences. The dream is not just to have some graphs to complement the text, but to allow readers to really understand the information in a different way - i.e. the difference between reading a book and going to a museum. For example, imagine something like https://observablehq.com/@tmcw/enigma-machine being on the w:Enigma machine article.

My belief is the reason that Extension:Graph did not catch on, is essentially it is both too low level and too high level at the same time:

  • The Vega syntax is hard to understand for normal people. It is too low level for the average Wikipedia editor.
  • The Vega syntax can be difficult to work with if you are trying to do something outside of its intended user case, thus being too high level
  • It is difficult to make abstractions over graph (too high level)

In Wikipedia, Scribunto has seen great success, as it gave some simple tools to editors, which allowed template maintainers to combine them in complex ways to make complicated abstractions. I think we should follow that approach with interactive content. This extension essentially hooks Lua up to SVG, allowing template editors to go wild. The theory is, that they can make abstractions that make sense resulting in easy to understand interfaces for less technical users, and the full freedom to do anything you can imagine for the technical users.

Hello World example[edit]

Try this on the demo site - http://bawolff.net/monstranto/index.php/Main_Page A simple example for this extension. This makes a circle which changes colour when you click on it.

Create the following Lua module, named Module:Demo:

local p = {}

-- Invoked in page the normal {{#invoke:demo|circle}} way
function p.circle( frame )
   local svg = mw.html.create( 'svg' )
       :attr{ xmlns = 'http://www.w3.org/2000/svg', width = '150', height = '150' }
       :tag( 'circle' )
       :attr{ cx = "50", cy = "50", r = "40", stroke = "black", ["stroke-width"] = "3", fill = "red", id = "c1" }
       :allDone()

   -- Other recognized options: width, height, svgFile (unimplemented), activation, callbackParameter, style       
   return mw.ext.monstranto.addIllustration{
		svgText = tostring(svg),
		activationCallback = { "Test", "activate" }
   }
end

-- Called when the user clicks play
function p.activate(svg, args)
	return svg:getElementById( 'c1' ):addEventListener( "click", p.changeColour )
end

-- Called when user clicks on the circle
function p.changeColour( element, event )
  local colours = { "red", "yellow", "blue", "green", "orange", "pink" }
  local index = math.floor(math.random()*(#colours) + 1)
  element:setAttribute( "fill", colours[index] )
end

return p

Then put {{#invoke:demo|circle}} on a page somewhere.

Installation[edit]

  • Download and move the extracted Monstranto folder to your extensions/ directory.
    Developers and code contributors should install the extension from Git instead, using:cd extensions/
    git clone https://gerrit.wikimedia.org/r/mediawiki/extensions/Monstranto
  • Add the following code at the bottom of your LocalSettings.php file:
    wfLoadExtension( 'Monstranto' );
    
  • Yes Done – Navigate to Special:Version on your wiki to verify that the extension is successfully installed.

Security & performance considerations[edit]

This extension is designed to use multiple levels of security to prevent XSS:

  • Brower iframe sandbox feature to render the svg in a null origin that has no access to site data
  • Content Security Policy to prevent scripts other than those expected.
  • Verify initial SVG is not scripted (And thus not interactive until user touches it) using both MW SVG validation, and DomPurify
  • Use MediaWiki's restrictions on attributes starting with data-mw to prevent user bypassing things.
  • [not yet implemented] Use Lua sandboxing so that dangerous APIs are not exposed at all

Cryptominers/client-side DoS: This extension tries to mitigate the risk, by requiring users to click on the illustration before any scripts are run. Additionally, the scripts have extremely limited network access, making exfiltrating information difficult. A future todo might be to look into resource limiting the client side lua with timeouts.

Its possible that large number of iframes on a page might have performance implications. If this is a concern we could make the initial content be an <img> tag and only add an iframe after the user has clicked to activate. We could also limit the max number of illustrations per page.

Potentially these illustrations could be large. If that becomes an issue, we could potentially partially mitigate this by putting the definitions at the end of the html instead of in a data attribute. This should ensure that we don't block page rendering on slow connections while we wait for everything to download.

See also[edit]

Essays: