ProfessionalWiki / chameleon

Provides a highly flexible and customizable skin using Bootstrap 4
https://www.mediawiki.org/wiki/Skin:Chameleon
Other
115 stars 63 forks source link

Fork 2 or more mediawiki chameleon skins to be used in the same instance of mediawiki #428

Open eurodomenii opened 1 month ago

eurodomenii commented 1 month ago

My case is to use different css and fonts for admins, compared to anonymous users.

The first attempt was to conditionally load $egChameleonExternalStyleVariables and $egChameleonExternalStyleModules in LocalSettings.php, based on the cookie test, because the $user object cannot be loaded here, due to the premature access to service error

if (isset($_COOKIE[$wgDBname.'_session']) && isset($_COOKIE[$wgDBname.'UserName']) && $_COOKIE[$wgDBname.'UserName'] == "XXX" )

But the solution is not stable, because in some cases it enters the anonymous branch, even if there is a cookie set and it compromises the design.

Then, I thought of making one or more forks of the Chameleon theme, which admin users can switch from their preferences.

A concept of the project is posted at https://github.com/eurodomenii/mw_chameleon_fork

After copying the files, I ran two scripts

find . -type f -exec sed -i 's/chameleon/chameleon1/g' {} \; 
find . -type f -exec sed -i 's/Chameleon/Chameleon1/g' {} \;

And rename few files

skins/chameleon1/resources/styles/chameleon.scss
skins/chameleon1/src/Chameleon.php, 
skins/chameleon1/src/ChameleonTemplate.php 
skins/chameleon1/tests/phpunit/Unit/ChameleonTemplateTest.php

But the variables were overwritten and the styles messed up.

After x-debugging load.php

$resourceLoader->modules["zzz.ext.bootstrap.styles"]->variables I realized they were overwriting each other here

$resourceLoader->modules["zzz.ext.bootstrap.styles"]->styles Here the styles from both themes were added

I think that Chameleon's interconnection with Bootstrap was not designed for such a use case, because all variables, styles and scripts go in the 'zzz.ext.bootstrap.styles' module, for all forks

protected function registerSkinWithMW() {
        MediaWikiServices::getInstance()->getSkinFactory()->register( 'chameleon1', 'Chameleon1',
            function () {
                $styles = [
                    'mediawiki.ui.button',
                    'skins.chameleon1',
                    'zzz.ext.bootstrap.styles',
                ];

Finally, I found the workaround ext.bootstrap1.styles + ext.bootstrap1.scripts + new class BootstrapManager1.php workaround, see relevant details in the commit https://github.com/eurodomenii/mw_chameleon_fork/commit/bb699afcba3d1449c761c1f4320c18bbab3e28a2

I'm not convinced it's the best solution, it seems hackish, but it works! See also https://github.com/eurodomenii/mw_chameleon_fork/blob/master/CommonSettings.php usage of new Chameleon1/2 variables.

The code below duplicates the scripts, but in a hurry, I preferred to simply comment it out, as I didn't need it.

protected function addResourceModules(): void {
        $GLOBALS[ 'wgResourceModules' ][ 'skin.chameleon1.sticky' ] = [
            'localBasePath'  => $GLOBALS[ 'chameleon1LocalPath' ] . '/resources/js',
            'remoteBasePath' => $GLOBALS[ 'chameleon1RemotePath' ] . '/resources/js',
            'group'          => 'skin.chameleon1',
            'skinScripts'    =>
                [ 'chameleon1' => [ 'hc-sticky/hc-sticky.js', 'Components/Modifications/sticky.js' ] ]
        ];

        $GLOBALS[ 'wgResourceModules' ][ 'skin.chameleon1.toc' ] = [
            'localBasePath'  => $GLOBALS[ 'chameleon1LocalPath' ] . '/resources',
            'remoteBasePath' => $GLOBALS[ 'chameleon1RemotePath' ] . '/resources',
            'group'          => 'skin.chameleon1',
            'skinScripts'    => [ 'chameleon1' => [ 'js/Components/toc.js' ] ]
        ];
    }

Thank you!