Extension:ConditionalMenus
ConditionalMenus Release status: unknown |
|
---|---|
Implementation | Tag |
License | No license specified |
Download | see below |
Translate the ConditionalMenus extension if it is available at translatewiki.net |
|
Check usage and version matrix; code metrics |
ConditionalMenus 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:
<submenu> <iftitle>ConditionalMenus Extension</iftitle> <ifcategory>Leet Category</ifcategory> <ifancestor>Abraham Category</ifancestor> <level>3</level> <content> [[Link1]] [[Link2]] [[Link3]] </content> </submenu>
Contents
What does it do?[edit | edit source]
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
What is it used for?[edit | edit source]
[edit | edit source]
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]] <submenu> <iftitle>Characters Guide</iftitle> <iftitle>Joe</iftitle> <ifcategory>Characters Guide</ifcategory> <level>2</level> <content> [[Joe]] [[Mac]] [[Peter]] </content> </submenu> [[: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[edit | edit source]
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:
<submenu> <group>HeaderImage</group> <ifancestor>Work</ifancestor> <content>[[Image:Header-Work.jpg]]</content> </submenu><submenu> <group>HeaderImage</group> <ifancestor>Family</ifancestor> <content>[[Image:Header-Family.jpg]]</content> </submenu><submenu> <group>HeaderImage</group> <ifancestor>Nonsense</ifancestor> <content>[[Image:Header-Nonsense.jpg]]</content> </submenu><submenu> <group>HeaderImage</group> <else/> <content>[[Image:Header-Default.jpg]]</content> </submenu>
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[edit | edit source]
- Copy everything inside "Code" below into a file called "navigation.php" and put it under your "extensions" folder
- In LocalSettings.php, add: include("extensions/navigation.php");
- Done! :)
Code[edit | edit source]
<?php $wgExtensionFunctions[] = "wfNavigationExtension"; function wfNavigationExtension() { global $wgParser; $wgParser->setHook("submenu", "submenusExtension" ); } /** * This extension parses: * <submenu> * <group></group> * <iftitle></iftitle> * <ifcategory></ifcategory> * <ifancestor></ifancestor> * <else/> * <content></content> * <level></level> * </submenu> */ 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 <group> // tag *and* this submenu is actually displayed, all of these groups will be written // into the global submenuGroups array. So submenus with <else/>-Tag will know there's // nothing left to do for them. preg_match_all("@<group>(.*)</group>@isU", $input, $matches); $representgroup = array(); foreach ($matches[1] as $match) { $representgroup[] = trim($match); } // process allow list preg_match_all("@<iftitle>(.*)</iftitle>@isU", $input, $matches); $allowtitle = array(); foreach ($matches[1] as $match) { $allowtitle[] = trim($match); } preg_match_all("@<ifcategory>(.*)</ifcategory>@isU", $input, $matches); $allowcategory = array(); foreach ($matches[1] as $match) { $match = preg_replace("@($categoryNamespaceName:\s?)?(.*)@is", "\\2", $match); $allowcategory[] = trim($match); } preg_match_all("@<ifancestor>(.*)</ifancestor>@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, "<else/>") || substr_count($input, "<else />")) { $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("@<content>(.*)</content>@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("@<level>(.*)</level>@isU", $input, $matches); $level = intval(trim($matches[1])); if ($level) { $returnval = preg_replace("@<p>(.*)</p>@isU", "\\1", $returnval); $returnval = preg_replace("@^.*$@m", "<li>\\0</li>", $returnval); $returnval = preg_replace("@<li>\s*</li>@", "", $returnval); for ($i = 0; $i < $level; $i++) { $returnval = "<ul>$returnval</ul>"; } } // 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; } ?>