Manual talk:Extension registration

About this board

Mqudsi (talkcontribs)

Can the following text be clarified?

Extensions that are loaded together with wfLoadExtensions (with plural -s) will be cached together.

What does it mean for extensions to be "cached together" and how does it differ from (what I imagine to be the corollary) "cached separately?" How does wfLoadExtensions($exts); differ from foreach($exts as $ext) wfLoadExtension($ext);?

Thanks!

Cavila (talkcontribs)

I don't know if it is significantly more efficient in terms of caching to use wfLoadExtensions rather than wfLoadExtension. I'd be interested to know, too.

Also, that comment seems weirdly out of context ("Features"?), something for which I may be partly to blame after merging information about installing extensions (info that's relevant to site admins not developers) into Manual:Extensions/Installation and upgrade. I just added a section about the plural option to that page and would suggest removing the comment on this page. What do you think?

Cavila (talkcontribs)

I went ahead and removed that paragraph, seeing as it is not helpful here.

Mqudsi (talkcontribs)

Thanks, that is much less ambiguous!

Uncaught Exception - Array to string conversion

4
Summary by Berot3

spelling mistake! a missing "s" at the end: for arrays it should be wfLoadSkins instead of wfLoadSkin

Berot3 (talkcontribs)

On mediawiki 1.35.2 I get a error when trying to use following setting:

wfLoadSkin([ 'MonoBook', 'Timeless', 'Vector' ]);

error:

Notice: Array to string conversion in C:\Bitnami\mediawiki-1.35.2-0\apps\mediawiki\htdocs\includes\GlobalFunctions.php on line 86

Fatal error: Uncaught Exception: Unable to open file C:\Bitnami\mediawiki-1.35.2-0\apps\mediawiki\htdocs/skins/Array/skin.json: filemtime(): stat failed for C:\Bitnami\mediawiki-1.35.2-0\apps\mediawiki\htdocs/skins/Array/skin.json in C:\Bitnami\mediawiki-1.35.2-0\apps\mediawiki\htdocs\includes\registration\ExtensionRegistry.php:177 Stack trace: #0 C:\Bitnami\mediawiki-1.35.2-0\apps\mediawiki\htdocs\includes\GlobalFunctions.php(88): ExtensionRegistry->queue('C:\\Bitnami\\medi...') #1 C:\Bitnami\mediawiki-1.35.2-0\apps\mediawiki\htdocs\LocalSettings.php(192): wfLoadSkin(Array) #2 C:\Bitnami\mediawiki-1.35.2-0\apps\mediawiki\htdocs\includes\Setup.php(143): require_once('C:\\Bitnami\\medi...') #3 C:\Bitnami\mediawiki-1.35.2-0\apps\mediawiki\htdocs\includes\WebStart.php(89): require_once('C:\\Bitnami\\medi...') #4 C:\Bitnami\mediawiki-1.35.2-0\apps\mediawiki\htdocs\index.php(44): require('C:\\Bitnami\\medi...') #5 {main} thrown in C:\Bitnami\mediawiki-1.35.2-0\apps\mediawiki\htdocs\includes\registration\ExtensionRegistry.php on line 177
Berot3 (talkcontribs)

loading every skin one by one works as usual

also: it works for extensions, like:

wfLoadExtensions([
	'CategoryTree',
	'Cite',
	'CiteThisPage',
	'CodeEditor',
	'ConfirmEdit',
	'Gadgets',
	'ImageMap',
	'InputBox',
	'Interwiki',
	'LocalisationUpdate',
	'MultimediaViewer',
	'Nuke',
	'OATHAuth',
	'PageImages',
	'ParserFunctions',
	'PdfHandler',
	'Poem',
	'Renameuser',
	'ReplaceText',
	'Scribunto',
	'SecureLinkFixer',
	'SpamBlacklist',
	'SyntaxHighlight_GeSHi',
	'TemplateData',
	'TextExtracts',
	'TitleBlacklist',
	'WikiEditor',
	'VisualEditor',
]);
Mainframe98 (talkcontribs)

You should use wfLoadSkins.

Berot3 (talkcontribs)

well thanks a lot. that is embarrassing :D

I will double-down on my copy-pasting-skills, I promise! ;)

Kghbln (talkcontribs)

The page informs that you need to use APC or APCu for caching (supposedly for PHP <= 5.4) to improve loading of many extensions.

  1. What about other caching mechanisms such as e.g. memcached or redis?
  2. What about PHP >= 5.5? Will the natively provided caching be enough for this job?
Legoktm (talkcontribs)

It all depends on how many extensions you plan on using. If you just have one or two, caching with memcached/redis will probably slow it down (I haven't actually confirmed this, I'll do that tonight). If you have PHP >= 5.5, you'll need to install the apcu extension, which is included in HHVM.

The code is definitely flexible enough that it should be trivial to implement support for memcached/redis if the performance is good enough.

Kghbln (talkcontribs)

