From a custom user script running on a MediaWiki site such as User:Username/common.js
or User:Username/vector.js
I wish to add some functionality when the user is editing a section.
But to get the correct context I need to know which section they're editing by name and the sections parents in the section/subsection hierarchy.
I know I can parse the URL to get a section number but I can't find a straightforward way to go from that number to the name of the section or its position in the section structure. I know there are a bunch of variables accessible in various ways by JavaScript with names beginning wg
but so far I can't find any that are relevant.
The obvious hack is to load the related page via AJAX and parse either the TOC if there is one or the page layout otherwise. This seems expensive and may not even be so easy if there are sections using <h3>X</h3>
tags rather than ===X===
style wikitext.
Perhaps there's something in the current MediWiki JavaScript interface I haven't been able to find?
(Use case is the English Wiktionary where unlike on Wikipedia the same section names can occur several times such as "Noun" being under both "English" and "Italian", etc.)
You can use the Parsing API to get the sections of the current page. prop=sections
is what you'll want. Then it's a matter of looping through the result and getting what you want.
Example output for the table page:
{
"parse": {
"title": "table",
"sections": [
{
"toclevel": 1,
"level": "2",
"line": "English",
"number": "1",
"index": "1",
"fromtitle": "table",
"byteoffset": 21,
"anchor": "English"
},
{
"toclevel": 2,
"level": "3",
"line": "Etymology",
"number": "1.1",
"index": "2",
"fromtitle": "table",
"byteoffset": 223,
"anchor": "Etymology"
},
// ...
]
}
}
The following should give you an array with the relevant sections (in reverse: current section is sections[0]
, parents are sections[1]
etc. if any)
$(document).ready(function(){
// Whitelist allowable Namespaces here
if( mw.config.get('wgNamespaceNumber') !== 0 ) return;
if( ['edit','submit'].indexOf(mw.config.get('wgAction')) > -1 ) {
var sectionId = $("#editform input[name=wpSection]").val();
if( !sectionId || isNaN(sectionId) || sectionId == "0" ) return;
mw.loader.using( 'mediawiki.api', function () {
( new mw.Api() ).get( {
action: 'parse',
page: mw.config.get('wgPageName'),
prop: 'sections',
} ).done( function ( data ) {
var sections = [];
// Might want to check for errors here first
var allSections = data.parse.sections;
for( var i = 0, l = allSections.length; i < l; ++i) {
var thisSection = allSections[i];
if( thisSection.index == sectionId ) {
sections.push(thisSection);
// Loop back for the parents
var toclevel = thisSection.toclevel;
while( toclevel > 1 && i > 0 ) {
--i;
var possibleParent = allSections[i];
if( possibleParent.toclevel < toclevel ) {
sections.push(possibleParent);
toclevel = possibleParent.toclevel;
}
}
break;
}
}
// Use sections here
console.log(sections);
} );
} );
}
});
Not tested on Wiktionary itself, but works on a 1.24 local wiki.
Edit: As mentioned in the comments, if the page has templates with sections, the indexes won't match, so it is better to manually find the section with the correct index.