Page MenuHomePhabricator

Fix uses of OutputPageBeforeHTML hook in popular extensions that assume it is only executed once per page view
Closed, ResolvedPublic

Description

As documented on Manual:Hooks/OutputPageBeforeHTML, the OutputPageBeforeHTML hook can be executed more than once per page view, if the page content is composed from multiple sources.

For example, if the MediaWiki:Talkpageheader localisation message is defined, it is inserted at the top of all talk pages, and the hook is called twice: for the content from this message and for the content from the page's wikitext. This can be reproduced on e.g. https://fr.m.wikipedia.org/wiki/Discussion:Rhinocéros_de_Louis_XV.

However, we have some code that is not aware of that. This mistake caused major rendering issues in DiscussionTools (T316175#8404730), and after fixing that, I noticed that other extensions are also affected, but in less significant ways, so no one ever noticed. (e.g. MobileFrontend inserts duplicate <meta name="theme-color" content="#eaecf0"/> tags).

Code to review: https://codesearch-beta.wmcloud.org/deployed/?q=OutputPageBeforeHTML&files=%5C.php%24

Event Timeline

The hook is used by:

  • mediawiki/extensions/DiscussionTools
    • Looks wrong
  • mediawiki/extensions/DoubleWiki
    • Looks correct
  • mediawiki/extensions/MobileFrontend
    • Looks wrong
  • mediawiki/extensions/ShortUrl
    • Looks wrong (but harmless)
  • mediawiki/extensions/TemplateData
    • Looks correct
  • mediawiki/extensions/Wikibase
    • Looks correct
  • mediawiki/extensions/WikidataPageBanner
    • Only mentioned in a code comment (which looks wrong)

Change 858618 had a related patch set uploaded (by Bartosz Dziewoński; author: Bartosz Dziewoński):

[mediawiki/extensions/DiscussionTools@master] Use 'BeforePageDisplay' instead of 'OutputPageBeforeHTML' for once-per-page things

https://gerrit.wikimedia.org/r/858618

Change 858619 had a related patch set uploaded (by Bartosz Dziewoński; author: Bartosz Dziewoński):

[mediawiki/extensions/MobileFrontend@master] Use 'BeforePageDisplay' instead of 'OutputPageBeforeHTML' for once-per-page things

https://gerrit.wikimedia.org/r/858619

Change 858620 had a related patch set uploaded (by Bartosz Dziewoński; author: Bartosz Dziewoński):

[mediawiki/extensions/ShortUrl@master] Use 'BeforePageDisplay' instead of 'OutputPageBeforeHTML' for once-per-page things

https://gerrit.wikimedia.org/r/858620

Change 858621 had a related patch set uploaded (by Bartosz Dziewoński; author: Bartosz Dziewoński):

[mediawiki/extensions/WikidataPageBanner@master] Remove mention of unused OutputPageBeforeHTML hook

https://gerrit.wikimedia.org/r/858621

Tacsipacsi subscribed.
  • mediawiki/extensions/DoubleWiki
    • Looks correct

Well, not entirely. I don’t know if there are things that work similarly to talkpageheader but in even-numbered namespaces, but I could (IMO) break it:

  1. Since DoubleWiki works with interlanguage links, I had to get MediaWiki display interlanguage links in talk namespaces. I could’ve probably written an extension that adds them (or install Wikibase), but the easiest solution was simply modifying Parser.php to remove the $nottalk check from the code recognizing interlanguage links. Isn’t likely to happen in production, but it fits for testing. 🙂
  2. Created MediaWiki:talkpageheader, calling a template in which I “forgot” to wrap the interlanguage link in <noinclude>.
  3. Also added a direct interlanguage link to a talk page.
  4. Opened the talk page with &match=hu added to the URL.
  5. Got QuadrupleWiki instead of DoubleWiki: both the talk page header and the main content got their Hungarian equivalents – except that sometimes the main content also got the Hungarian equivalent of the talk page header, probably due to cache pollution.

Until someone comes up with a such way to reproduce this that at least doesn’t involve modifying the parser, it’s pretty low-priority, but it’s still a bug.

Change 858618 merged by jenkins-bot:

[mediawiki/extensions/DiscussionTools@master] Use 'BeforePageDisplay' instead of 'OutputPageBeforeHTML' for once-per-page things

https://gerrit.wikimedia.org/r/858618

@Tacsipacsi You're right. I guess I didn't look too closely when I wrote that it looks correct.

I don't particularly want to spend time on DoubleWiki here. As you noted, it's not an issue in practice, and unlike MobileFrontend or DiscussionTools, no one has heard of it so I think folks aren't likely to use it as a bad example to copy-paste. I filed a separate bug for it: T323965.

matmarex renamed this task from Fix uses of OutputPageBeforeHTML hook that assume it is only executed once per page view to Fix uses of OutputPageBeforeHTML hook in popular extensions that assume it is only executed once per page view.Nov 29 2022, 12:17 AM

Change 858620 merged by jenkins-bot:

[mediawiki/extensions/ShortUrl@master] Use 'BeforePageDisplay' instead of 'OutputPageBeforeHTML' for once-per-page things

https://gerrit.wikimedia.org/r/858620

Change 858621 merged by jenkins-bot:

[mediawiki/extensions/WikidataPageBanner@master] Remove mention of unused OutputPageBeforeHTML hook

https://gerrit.wikimedia.org/r/858621

Change 858619 merged by jenkins-bot:

[mediawiki/extensions/MobileFrontend@master] Use 'BeforePageDisplay' instead of 'OutputPageBeforeHTML' for once-per-page things

https://gerrit.wikimedia.org/r/858619