VisualEditor/Tag extensions

This tutorial explains how to integrate tag extensions with the visual editor. While geared toward a specific kind of extension, it may be of use for other kinds of extensions involving editing. For related information see VisualEditor/Gadgets and for examples see Extension:Score, Extension:SyntaxHighlight, and others in Category:Extensions with VisualEditor support.

Background edit

VisualEditor has three layers:

  • DM: DataModel
  • CE: ContentEditable
  • UI: UserInterface

As a simplified view, the user can interact directly with the UserInterface and ContentEditable, both of which then translate the user's input into the DataModel. The DataModel is never exposed to the user.

For this tutorial, we only need a broad sense of the layers, but further details can be found at the main documentation.

Diretory structure and naming edit

The code is a resource loader module, and to keep it organized CisualEditor-related code is usually located in its own subdirectory of the modules folder.

The JavaScript is object oriented and structured as multiple class objects. Each of these objects should be in their own file. The files are named using the scheme ve.LAYER.MWFileName.js. The ve at the start indicates that the file is a VisualEditor module. The layer is one of the three described above in lower case: dm, ce, or ui. This details what layer the object interacts with. The file name usually has MW at the start to indicate that it is a mediawiki extension; because VisualEditor is a general HTML editor, it's possible that some objects are not mediawiki related, so it is best to be clear from the start.

Registering the module edit

The visual editor module must be registered in your extension's extension.json in order to work. Two main edits are required:

First, edit the "ResourceModules" section to include a module for the visual editor like:

{
  "ResourceModules": {
    "ext.chess.visualEditor": {
      "scripts": [
        "modules/ve-chess/ve.dm.MWPgnNode.js"
      ],
      "dependencies": [
        "ext.visualEditor.mwcore"
      ]
  }
}

Remember to include the dependency on the visual editor core module.

Second, add or edit the "attributes" to register which resource module should be loaded with the visual editor:

{
  "attributes": {
    "VisualEditor": {
      "PluginModules": [
        "ext.chess.visualEditor"
      ]
  }
}

Data model edit

Content editable edit

User interface edit