User:TChin (WMF)/MediaWiki Tidbits
Useful MediaWiki Dev Tidbits
editDisclaimer: This is a brain dump. Most of this stuff I'm writing from memory and the information can be outdated.
MediaWiki
editInternationalization vs Localization
edit- Internationalization: Designing software so it can be adapted to different languages without engineering changes
- MediaWiki passes keys and params around that represent localizable strings
- Localization: The process of adapting internationalized software for a language/region
- MediaWiki then converts the key into the localized string using a metric crap ton of json files
- We are currently trying to separate the logic that does internationalization from the logic that does localization
Message vs MessageValue
editMessage
does both internationalization and localization (messy and bad, uses global state which is terrible for testing)MessageValue
is a new way to store message data independent of MediaWiki and without the messy formatting logic- Formatter logic now stored in a separate
TextFormatter
wfMessage( 'message-key' )->params( ... )
->inContentLanguage()
->text();
|
$textFormatter = MediaWikiServices::getMessageFormatterFactory()
->getTextFormatter( 'en' );
$textFormatter->format(
MessageValue::new( 'message-key' )->textParams( ... )
);
|
Interface Explanations
editPageReference
: Potentially viewable or linkable object (could be an interwiki link)PageIdentity
: A page that may exist (could be a special page)ProperPageIdentity
: An editable page (not special page) that could exist (may not be created yet)PageRecord
: A loaded page from the database
Revision Confusion
edit- Null edit - edit with nothing that triggers a page to be re-parsed, so may change content but don’t do a revision (i.e: a transcluded template was updated)
- Null revision - create a revision with the exact same content as before, so no update, but just to put a marker into the history (i.e: restoring the history)
PageUpdater
is a builder that does page updates.DerivedPageDataUpdater
is the state of the page update from the page update builder and a service that executes updates (although we want to split them)RevisionRecord
is how revisions are stored for a page- Slots are what specific sections have been saved
When Does Parsing Happen?
edit- MediaWiki uses the roundtrip time from saving a page and redirecting the user to actually render the page
- We have a lot of mechanisms to defer the parsing
- But in reality, certain things have to happen before you save the page
- For example, hooks that look at what links are being added, so you have to parse the page to get them
- Parsing always happen before saving, even though MediaWiki is designed to do it afterwards
- If parsing is triggered, we make sure to reuse the parsing output so we don’t parse again, but sometimes it doesn’t work
- Pages can render their own revision id, which isn’t known until it’s save so we’d have to re-render it again
- The current way to avoid re-rendering is weird state management in
WikiPage
Misc
edit- You can play with MediaWiki objects and functions with the
maintenance/shell.php
script (docs) - If MediaWiki can't find a newly-created class, run
maintenance/generateLocalAutoload.php
- When modifying extensions, pay attention to any extension under MediaWiki's Language Extension Bundle, as they must be backwards compatible to at least two stable MediaWiki releases
Useful Links
edit- MediaWiki PHP Coding Style Conventions
- MediaWiki Code Search
- MediaWiki Docs
- MediaWiki Code Coverage
- Database Schema
- Dependency Injection
- Stable Interface Policy
Testing
editPHP
edit- If you're using XDebug, remember to
export XDEBUG_SESSION=1
to enable step debugging for tests - You can filter PHP tests using
--filter
and then part of some testing function - Use
TestingAccessWrapper
to access private and protected methods - Data providers can return either an array or yield values
- Data providers are run before the fake databases are set up, so don't use any code that hits the database (i.e:
Title::newFromText
) - Remember to add the
@group Database
tag to the top comment block of anyMediaWikiIntegrationTestCase
tests if you're using the database MediaWikiUnitTestCase
does not have access toMediaWikiServices
but you can useDummyServicesTrait
- Mocking static methods is a pain in the ass so try to avoid it
- If you're testing an extension and it throws an error saying it requires some class within the extension, remember to register the extension in
LocalSettings.php
- If you're testing an extension and it throws an error saying it can't find a database, remember to run the
maintenance/update.php
script after registering the extension - If you're testing something and it throws an error saying something about a 'poolwiki' database, you have WikiBase installed and copied the example settings so you can just comment all that stuff out :P
Javascript
edit- For Javascript API testing, the secret key you need in
.api-testing-config.json
can be set inLocalSettings.php
with the variable$wgSecretKey
- If you're using mediawiki-docker-dev (note: different from mediawiki-docker), everything is already set for you and the
.api-testing-config.json
is:
{
"base_uri": "http://default.web.mw.localhost:8080/mediawiki/",
"main_page": "Main_Page",
"root_user": {
"name": "Admin",
"password": "dockerpass"
},
"secret_key": "a5dca55190e1c3927e098c317dd74e85c7eced36f959275114773b188fbabdbc",
"extra_parameters": {
"xdebug_session": "PHPSTORM"
}
}