User:TChin (WMF)/MediaWiki Tidbits
Appearance
Useful MediaWiki Dev Tidbits
[edit]Disclaimer: This is a brain dump. Most of this stuff I'm writing from memory and the information can be outdated.
MediaWiki
[edit]Internationalization 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
[edit]Message
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
[edit]PageReference
: 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
[edit]PHP
[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"
}
}