Thank you for your answer. I guess that 15 to 25 extensions is a good pick for an average regular wiki out in the wild. So working with some sort of caching seems to be very advisable for them in the future. I believe that in general it should therefore be possible to choose other ways than just APCu in a sense of providing more options. Thus it will indeed be cool to implement support for other caching mechanisms. So to sum up the current situation:

  • PHP <= 5.4 -> APC which includes user cache
  • PHP >= 5.5 -> APCu since native PHP does not include user cache

[RESOLVED] Loading multiple extensions

7
Summary by Berot3

I rebuilt the site with a fresh install and it looks like it's working properly again.

Prod (talkcontribs)

A bunch of extensions I use were updated with extension registration, but it seems the backwards compatibility isn't working for me. For example I have the following three extensions enabled:

require_once( "$IP/extensions/CharInsert/CharInsert.php" );
require_once( "$IP/extensions/Cite/Cite.php" );
require_once( "$IP/extensions/Gadgets/Gadgets.php" );

Only CharInsert is showing up in my Special:Version page, even though they're all using extension registration. All my other extensions which haven't been updated are still working. Is the backwards compatibility supposed to work without any further changes, or am I missing something?

Florianschmidtwelzow (talkcontribs)

CharInsert is the only extension, that doesn't force to use extension registration, Cite and Gadgets uses extension registration, still if you use "the old" installation method. Could you check, if you can install the extensions via:

wfLoadExtensions( array( 'CharInsert', 'Cite', 'Gadgets' ) );

?

Prod (talkcontribs)

I've switched to the wfLoadExtensions method and the output is still about the same (checking Special:Version). I tried enabling the debug log but nothing really jumped out at me. I'm on version 1.25.0-rc.0. I updated CharInsert to the master branch, and HitCounters to the latest code available, but the remaining extensions are on REL1_25.

Here's my LocalSettings.php.

Legoktm (talkcontribs)

The backwards-compatability should working, if not there's a bug. Can you enable the deubgging settings and see if anything comes up? What other extensions do you have installed? Can you pastebin your LocalSettings.php with passwords removed? And what version of MediaWiki are you using?

Paladox (talkcontribs)

CharInsert now does what the other two extensions do it now uses the extension.json.

Prod (talkcontribs)

I disabled all my extensions and tried the following tests, with results below. Cite and Gadgets are from REL1_25,

require_once( "$IP/extensions/Cite/Cite.php" ); Cite enabled, Gadgets disabled
require_once( "$IP/extensions/Gadgets/Gadgets.php" ); Cite disabled. Gadgets enabled
require_once( "$IP/extensions/Cite/Cite.php" );

require_once( "$IP/extensions/Gadgets/Gadgets.php" );

Cite enabled, Gadgets disabled
require_once( "$IP/extensions/Gadgets/Gadgets.php" );

require_once( "$IP/extensions/Cite/Cite.php" );

