Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to add a link in MediaWiki VisualEditor Toolbar?

I`m trying to insert a custom link to a special page in VisualEditor toolbar. See the image below.

Link PositionSee Image

I googled a lot but without success. Someone please give a path...

like image 755
ricardogobbo Avatar asked May 16 '15 06:05

ricardogobbo


1 Answers

My answer is based on the following resources:

  • MediaWiki core JS doc (ooui-js)
  • VisualEditor JS doc (+ reading code of both repositories used for VE, mediawiki/extension/VisualEditor and VisualEditor)

Also, I'm pretty sure, that there is no documented way of adding a tool to the toolbar in VE, as far as I know. Although it's possible to add a tool to a group, which is already added, mostly used for the "Insert" tool group, like in Syntaxhighlight_GeSHi). There is, probably, a much easier or "better" way of doing this :)

First, VisualEditor provides a way to load additional modules (called plugins) when the main part of VE loads (mostly, when you click the "Edit" button). The modules needs to be registered via the global variable $wgVisualEditorPluginModules (or the equivalent in extension.json, if you're using the new extension registration). In your extension registration file, you should initialize a module (with your required script files to add the tool) and add it as a VE plugin.

Example PHP (old extension registration via PHP files):

// other setup...
$wgResourceModules['ext.extName.visualeditor'] = array(
    'localBasePath' => __DIR__,
    'remoteExtPath' => 'extName'
    'dependencies' => array(
        'ext.visualEditor.mwcore',
    ),
    'scripts' => array(
        'javascripts/ve.ui.ExtNameTool.js',
    ),
    'messages' => array(
        'extname-ve-toolname',
    ),
);
$wgVisualEditorPluginModules[] = 'ext.extName.visualeditor';
// other setup...

extension.json (new JSON-based extension registration):

// other setup...
"ResourceModules": {
    "ext.geshi.visualEditor": {
        "scripts": [
            "javascripts/ve.ui.ExtNameTool.js"
        ],
        "dependencies": [
            "ext.visualEditor.mwcore"
        ],
        "messages": [
            "extname-ve-toolname"
        ]
   }
},
"VisualEditorPluginModules": [
    "ext.extName.visualeditor"
],
// other setup...

Now, if VE starts, it will load your module, named ext.extName.visualeditor in this example, with the script ve.ui.ExtNameTool.js. In this script, you can now do, what ever you want. As an example, this is a way to add a new module to the end of the toolgroup list in the toolbar:

Example of ve.ui.ExtNameTool.js:

( function () {
    // create a new class, which will inherit ve.ui.Tool,
    // which represents one tool
    ve.ui.extNameTool = function extNameTool( toolGroup, config ) {
        // parent constructor
        ve.ui.extNameTool.super.apply( this, arguments );
        // the tool should be enabled by default, enable it
        this.setDisabled( false );
    }
    // inherit ve.ui.Tool
    OO.inheritClass( ve.ui.extNameTool, ve.ui.Tool );
    // every tool needs at least a name, or an icon
    // (with the static property icon)
    ve.ui.extNameTool.static.name = 'extname';
    // don't add the tool to a named group automatically
    ve.ui.extNameTool.static.autoAddToGroup = false;
    // prevent this tool to be added to a catch-all group (*),
    although this tool isn't added to a group
    ve.ui.extNameTool.static.autoAddToCatchall = false;
    // the title of the group (it's a message key,
    // which should be added to the extensions i18n
    // en.json file to be translateable)
    // can be a string, too
    ve.ui.extNameTool.static.title =
        OO.ui.deferMsg( 'extname-ve-toolname' );
    // onSelect is the handler for a click on the tool
    ve.ui.extNameTool.prototype.onSelect = function () {
        // show an alert box only, but you can do anything
        alert( 'Hello' );
        this.setActive( false );
    }
    // needs to be overwritten, but does nothing so far
    ve.ui.extNameTool.prototype.onUpdateState = function () {
    ve.ui.extNameTool.super.prototype.onUpdateState.apply( this, arguments );
    }
    // the tool needs to be registered to the toolFactory
    // of the toolbar to be reachable with the given name
    ve.ui.toolFactory.register( ve.ui.extNameTool );
    // add this tool to the toolbar
    ve.init.mw.Target.static.toolbarGroups.push( {
        // this will create a new toolgroup with the tools
        // named in this include directive. The naem is the name given
        // in the static property of the tool
        include: [ 'extname' ]
    } );
} )();

After installing the extension in your LocalSettings.php and starting VE, you should see a new tool in the toolbar with the given name. Clicking it will show an alert box with content "Hello". Like written in the inline comments: In the click handler (onSelect) you can do whatever you want, e.g. open a link in a new tab, e.g. to a Special page. To get the link to a special page I would suggest to use mw.Title to get a localized namespace. For example:

var relativeUrl = mw.Title.newFromText( 'RecentChanges', -1 ).getUrl();

The first parameter of mw.Title.newFromText() is the name of the page, the second parameter is the ID of the namespace (-1 is the default for special pages and should always work).

I hope that helps!

like image 61
Florian Avatar answered Oct 18 '22 12:10

Florian