A partial archive of https://discourse-mediawiki.wmflabs.org as of Saturday May 21, 2022.

Looking for a way (the right hook) to add deferred content to a wiki page

Oetterer

I currently work on a problem with my extension, the modal component, to be precise. I have a problem where I need to insert content created by a parser tag, only not in place of the parser tag but somewhere else on the page.

Introduction

The desired functionality is this: I have a parser tag that inserts a trigger element (button, image, text link) in place of the tag. This element when clicked by the user triggers a modal to appear in front of the content as an overlay with a grey backdrop. Basically, it is a div element, which needs to be somewhere on the page.

Problem is, it cannot be insterted directly by the parser function, because in most cases this would mess up the layout (creating a line break at the least). So I have to deferr the html injection.

I tested several solutions, none of which worked as intended:

Hooks ParserBeforeTidy, ParserAfterTidy

They basically do what I was aiming for. Unfortunately they get called everytime a parser is invoked, so my div can turn up at places, that makes it "inaccessible". So unless there is way to ensure that the hook is called by the main parser instance for the main content, I cannot use this hook.

Hooks SkinAfterContent, OutputPageParserOutput

Correctly insert the deferred html once on the page at the end (or in case of _OutputPageParserOutput_ at the beginning, if desired) of the main content (I currently see no differences between these two, but I expect there to by some). Unfortunatly they both do not work for me either, because of the parser cache. The modal correctly shows when the page is edited or purged but when the page is reloaded, the click on the trigger does nothing. No modal div has been added to the html output. I also tried to utilize
$wgParser->getOutput()->setExtensionData( 'bsc_deferredContent', $html );

but apparently, the extension data is not cached either.

possible solutions, someone might help me with

  • point me towards the right hook, that inserts content into the page before it is cached.
  • tell me how to add extension data to the cache to be retrieved on subsequent calls.
  • give me an alltogether better concept to solve this problem with.

I really don’t want to disable the parser cache for pages containing a modal but as it stands out, this is my only working solution for the moment. So I could really need some help.

Thank you for reading this far!
Cheers,
Tobi

Ciencia-Al-Poder

Have you checked what Extension:Cite does? When you add a <ref> but there’s no <references/> on the page, references appear at the end of the page anyway, even if you are editing a section that have <ref> and the <references/> is at a later section, they appear on preview.

Tgr

You can use setExtensionData (which does get cached), you can use a HTML template loaded as a ResourceLoader asset, you can use ContentAlterParserOutput

Oetterer

Thank you for the suggestion, Cita was indeed on my inspection list. @Tgr only was faster with his reply! :slight_smile:

Oetterer

Thanks for the clarification. Apparently, when I run my tests with setExtensionData() I had initalized the data wrong and therefore it got overwritten on consecutive loads. After your suggestion, I did some more digging and have a workable solution now, using getExtensionData(), setExtensionData(), and the hook OutputPageParserOutput. Your help is much appreciated!

Osnard

You can try “OutputPageBeforeHTML” [1]. But as mentioned on the description page, this may also have some disadvantages.

Your ParserFunction/TagExtension may just add a marker (e.g. <!-- ###COMPONENT X START-->) which then can be substituted in the mentioned hook.

[1] https://www.mediawiki.org/wiki/Manual:Hooks/OutputPageBeforeHTML