Bartosz Dziewoński has uploaded a new change for review.
https://gerrit.wikimedia.org/r/148508
Change subject: Use a special fallback skin when selected skin is unavailable
......................................................................
Use a special fallback skin when selected skin is unavailable
It displays a helpful message that explains why and how to
install and enable skins.
Bug: 68332
Change-Id: Id14fbb8733cd8fbb912a724ac658f5e7244364b5
---
M includes/AutoLoader.php
M includes/DefaultSettings.php
M includes/Setup.php
A includes/SkinFallback.php
M languages/i18n/en.json
M languages/i18n/qqq.json
6 files changed, 288 insertions(+), 3 deletions(-)
git pull ssh://gerrit.wikimedia.org:29418/mediawiki/core
refs/changes/08/148508/1
diff --git a/includes/AutoLoader.php b/includes/AutoLoader.php
index 046a0df..4f61a9b 100644
--- a/includes/AutoLoader.php
+++ b/includes/AutoLoader.php
@@ -159,6 +159,8 @@
'SiteStatsInit' => 'includes/SiteStats.php',
'Skin' => 'includes/Skin.php',
'SkinTemplate' => 'includes/SkinTemplate.php',
+ 'SkinFallback' => 'includes/SkinFallback.php',
+ 'SkinFallbackTemplate' => 'includes/SkinFallback.php',
'SquidPurgeClient' => 'includes/SquidPurgeClient.php',
'SquidPurgeClientPool' => 'includes/SquidPurgeClient.php',
'StatCounter' => 'includes/StatCounter.php',
diff --git a/includes/DefaultSettings.php b/includes/DefaultSettings.php
index 8046449..20970f1 100644
--- a/includes/DefaultSettings.php
+++ b/includes/DefaultSettings.php
@@ -2966,7 +2966,7 @@
/**
* Fallback skin used when the skin defined by $wgDefaultSkin can't be found.
*/
-$wgFallbackSkin = 'vector';
+$wgFallbackSkin = 'fallback';
/**
* Specify the names of skins that should not be presented in the list of
diff --git a/includes/Setup.php b/includes/Setup.php
index 040aba5..e40f44a 100644
--- a/includes/Setup.php
+++ b/includes/Setup.php
@@ -272,6 +272,10 @@
$wgSkipSkins[] = $wgSkipSkin;
}
+// Register a hidden "fallback" skin
+$wgValidSkinNames['fallback'] = 'Fallback'; // SkinFallback
+$wgSkipSkins[] = 'fallback';
+
if ( $wgLocalInterwiki ) {
array_unshift( $wgLocalInterwikis, $wgLocalInterwiki );
}
diff --git a/includes/SkinFallback.php b/includes/SkinFallback.php
new file mode 100644
index 0000000..11470f3
--- /dev/null
+++ b/includes/SkinFallback.php
@@ -0,0 +1,271 @@
+<?php
+/**
+ * Skin file for the fallback skin.
+ *
+ * The structure is copied from the example skin (mediawiki/skins/Example).
+ *
+ * @file
+ */
+
+/**
+ * SkinTemplate class for the fallback skin
+ */
+class SkinFallback extends SkinTemplate {
+ var $skinname = 'fallback', $template = 'SkinFallbackTemplate';
+
+ /**
+ * Add CSS via ResourceLoader
+ *
+ * @param $out OutputPage
+ */
+ function setupSkinUserCss( OutputPage $out ) {
+ parent::setupSkinUserCss( $out );
+ $out->addModuleStyles( 'mediawiki.skinning.interface' );
+ }
+}
+
+/**
+ * BaseTemplate class for the fallback skin
+ */
+class SkinFallbackTemplate extends BaseTemplate {
+ /**
+ * Outputs a single sidebar portlet of any kind.
+ */
+ private function outputPortlet( $box ) {
+ if ( !$box['content'] ) {
+ return;
+ }
+
+ ?>
+ <div
+ role="navigation"
+ class="mw-portlet"
+ id="<?php echo Sanitizer::escapeId( $box['id'] ) ?>"
+ <?php echo Linker::tooltip( $box['id'] ) ?>
+ >
+ <h3>
+ <?php
+ if ( isset( $box['headerMessage'] ) ) {
+ $this->msg( $box['headerMessage'] );
+ } else {
+ echo htmlspecialchars( $box['header'] );
+ }
+ ?>
+ </h3>
+
+ <?php
+ if ( is_array( $box['content'] ) ) {
+ echo '<ul>';
+ foreach ( $box['content'] as $key => $item ) {
+ echo $this->makeListItem( $key, $item );
+ }
+ echo '</ul>';
+ } else {
+ echo $box['content'];
+ }?>
+ </div>
+ <?php
+ }
+
+ private function findInstalledSkins() {
+ global $wgStyleDirectory;
+
+ // Get all subdirectories which might contains skins
+ $possibleSkins = scandir( $wgStyleDirectory );
+ $possibleSkins = array_filter( $possibleSkins, function (
$maybeDir ) {
+ global $wgStyleDirectory;
+ return $maybeDir !== '.' && $maybeDir !== '..' &&
is_dir( "$wgStyleDirectory/$maybeDir" );
+ } );
+
+ // Only keep the ones that contain a .php file with the same
name inside
+ $possibleSkins = array_filter( $possibleSkins, function (
$skinDir ) {
+ global $wgStyleDirectory;
+ return is_file(
"$wgStyleDirectory/$skinDir/$skinDir.php" );
+ } );
+
+ return $possibleSkins;
+ }
+
+ /**
+ * Inform the user why they are seeing this.
+ *
+ * @return string
+ */
+ private function buildHelpfulInformationMessage() {
+ global $wgDefaultSkin, $wgValidSkinNames;
+
+ $installedSkins = $this->findInstalledSkins();
+ $enabledSkins = $wgValidSkinNames;
+ $enabledSkins = array_change_key_case( $enabledSkins,
CASE_LOWER );
+
+ if ( $installedSkins ) {
+ $skinsInstalledText = array();
+ $skinsInstalledSnippet = array();
+
+ foreach ( $installedSkins as $skin ) {
+ $normalizedKey = strtolower( $skin );
+ $isEnabled = array_key_exists( $normalizedKey,
$enabledSkins );
+ if ( $isEnabled ) {
+ $skinsInstalledText[] = wfMessage(
'default-skin-not-found-row-enabled' )
+ ->params( $normalizedKey, $skin
)->plain();
+ } else {
+ $skinsInstalledText[] = wfMessage(
'default-skin-not-found-row-disabled' )
+ ->params( $normalizedKey, $skin
)->plain();
+ $skinsInstalledSnippet[] =
"require_once \"\$IP/skins/$skin/$skin.php\";";
+ }
+ }
+
+ return wfMessage( 'default-skin-not-found' )->params(
+ $wgDefaultSkin,
+ implode( "\n", $skinsInstalledText ),
+ implode( "\n", $skinsInstalledSnippet )
+ )->parseAsBlock();
+ } else {
+ return wfMessage( 'default-skin-not-found-no-skins'
)->params(
+ $wgDefaultSkin
+ )->parseAsBlock();
+ }
+ }
+
+ /**
+ * Outputs the entire contents of the page
+ */
+ public function execute() {
+ $this->html( 'headelement' ) ?>
+ <div id="mw-wrapper">
+ <a
+ id="p-logo"
+ role="banner"
+ href="<?php echo htmlspecialchars(
$this->data['nav_urls']['mainpage']['href'] ) ?>"
+ <?php echo Xml::expandAttributes(
Linker::tooltipAndAccesskeyAttribs( 'p-logo' ) ) ?>
+ >
+ <img
+ src="<?php $this->text( 'logopath' ) ?>"
+ alt="<?php $this->text( 'sitename' ) ?>"
+ />
+ </a>
+
+
+ <div class="warningbox">
+ <?php echo
$this->buildHelpfulInformationMessage() ?>
+ </div>
+
+
+ <div class="mw-body" role="main">
+ <?php if ( $this->data['sitenotice'] ) { ?>
+ <div id="siteNotice"><?php $this->html(
'sitenotice' ) ?></div>
+ <?php } ?>
+
+ <?php if ( $this->data['newtalk'] ) { ?>
+ <div class="usermessage"><?php
$this->html( 'newtalk' ) ?></div>
+ <?php } ?>
+
+ <h1 class="firstHeading">
+ <span dir="auto"><?php $this->html(
'title' ) ?></span>
+ </h1>
+
+ <div id="siteSub"><?php $this->msg( 'tagline' )
?></div>
+
+ <div class="mw-body-content">
+ <div id="contentSub">
+ <?php if (
$this->data['subtitle'] ) { ?>
+ <p><?php $this->html(
'subtitle' ) ?></p>
+ <?php } ?>
+ <?php if (
$this->data['undelete'] ) { ?>
+ <p><?php $this->html(
'undelete' ) ?></p>
+ <?php } ?>
+ </div>
+
+ <?php $this->html( 'bodytext' ) ?>
+
+ <?php $this->html( 'catlinks' ) ?>
+
+ <?php $this->html( 'dataAfterContent'
); ?>
+
+ </div>
+ </div>
+
+
+ <div id="mw-navigation">
+ <h2><?php $this->msg( 'navigation-heading' )
?></h2>
+
+ <form
+ action="<?php $this->text( 'wgScript' )
?>"
+ role="search"
+ class="mw-portlet"
+ id="p-search"
+ >
+ <input type="hidden" name="title"
value="<?php $this->text( 'searchtitle' ) ?>" />
+
+ <h3><label for="searchInput"><?php
$this->msg( 'search' ) ?></label></h3>
+
+ <?php echo $this->makeSearchInput(
array( "id" => "searchInput" ) ) ?>
+ <?php echo $this->makeSearchButton(
'go' ) ?>
+
+ </form>
+
+ <?php
+
+ $this->outputPortlet( array(
+ 'id' => 'p-personal',
+ 'headerMessage' => 'personaltools',
+ 'content' => $this->getPersonalTools(),
+ ) );
+
+ $this->outputPortlet( array(
+ 'id' => 'p-namespaces',
+ 'headerMessage' => 'namespaces',
+ 'content' =>
$this->data['content_navigation']['namespaces'],
+ ) );
+ $this->outputPortlet( array(
+ 'id' => 'p-variants',
+ 'headerMessage' => 'variants',
+ 'content' =>
$this->data['content_navigation']['variants'],
+ ) );
+ $this->outputPortlet( array(
+ 'id' => 'p-views',
+ 'headerMessage' => 'views',
+ 'content' =>
$this->data['content_navigation']['views'],
+ ) );
+ $this->outputPortlet( array(
+ 'id' => 'p-actions',
+ 'headerMessage' => 'actions',
+ 'content' =>
$this->data['content_navigation']['actions'],
+ ) );
+
+ foreach ( $this->getSidebar() as $boxName =>
$box ) {
+ $this->outputPortlet( $box );
+ }
+
+ ?>
+ </div>
+
+ <div id="mw-footer">
+ <?php foreach ( $this->getFooterLinks() as
$category => $links ) { ?>
+ <ul role="contentinfo">
+ <?php foreach ( $links as $key
) { ?>
+ <li><?php $this->html(
$key ) ?></li>
+ <?php } ?>
+ </ul>
+ <?php } ?>
+
+ <ul role="contentinfo">
+ <?php foreach ( $this->getFooterIcons(
'icononly' ) as $blockName => $footerIcons ) { ?>
+ <li>
+ <?php
+ foreach ( $footerIcons
as $icon ) {
+ echo
$this->getSkin()->makeFooterIcon( $icon );
+ }
+ ?>
+ </li>
+ <?php } ?>
+ </ul>
+ </div>
+ </div>
+
+ <?php $this->printTrail() ?>
+ </body></html>
+
+ <?php
+ }
+}
diff --git a/languages/i18n/en.json b/languages/i18n/en.json
index e42d716..5c7f67c 100644
--- a/languages/i18n/en.json
+++ b/languages/i18n/en.json
@@ -3525,5 +3525,9 @@
"action-pagelang": "change the page language",
"log-name-pagelang": "Change language log",
"log-description-pagelang": "This is a log of changes in page
languages.",
- "logentry-pagelang-pagelang": "$1 {{GENDER:$2|changed}} page language
for $3 from $4 to $5."
+ "logentry-pagelang-pagelang": "$1 {{GENDER:$2|changed}} page language
for $3 from $4 to $5.",
+ "default-skin-not-found": "Whoops! The default skin for your wiki
(<code>$wgDefaultSkin</code>), <code>$1</code>, is not available.\n\nYour
installation seems to include the following skins. See
[https://www.mediawiki.org/wiki/Manual:Skin_configuration Manual: Skin
configuration] for information how to enable them and choose the
default.\n\n$2\n\n; If you have just installed MediaWiki:\n: You probably
installed from git, or directly from the source code using some other method.
This is expected.\n:* Try installing some skins from
[https://www.mediawiki.org/wiki/Category:All_skins mediawiki.org's skin
directory].\n:* Download the [https://www.mediawiki.org/wiki/Download tarball
installer], which comes with several skins and extensions. You can copy and
paste the <code>skins/</code> directory from it.\n: Doing this should not
interfere with your git repository if you're a MediaWiki developer.\n\n; If you
have just upgraded MediaWiki:\n: MediaWiki 1.24 and newer no longer
automatically enables installed skins (see
[https://www.mediawiki.org/wiki/Manual:Skin_autodiscovery Manual:Skin
autodiscovery]). You can paste the following lines into LocalSettings.php to
enable all currently installed skins:\n\n<pre>$3</pre>\n\n; If you have just
modified LocalSettings.php:\n: Double-check the skin names for typos.",
+ "default-skin-not-found-no-skins": "Whoops! The default skin for your
wiki (<code>$wgDefaultSkin</code>), <code>$1</code>, is not available.\n\nYou
have no installed skins.\n\n; If you have just installed MediaWiki:\n: You
probably installed from git, or directly from the source code using some other
method. This is expected.\n:* Try installing some skins from
[https://www.mediawiki.org/wiki/Category:All_skins mediawiki.org's skin
directory].\n:* Download the [https://www.mediawiki.org/wiki/Download tarball
installer], which comes with several skins and extensions. You can copy and
paste the <code>skins/</code> directory from it.\n: Doing this should not
interfere with your git repository if you're a MediaWiki developer. See
[https://www.mediawiki.org/wiki/Manual:Skin_configuration Manual: Skin
configuration] for information how to enable skins and choose the default.\n",
+ "default-skin-not-found-row-enabled": "* <code>$1</code> / $2
(enabled)",
+ "default-skin-not-found-row-disabled": "* <code>$1</code> / $2
('''disabled''')"
}
diff --git a/languages/i18n/qqq.json b/languages/i18n/qqq.json
index ad5b288..9683874 100644
--- a/languages/i18n/qqq.json
+++ b/languages/i18n/qqq.json
@@ -3687,5 +3687,9 @@
"action-pagelang": "{{Doc-action|pagelang}}",
"log-name-pagelang": "Display entry for log name for changes in page
language in Special:Log.",
"log-description-pagelang": "Display description for log name for
changes in page language in Special:Log.",
- "logentry-pagelang-pagelang": "{{Logentry}}\nAdditional parameters:\n*
$4 - old language code, or \"[def]\" (hard-coded)\n* $5 - new language code, or
\"[def]\" (hard-coded)"
+ "logentry-pagelang-pagelang": "{{Logentry}}\nAdditional parameters:\n*
$4 - old language code, or \"[def]\" (hard-coded)\n* $5 - new language code, or
\"[def]\" (hard-coded)",
+ "default-skin-not-found": "Message shown when the default skin for this
MediaWiki installation can not be found.\n\nParameters:\n* $1: skin identifier
for the default skin\n* $2: list of installed skins, composed using
{{msg-mw|default-skin-not-found-row-enabled}} and
{{msg-mw|default-skin-not-found-row-disabled}}\n* $3: code snippet to use to
enable installed skins",
+ "default-skin-not-found-no-skins": "Message shown when the default skin
for this MediaWiki installation can not be found and the installation has no
skins at all.\n\nParameters:\n* $1: name of the default skin",
+ "default-skin-not-found-row-enabled": "One row of the list of installed
skins shown as a part of {{msg-mw|default-skin-not-found}}, for an enabled
skin.\n\nParameters:\n* $1: skin identifier\n$2: human-readable skin name",
+ "default-skin-not-found-row-disabled": "One row of the list of
installed skins shown as a part of {{msg-mw|default-skin-not-found}}, for a
disabled skin.\n\nParameters:\n* $1: skin identifier\n$2: human-readable skin
name"
}
--
To view, visit https://gerrit.wikimedia.org/r/148508
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: Id14fbb8733cd8fbb912a724ac658f5e7244364b5
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/core
Gerrit-Branch: master
Gerrit-Owner: Bartosz Dziewoński <[email protected]>
_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits