Discovering MediaWiki 1.44: Key Features for Developers

Why MediaWiki 1.44 matters to the code‑savvy

When the MediaWiki team rolled out 1.44, most wiki‑admins were busy checking the “new UI” screenshots. Developers, however, got a different kind of rush – the kind you feel when a toolbox suddenly sprouts fresh handles. Below is a quick‑hit tour of the bits that actually change the way we write extensions, poke the API, or just stare at server logs and think “huh, that’s nicer now”.

Domain events – the new lingua franca for extensions

From the messaging board on the developer wiki: “ events are finally here, and they actually work.” In plain English, MediaWiki 1.44 introduces a generic event system that mirrors the publish/subscribe pattern you see in Node or Django signals. The idea is simple: whenever a core operation (page save, user block, file upload…) happens, MediaWiki fires a DomainEvent object that any extension can listen to.

  • Typed payloads – each event carries a PHP class with typed properties, so you get autocompletion and static analysis for free.
  • Lazy subscribers – you no longer need a Hooks::register call in extension.json for every listener. Declaring the event in manifest.json is enough.
  • Built‑in throttling – the core can pause emission if the subscriber pool gets too noisy, preventing runaway loops.

Here’s a tiny example that logs every successful login:


use MediaWiki\HookContainer\HookContainer;
use MediaWiki\Hook\LoginSuccessDomainEvent;

class LogLoginSuccess {
    public static function onLoginSuccessDomainEvent( LoginSuccessDomainEvent $event ) {
        $user = $event->getUser();
        wfDebugLog( 'login', "User {$user->getName()} logged in at " . wfTimestampNow() );
    }
}

Notice the LoginSuccessDomainEvent class? That’s what the new system hands you – no more guessing whether the payload is an array or an object.

API refinements – less “magic strings”, more predictability

The Action API got a tidy spring‑clean. A few notable tweaks that developers will feel straight away:

  1. Parameter renames for clarityprop=info now accepts inprop=displaytitle instead of the cryptic show=title. It may look like a tiny rename, but it aligns the API with the internal naming conventions, reducing cognitive load.
  2. Batch‑create pages in one request – the new createpages module accepts an array of titles and source wikitext, returning a map of page IDs to errors if any. Perfect for migration scripts.
  3. Improved error objects – every error now includes an errorcode and a message field, plus an optional details object with extra context. Clients that parse JSON can now differentiate “permission denied” from “page protected” without string matching.

Sample call (cURL) that creates two pages:

curl -X POST https://mywiki.org/api.php \
  -d action=createpages \
  -d token=+\\ \
  -d pages[0][title]=New+Page+One \
  -d pages[0][content]===Header==\nHello+world! \
  -d pages[1][title]=New+Page+Two \
  -d pages[1][content]=Just+another+test \
  -d format=json

The JSON reply now looks like this:

{
  "createpages": {
    "pages": {
      "New Page One": { "pageid": 12345 },
      "New Page Two": {
        "error": {
          "errorcode": "protectedpage",
          "message": "The target page is protected"
        }
      }
    }
  }
}

File protection – a tighter grip on uploads

Uploading files has always been a balancing act between openness and abuse prevention. MediaWiki 1.44 adds two knobs that let you fine‑tune the dance:

  • per‑file expiration – admins can now set an expiration timestamp on a file, after which the file is automatically hidden from the public while staying in the file archive.
  • hash‑based allow‑list – you can whitelist SHA‑256 hashes of known‑good files, so even if a user bypasses the mime check, the file won’t slip through.

In practice, an extension that handles image galleries can call the new API endpoint filehashallowlist to add a hash, then forget about that particular upload ever causing trouble again.

Patrolling redesign – fewer clicks, clearer signals

Patrolling used to be a “click‑the‑checkbox” routine that left many editors wondering if they’d actually marked a revision. The 1.44 revamp swaps that for a single‑action UI: once you hit “Mark as patrolled”, the system records a timestamp and silently updates the “patrolled” flag. The back‑end now exposes a patrolled property on the revisions API module, making it trivial for bots to query the patrolled status without extra parsing.

For developers, the big win is the new hook PostPatrolDomainEvent, which fires after any patrol operation, letting you trigger notifications or analytics without wrestling with the old WatchArticleComplete hook.

Redirect handling gets smarter

If you’ve ever written a script that follows redirects and ended up in a loop, you know the pain. MediaWiki 1.44 adds a “smart redirect” engine that:

  • detects double‑redirects and resolves them in one pass,
  • honors the #REDIRECT magic word even when it appears after some trailing whitespace,
  • exposes a new API flag redirects=resolve that returns the final target title instead of the intermediate one.

Example: asking for “Old‑Page” now returns “New‑Page” directly, saving you an extra HTTP round‑trip.

What’s new for sysadmins (quick glance)

Because developers love a clean sandbox, here are a couple of admin‑only upgrades that indirectly affect us:

  • Better manageblocks UI – now you can bulk‑expire blocks via a CSV upload, handy when a spammer’s IP range expands.
  • Enhanced logging – all domain events are also logged to eventlog, which can be shipped to external SIEM tools without custom parsers.

Putting it together – a tiny extension skeletonh3>

Let’s say you want an extension that watches every new file upload, checks the hash against an allow‑list, and if it fails, automatically blocks the uploader for an hour. With domain events and the new API, the code shrinks dramatically.


use MediaWiki\Hook\FileUploadDomainEvent;
use MediaWiki\User\UserFactory;
use MediaWiki\Permissions\BlockUserFactory;

class AutoBlockBadFiles {

    /** @var UserFactory */
    private $userFactory;
    /** @var BlockUserFactory */
    private $blockFactory;

    public function __construct( UserFactory $uf, BlockUserFactory $bf ) {
        $this->userFactory = $uf;
        $this->blockFactory = $bf;
    }

    public static function onFileUploadDomainEvent( FileUploadDomainEvent $event ) {
        $hash = $event->getFile()->getSha256();
        if ( ! $this->isHashAllowed( $hash ) ) {
            $u = $event->getUser();
            $this->blockFactory->newBlock( $u, [
                'expiry' => '1 hour',
                'reason' => 'Uploaded disallowed file hash'
            ] )->placeBlock();
        }
    }

    private function isHashAllowed( string $hash ) : bool {
        // Imagine we query the new filehashallowlist API here.
        return in_array( $hash, $this->getAllowedHashes() );
    }
}

Notice how the boilerplate is gone? No need to tap into UploadComplete or manually parse $_FILES. The domain event does the heavy lifting.

Where to read more

The official release notes live on mediawiki.org. For a developer‑centric deep‑dive, see the Domain events manual. And if you enjoy crunchy changelogs with a side of humor, the ProWiki blog posted a nice “highlights” summary here.

Final thoughts (or not?)

MediaWiki 1.44 doesn’t reinvent the wheel, but it adds a few well‑placed spokes that make the ride smoother for anyone who writes code on top of the platform. The domain events system is the headline act; the API sanitisation, smarter redirects, and file‑hash controls are the reliable supporting cast. If you’ve been dragging a legacy extension through the 1.35 LTS maze, consider giving these new hooks a spin – you might find the code you’ve been fighting with finally behaves.

Subscribe to MediaWiki Tips and Tricks

Don’t miss out on the latest articles. Sign up now to get access to the library of members-only articles.
jamie@example.com
Subscribe