Cite disabled, Gadgets enabled
wfLoadExtensions( array( 'Cite', 'Gadgets' ); Cite enabled, Gadgets disabled
wfLoadExtensions( array( 'Gadgets', 'Cite' ); Cite disabled. Gadgets enabled

All my other extensions (which don't use registration) seem to work as normal and don't impact these tests. But only the first extension I enable through registration appears to be working.

Prod (talkcontribs)

Looks like I had some legacy files left over from a previous version causing conflicts. I rebuilt the site with a fresh install and it looks like it's working properly again. Thanks for the help Legoktm and Florianschmidtwelzow!

Comments (keys starting with @ in extension.json) not ignored in "SpecialPages" array

4
217.15.199.78 (talkcontribs)

Hello,

Special:Specialpages crashes (in SpecialPageFactory.php/getPage()/"$page = new $className;") if there are comments (like "@doc": "Something") under "SpecialPages" array in extension.json. It seems keys starting with "@" are not as filtered as this page suggests...

Legoktm (talkcontribs)

"@" is only ignored in the top level structure, or under the "config" key.

SPage (WMF) (talkcontribs)
Legoktm (talkcontribs)

Thanks. Re: Gather, that only works because ResourceLoader is ignoring the unknown parameter, I wouldn't depend upon it. The extension registry is still loading and caching that value on each request unlike "@" keys in top-level/config which are ignored in the parsing stage.

Documentation for how to register an extension

1
79.86.113.37 (talkcontribs)

Coming to this for the first time for writing my first extension, I don't see any guide as to how to write the code to register a new extension, only how to convert an old extension. Maybe it is obvious, but at least a simple example would help.

Kaldari (talkcontribs)

What's the registerExtension() function for? Registering stuff that can't be registered through the JSON file?

Legoktm (talkcontribs)

Can you give an example of what you mean?

Kaldari (talkcontribs)

Two extensions (Math and Spamblacklist) define a registerExtension() function that is never explicitly called. There are also patches in gerrit to add it to two other extensions (TimedMediaHandler and MobileFrontend). The function has no documentation anywhere. As best as I can tell it seems to be for registering globals that can't be migrated to extension.json.

Legoktm (talkcontribs)

Those are "callbacks", see the docs. Some of them, like the ones in WikiEditor were necessary because extension.json didn't support 2d arrays (it does now) and can probably be removed.

Kaldari (talkcontribs)

Why is this implemented in such a convoluted way? Couldn't we just use a regular hook?

Legoktm (talkcontribs)

It's somewhat intentionally convoluted, any instance of it indicates that extension.json is missing support for a feature or an extension is doing something wrong.

A hook isn't feasible due to the way these are called, plus we try to avoid as many dependencies upon the rest of MediaWiki in early initialization, including the Hooks class.

Kaldari (talkcontribs)

OK, I'm beginning to understand this. If people would just follow the coding conventions and document their functions, things wouldn't be so confusing :P

Would it be possible for you or someone else involved in extension registration to update Manual:Extension registration/Limitations? This seems like a pretty critical documentation page and it hasn't been kept up to date. I tried to make a few changes myself, but I don't know the Phab tickets for any of these issues. Thanks!

SPage (WMF) (talkcontribs)
  1. It's confusing that the example gives it a hook name but it isn't. I added a note to Manual:Extension registration#Customizing registration mentioning this.
  2. When does registration call the callback, is it immediately after registering this one extension or after registering all extensions? Some extensions try to do stuff based on the presence of other extensions, and then wind up being order-dependent.
  3. The section says "There are two features that can be used to support these cases". What's the second?

Answer here or update the docs, thanks

Documentation on extension.json format and how to write a file

2
Summary by Berot3

filed

Brooke Vibber (talkcontribs)

Could use some. :) Seems to be essentially no documentation on the format, how to specify things, etc. Does everyone just copy-paste from existing files? :(

Brooke Vibber (talkcontribs)

How can I translate the namespace “name” to a local language the right way?

5
Summary last edited by Andreas Plank 07:58, 2 June 2021 2 years ago

One solution see post from 11. April 2019 17:31

I don’t know if it is the right way but it works for me ;-)

Andreas Plank (talkcontribs)

Hej-hej,

I asked for translating the default namespace (at extension talk of UploadWizard), how is it possible to do it the right way? $wgNamespaceAliases doesn’t help that much, because I want the translated namespace to appear (in search and display) not the default defined from extension.json. Any proper solution? Thanks.

Legoktm (talkcontribs)

Namespaces should be translated in the extension localization file, see this example in the Scribunto extension. I don't know why no one has done that for UploadWizard yet.

Jdforrester (WMF) (talkcontribs)
Jdforrester (WMF) (talkcontribs)

Yes, you add the name to $wgNamespaceAliases in local config of the wiki in question. For Wikimedia, you'd add that to the major InitialiseSettings.php file.

The alias only helps for manual linking; the URL is re-written by MediaWiki on browse (https://commons.wikimedia.org/wiki/COM:Deletion_requests becomes https://commons.wikimedia.org/wiki/Commons:Deletion_requests, etc.), so I'm not sure how valuable this would be. In general, MediaWiki's support for multi-lingual wikis is patchy, and this is one of those areas. Note also that there's a risk of whatever name you pick being subject to clashes, either with other desired aliases or for actual namespaces in future.

Currently, Commons only has language aliases/shorthands in English and for three namespaces ('Museum:'/'Museum_talk:' for 'Institution:'/'Institution_talk:', and 'COM:' for Commons:"). We could add a "translation" for NS_CAMPAIGN, but as this hasn't been done before I think it'd be best if there was a community discussion on Commons about that first.

Andreas Plank (talkcontribs)

In MW 1.30 I did the following:

if (! defined ("NS_CAMPAIGN" )) {
  define("NS_CAMPAIGN",        460);
  define("NS_CAMPAIGN_TALK",   461);
}
# rename untranslated Campaign
switch ($wgLanguageCode) {
  case "de":
  case "de-formal":
  case "de-at":
  case "de-ch":
    $wgExtraNamespaces[NS_CAMPAIGN]      = "Medienkampagne";
    $wgExtraNamespaces[NS_CAMPAIGN_TALK] = "Medienkampagne_Diskussion";
    $wgNamespaceAliases['Campaign'] = NS_CAMPAIGN;
    $wgNamespaceAliases['Campaign_talk'] = NS_CAMPAIGN_TALK;
    break;
  // other cases 
  default:
    $wgExtraNamespaces[NS_CAMPAIGN]      = "Campaign";
    $wgExtraNamespaces[NS_CAMPAIGN_TALK] = "Campaign_talk";
  break;
}

#############################
# Extension: UploadWizard & Co
#############################
wfLoadExtension( 'EventLogging' );
wfLoadExtension( 'UploadWizard' );

and it works as I want it to:

  1. it uses Medienkampagne on a German Wiki as default
  2. but Campaign also works (and is led to Medienkampagne)

I don’t know if it is the right way but it works for me ;-)

How to make site-specific changes to an extension's configuration *Without* touching extension.js?

2
Summary by Berot3

e.g. with $wgMyExtVarname = 'site-specific value'; in LocalSettings.php.

Otheus (talkcontribs)

There is also no documentation on the PHP code corresponding to the config section for version 2. The reader is left to experiment.

Samwilson (talkcontribs)

(I assume you mean 'extension.json'.)

You change extensions' config values the same way in version 2 of the extension.json schema, e.g. with $wgMyExtVarname = 'site-specific value'; in LocalSettings.php.