Page MenuHomePhabricator

Hook for inserting custom CSS missing / inserted CSS lost on later view
Closed, ResolvedPublic

Description

The suggested way of adding custom CSS and scripts for a MediaWiki extension is
via $wgOut->addLink and $wgOut->addScript. However, even if extensions call
these functions during parsing (so that everything appears in the header as
expected), these modifications are (of course) not stored within the database.
Hence, when the article is viewed at a later stage, the headers are missing
again whenever the parsing hooks are not triggered.

The problem is that there is no hook "InitializeOutputPage" (or whatwever) where
extensions can add standard scripts and CSS. This hook would also be useful as a
clean way for performing all kinds of wgOut-customizations that apply to all
pages. It should be easy to fix the issue by providing such a hook.

The required code would probably be:

wfRunHooks('InitializeOutputPage');

to be added in Setup.php after '$wgOut = new OutputPage();' No parameters should
be needed for he hook, since all relevant variables at this stage are global anyway.


Version: 1.7.x
Severity: normal

Details

Reference
bz5077

Event Timeline

bzimport raised the priority of this task from to Medium.Nov 21 2014, 9:09 PM
bzimport added a project: MediaWiki-Parser.
bzimport set Reference to bz5077.
bzimport added a subscriber: Unknown Object (MLST).

Parser hooks can only output HTML and other parser state information to the parser.
If it were desirable for parser hooks to be able to add page-wide CSS (which it perhaps
isn't, since this would not be portable to other output styles) this would have to go
into the ParserOutput object to be stored in the cache.

(In reply to comment #1)

The rationale of having parser extensions add their own CSS/JScript is to make
small graphical or interface enhancements that do not jeopardize compatibility
with the various styles (to the extent that this can be guaranteed). For
example, one might want to have a link- or span-class that adds some small
icons, as is done in the geo-coordinate feature currently tested in Wikipedia.

An alternative for this function might be to have a variable that allows
registering additional CSS, Scripts, or header metalinks within LocalSettings.
Maybe there is a way and I just do not know how to do it properly in the current
version ... but using wgOut->addLink currently seems to be no option for
extensions that try to live on hooks only.

A better proposal for a solution which is also suitable for extensions that have
nothing to do with parsing (but still might want to modify certain header
elements for whatever reason):

Add a hook in OutputPage.php, right after "wfProfileIn( 'Output-skin' );" As
parameters, the hook should get the outputpage ($this), so that CSS/Scripts can
be added based on the status and title of the page.

This seems to be a sufficiently general and robust solution, and extensions
could easily add their header tags there without patching anything or modifying
the parser cache. Whereever the hook is placed, it is important that the
OutputPage's mIsArticle and mPagetitle are normally available at this stage.

Problem with the above position: this hook would sometimes be called more than
once during parsing

  • Solution 1: add a bool member to OutputPage that records whether the hook was

already called. Do not call it more than once for one output. I am not sure
whether this might possibly conflict with the requirement that mPagetitle is set.

  • Solution 2: (maybe cleaner) add a duplicate elimination to OutputPage

functions "addScript", "addLink", "addMeta", ... This can e.g. be done by
generating PHP array keys from the added elements. Maybe add an optional
parameter to "ignore duplicates" to avoid performance impacts for the internal
calls to addFoo that are known not to generate duplicates.

  • Solution 3: do nothing and leave it to the extensions to record what they have

already added in a certain run.

jeluf wrote:

Fixed in r14420 (1.7 alpha)

Add this to SemanticMediaWiki/includes/SMW_Settings.php:

$wgHooks['BeforePageDisplay'][] = 'SMWBeforePageDisplayHook';

function SMWBeforePageDisplayHook( $out ) {

smwfAddHTMLHeader( &$out );

}