Extension:ConditionalMenus

This extension allows to show or not show certain parts of a page, depending on what the page name is and what categories are in the ancestry of the page. It is useful in pages that are usually included, to allow for dynamic menus or headers.

The extension parses the following example:

ConditionalMenus Extension Leet Category Abraham Category 3

Link1 Link2 Link3

What does it do?
In our example: If the page's name is "ConditionalMenus Extension" then anything inside the content tag is shown. If the page is of category "Leet Category" then anything inside the content tag is shown If the page is of category "Abraham Category" or is of a category that is of category "Abraham Category" (and so on...) then anything inside the content tag is shown In any other scenario nothing is parsed

Conditionally opened submenu
For example, you have navigation like:

Introduction Series information Category:Characters Guide Category:Episode List Goofs

And you want to display the list of characters but ONLY in the character pages (and maybe in an intro page), then you'd use:

Introduction Series information Category:Characters Guide Characters Guide Joe Characters Guide 2 Joe Mac Peter Category:Episode List Goofs

this would show the "Joe, Mac and Peter" links to the user ONLY if he is inside the "Characters Guide" page, or if he is inside the Joe page, or if he is inside any page that belongs to the "characters guide" category

This way if the user is browsing the "Introduction" pages he sees the small menu, and as soon as he enters to the "Characters Guide" category page he also sees the list of characters

Different header images for different categories, one default header
Suppose the pages of your wiki are divided into three main categories, say "Work", "Family", and "Nonsense". Your Skin includes a header with an image at the top of each page, and you want this image to be different depending on the category of the current site. Of course, there are also pages that are not part of your trinity, for example project pages, special pages, and any page that hasn't been categorized yet. You want to give these pages a default header image.

You would write your header page (the one that is included at the top) as follows:

HeaderImage Work HeaderImage Family HeaderImage Nonsense HeaderImage

The last submenu is the else-case: It looks up whether the content of any submenus of the HeaderImage group have already been displayed and if not, displays its own content.

How to use it

 * 1) Copy everything inside "Code" below into a file called "navigation.php" and put it under your "extensions" folder
 * 2) In LocalSettings.php, add: include("extensions/navigation.php");
 * 3) Done! :)

Code
setHook("submenu", "submenusExtension" ); }

/** * This extension parses: * *        *        *        *        *       *        *        *  */ function submenusExtension($input, $argv, $parser) {       global $wgTitle, $wgUser, $wgArticle, $wgContLang, $submenuGroup;

$namespaceNames = $wgContLang->getNamespaces; $categoryNamespaceName = $namespaceNames[NS_CATEGORY]; // initialize our array $matches = array;

// find out categories this page belongs to       $categories = $wgTitle->getParentCategories; if (!is_array($categories)) $categories = array; $categories = array_keys($categories);

// strip namespace prefix foreach ($categories as &$category) { $category = preg_replace("@($categoryNamespaceName:\s?)?(.*)@is", "\\2", $category); }

// If this submenu belongs to one or more submenuGroups specified by the // tag *and* this submenu is actually displayed, all of these groups will be written // into the global submenuGroups array. So submenus with -Tag will know there's       // nothing left to do for them. preg_match_all("@ (.*) @isU", $input, $matches); $representgroup = array; foreach ($matches[1] as $match) { $representgroup[] = trim($match); }       // process allow list preg_match_all("@ (.*) @isU", $input, $matches); $allowtitle = array; foreach ($matches[1] as $match) {               $allowtitle[] = trim($match); }       preg_match_all("@ (.*) @isU", $input, $matches); $allowcategory = array; foreach ($matches[1] as $match) {               $match = preg_replace("@($categoryNamespaceName:\s?)?(.*)@is", "\\2", $match); $allowcategory[] = trim($match); }

preg_match_all("@ (.*) @isU", $input, $matches); $allowancestor = array; foreach ($matches[1] as $match) {               $match = preg_replace("@($categoryNamespaceName:\s?)?(.*)@is", "\\2", $match); $allowancestor[] = trim($match); }

if (substr_count($input, " ") || substr_count($input, " ")) { $allowotherwise = TRUE; }

// check if we are to parse content $allowed = false; if (in_array($wgTitle->mTextform, $allowtitle) || in_array($wgTitle->mDbkeyform, $allowtitle)) {               $allowed = true; }       // No matching title? Maybe the page is in an "allow category". if (!$allowed) { foreach ($categories as $category) {                       if (in_array(trim($category), $allowcategory)) {                               $allowed = true; break; }                              }        }

// Still not allowed? Maybe the page has an "allow ancestor category". if (!$allowed) { foreach ($allowancestor as $ancestor) { if (hasAncestorCategory($wgTitle, $ancestor, $categoryNamespaceName)) {                               $allowed = true; break; }               }        }

// If this is an else-case submenu, check whether any of the submenuGroups it belongs // to is not yet represented by any submenu on this page if ($allowotherwise) { foreach ($representgroup as $group) { if (!$submenuGroup[$group]) { $allowed = TRUE; break; }               }        }

// if allowed print content, otherwise return blank if (!$allowed) {               return ""; }       preg_match("@ (.*) @isU", $input, $matches); $content = trim($matches[1]); if (!$content) {               return ""; }       // parse the content $output = $parser->recursiveTagParse($content); // rather ugly hack to delete empty dots $returnval = trim($output); preg_match("@ (.*) @isU", $input, $matches); $level = intval(trim($matches[1])); if ($level) {               $returnval = preg_replace("@ (.*) @isU", "\\1", $returnval); $returnval = preg_replace("@^.*$@m", "\\0", $returnval); $returnval = preg_replace("@\s*@", "", $returnval); for ($i = 0; $i < $level; $i++) {                       $returnval = "$returnval"; }       }

// announce that all submenuGroups that this submenu belongs to are now // represented foreach ($representgroup as $group) { $submenuGroup[$group] = TRUE; }       // return final value return "\r\n".$returnval; }

/** * Checks whether a page is a descendant of a given category. * @param title a Title object, representing the given page * @param targetName the name of the given category, WITHOUT prefix * @param categoryNamespaceName the name of the category namespace * @returns true if the page represented by $title is a descendant *         of a category witht the name $targetName */ function hasAncestorCategory($title, $targetName, $categoryNamespaceName) { $parentNames = $title->getParentCategories; if (!is_array($parentNames)) $parentNames = array; $parentNames = array_keys($parentNames);

foreach ($parentNames as &$parentName) { if ($parentName == "$categoryNamespaceName:$targetName" ||			hasAncestorCategory(Title::newFromText($parentName), $targetName, $categoryNamespaceName)) {			return true; }       }

return false; }

?>