NonincludableNamespaces
From TestWiki
This extension is designed to emulate and extend the function of the $wgNonincludableNamespaces configuration variable, which was introduced in MediaWiki v1.10.0.
- In versions of MW < 1.10.0, it emulates the functionality of the config variable, along with the additional functionality detailed below.
- In versions of MW >= 1.10.0 there is already code to handle this variable correctly, but the extension adds a couple of short-cuts that make configuration a bit simpler.
Contents |
Usage
This extension adds the full functionality of $wgNonincludableNamespaces, plus the enhancements below, to versions of MediaWiki < 1.10.0. From 1.10.0 upwards, $wgNonincludableNamespaces exists natively in the software, in which case the extension simply implements the additional features.
Emulated features
- If
$wgNonincludableNamespacesis not set, then all transclusion is allowed. - If
$wgNonincludableNamespacesis an array then transclusion is not allowed for any namespaces included in the array. Elements must be numeric namespace ids.
Additional features
- If
$wgNonincludableNamespacesis not an array then it is evaluated as a boolean with the following results:- If
Truethen no transclusion is allowed, except from the template namespace. - If
Falsethen no transclusion is allowed at all.
- If
Developers
The extension defines the constant NIN_Installed when it is loaded, so extension developers can check whether the $wgNonincludableNamespaces variable is supported, either via MW or this extension, by using the following code:
if ( version_compare($wgVersion, '1.10.0', '>=') || NIN_Installed ) { // Installed }
Source
Copy the source code to a file called NonincludableNamespaces.php in your extensions directory, and add the following line to the bottom of your LocalSettings.php file:
include_once("extensions/NonincludableNamespaces.php");
You may then use the variable $wgNonincludableNamespaces to configure your wiki, as described above.
Live sourcecode viewer: NonincludableNamespaces.php
Last modified: 2008-10-23 02:12:02
<?php if (!defined('MEDIAWIKI')) die("MediaWiki extensions cannot be run directly."); /** * An extension to emulate (and slightly extend) the functionality of * $wgNonincludableNamespaces. * * @package MediaWiki * @subpackage Extensions * * @author Mark Clements <mclements at kennel17 dot co dot uk> * @copyright copyright © 2007, Mark Clements * @license http://creativecommons.org/licenses/by-sa/2.5/ cc-by-sa 2.5 or later * @version $Rev: 114 $ */ // Set version number from SVN revision tag. $NIN_Version = substr('$Rev: 114 $', 6, -2); // Set description depending on MW version in use. $NIN_Description = '[http://www.mediawiki.org/wiki/Manual:$wgNonincludableNamespaces ' . '$wgNonincludableNamespaces]'; if (version_compare($wgVersion, '1.10.0', '<')) $NIN_Description = 'emulates (and extends) ' . $NIN_Description . ' for MW < 1.10.0'; else $NIN_Description = 'makes configuration of ' . $NIN_Description . ' easier for a few common situations'; // Setup extension credits $wgExtensionCredits['other'][] = array( 'name' => "NonincludableNamespaces", 'version' => "r" . $NIN_Version, 'author' => "Mark Clements", 'description' => $NIN_Description, 'url' => "http://www.mediawiki.org/wiki/User_talk:HappyDog", ); // Tidy up global vars. unset($NIN_Version); unset($NIN_Description); $wgExtensionFunctions[] = "wfNIN_Setup"; /* Emulates the functionality of $wgNonincludableNamespaces: (http://www.mediawiki.org/wiki/Manual:%24wgNonincludableNamespaces) * If $wgNonincludableNamespaces is not set, then all transclusion is allowed. * If $wgNonincludableNamespaces is an array then transclusion is not allowed for any namespaces included in the array. Elements must be numeric namespace ids. ...with a few additional features: * If $wgNonincludableNamespaces is not an array, then it is evaluated as a boolean, with the following results: * IF TRUE then NO transclusion is allowed, except from the template namespace. * IF FALSE then NO transclusion is allowed at all. This extension adds the full functionality of $wgNonincludableNamespaces, including the above enhancements to versions of MediaWiki < 1.10.0. From 1.10.0 upwards, $wgNonincludableNamespaces exists natively in the software, in which case the extension simply implements the additional features described above. */ ///////////////////////////////////////////////// define("NIN_Installed", true); ///////////////////////////////////////////////// function wfNIN_Setup() { global $wgNonincludableNamespaces; global $wgVersion, $wgCanonicalNamespaceNames; //////// TIDY INPUT // Check value of $wgNonincludableNamespaces and adjust it so it contains a valid array. // * If not set, or False, convert to empty array. // * If True, convert // all Namespace IDs that should not be transcludable (or an empty array, if all are transcludable). // NOT SET -> No namespaces disallowed. if (!isset($wgNonincludableNamespaces)) { $wgNonincludableNamespaces = array(); } // ARRAY -> Array of namespaces IDs that are blocked from transclusion. No modification necessary. elseif (is_array($wgNonincludableNamespaces)) { // Drop through } // NON-ARRAY -> Evaluate as a boolean and block all namespaces (or all but template namespace). else { // If $wgNonincludableNamespaces is true then pages in the template namespace may be included, // otherwise they are blocked from inclusion. if ($wgNonincludableNamespaces == true) $AllowTemplateInclusion = true; else $AllowTemplateInclusion = false; // Main namespace is not in CanonicalNamespaceNames, as it has no name, so add it manually here. $wgNonincludableNamespaces = array(NS_MAIN); // Then add all defined namespaces (except the Template namespace if true). This includes any // namespaces specified in $wgExtraNamespaces. foreach ($wgCanonicalNamespaceNames as $NS_ID => $NS_Name) { // If $AllowTemplateInclusion is true then we don't include the template namespace in the array. if (!($AllowTemplateInclusion && $NS_ID == NS_TEMPLATE)) { $wgNonincludableNamespaces[] = $NS_ID; } } } // //////// END TIDY INPUT // If version is < 1.10.0 (and there are any namespaces that need blocking) // we need to add a handler to deal with the above settings. if (version_compare($wgVersion, '1.10.0', '<')) { if (count($wgNonincludableNamespaces) > 0) $wgHooks['ParserAfterStrip'][] = "wfNIN_NonincludableNamespaces"; } // MW 1.10 and above will automatically handle the above settings appropriately. } ///////////////////////////////////////////////// function wfNIN_NonincludableNamespaces(&$Parser, &$Text, &$StripState) { global $wgNonincludableNamespaces; global $wgContLang, $wgCanonicalNamespaceNames; $BlockedNamespaces = array(); $LocalNamespaces = $wgContLang->getNamespaces(); // Build list of blocked namespaces. foreach($wgNonincludableNamespaces as $NS_ID) { // Add the 'no prefix' option for the template namespace (as well as the actual // namespace name(s), which are added below). if ($NS_ID == NS_TEMPLATE) $BlockedNamespaces[] = ""; // For the main namespace, there is no name so we just add the colon. if ($NS_ID == NS_MAIN) $BlockedNamespaces[] = ":"; // For all other namespaces, we add the canonical (English) name which works on all // wikis, plus the localised name (if different). else { if (isset($wgCanonicalNamespaceNames[$NS_ID])) $BlockedNamespaces[] = $wgCanonicalNamespaceNames[$NS_ID] . ":"; if (isset($LocalNamespaces[$NS_ID]) && $LocalNamespaces[$NS_ID] != $wgCanonicalNamespaceNames[$NS_ID]) { $BlockedNamespaces[] = $LocalNamespaces[$NS_ID] . ":"; } } } // For each blocked namespace, filter out all transclusions of that namespace. foreach ($BlockedNamespaces as $NS_Name) { // 0 - Entire matched text (from one char before start of template tag to end of content). // 1 - Character before start of template tag (or blank if at start of content). // 2 - Namespace (including colon) // 3 - Page name // 4 - Remainder of page content - to be checked to find correct closing tag. $Regex = '/(^|[^{])\{\{(' . $NS_Name . ')([^|}]+)(.*)/is'; $SearchText = $Text; // Match all transclusions of this namespace ($Matches[2] is namespace, $Matches[3] is page). while (preg_match($Regex, $SearchText, $Matches)) { // Build the Link that will be used to replace the template parameter. $Link = $Matches[3]; if ($Matches[2] == "") $Link = $wgContLang->getNsText(NS_TEMPLATE); elseif ($Matches[2] != ":") $Link = $Matches[2] . $Link; $Link = "[[" . $Link . "]]"; // Work out the BadTemplateCode that will be replaced by the above link. $Pos = 0; // This is an array of tags that need to be closed, which is used like a stack. // Whenever an opening tag is found it is unshift()ed onto the front of the array, // and whenever a closing tag is matched, it is shift()ed off again. This ensures // that template calls that include templates/special parameters/parser functions, etc. // as parameters are properly replaced. $TagsToMatch = array("}}"); $BadTemplateCode = ""; $Source = $Matches[4]; while (($NextClosePos = strpos($Source, $TagsToMatch[0], $Pos)) !== false) { $NextOpenPos = strpos($Source, "{{{", $Pos); if ($NextOpenPos !== false && $NextOpenPos < $NextClosePos) { array_unshift($TagsToMatch, "}}}"); $Pos = $NextOpenPos + 3; continue; } $NextOpenPos = strpos($Source, "{{", $Pos); if ($NextOpenPos !== false && $NextOpenPos < $NextClosePos) { array_unshift($TagsToMatch, "}}"); $Pos = $NextOpenPos + 2; continue; } // If no opening tags before the matching close tag, remove it from the array and // update the Pos to search from. $Pos = $NextClosePos + strlen($TagsToMatch[0]); array_shift($TagsToMatch); // If no more tags, then we can exit the loop. if (count($TagsToMatch) == 0) break; } $BadTemplateCode = substr($Source, 0, $Pos); // Only replace code if all tags are closed, otherwise this is an invalid template inclusion // and the software will ignore it automatically. if ($BadTemplateCode != "") { $BadTemplateCode = "{{" . $Matches[2] . $Matches[3] . $BadTemplateCode; $Text = str_replace($BadTemplateCode, $Link, $Text); } // Only search in the remainder of the text. This wouldn't be needed if we could guarantee // that all tags were closed, but as we can't we only search the remainder to avoid getting // into an infinite loop. $SearchText = $Source; } } return true; }
