r113252 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r113251‎ | r113252 | r113253 >
Date:17:31, 7 March 2012
Author:netbrain
Status:deferred (Comments)
Tags:
Comment:
initial import of SideBarMenu wikimedia extension
Modified paths:
  • /trunk/extensions/SideBarMenu/README (modified) (history)
  • /trunk/extensions/SideBarMenu/SideBarMenu.body.php (added) (history)
  • /trunk/extensions/SideBarMenu/SideBarMenu.i18n.php (added) (history)
  • /trunk/extensions/SideBarMenu/SideBarMenu.php (added) (history)
  • /trunk/extensions/SideBarMenu/includes (added) (history)
  • /trunk/extensions/SideBarMenu/includes/MenuItem.php (added) (history)
  • /trunk/extensions/SideBarMenu/includes/MenuParser.php (added) (history)
  • /trunk/extensions/SideBarMenu/test (added) (history)
  • /trunk/extensions/SideBarMenu/test/MenuItemTest.php (added) (history)
  • /trunk/extensions/SideBarMenu/test/MenuParserTest.php (added) (history)

Diff [purge]

Index: trunk/extensions/SideBarMenu/test/MenuParserTest.php
@@ -0,0 +1,214 @@
 2+<?php
 3+
 4+class MenuParserTest extends MediaWikiTestCase
 5+{
 6+
 7+ public function testValidInputWhenNull(){
 8+ $this->assertFalse(MenuParser::isValidInput(null));
 9+ }
 10+
 11+ public function testValidInputWhenEmpty(){
 12+ $this->assertFalse(MenuParser::isValidInput(""));
 13+ }
 14+
 15+ public function testValidInput(){
 16+ $this->assertTrue(MenuParser::isValidInput("+MenuItem"));
 17+ }
 18+
 19+ public function testIsRoot(){
 20+ $isRoot = MenuParser::isRoot("MenuItem");
 21+ $this->assertTrue($isRoot);
 22+ }
 23+
 24+ public function testIsNotRoot(){
 25+ $isRoot = MenuParser::isRoot("*MenuItem");
 26+ $this->assertFalse($isRoot);
 27+ }
 28+
 29+ public function testGetLevelWhenNull(){
 30+ $this->assertEquals(0,MenuParser::getLevel(null));
 31+ }
 32+
 33+ public function testGetLevelWhenEmpty(){
 34+ $this->assertEquals(0,MenuParser::getLevel(""));
 35+ }
 36+
 37+ public function testGetLevelWhenValidButNoStars(){
 38+ $this->assertEquals(0,MenuParser::getLevel(""));
 39+ }
 40+
 41+ public function testGetLevelWithValid(){
 42+ $this->assertEquals(3,MenuParser::getLevel("***MenuItem"));
 43+ }
 44+
 45+ public function testGetExpandedParameterWhenNoneSupplied(){
 46+ //default is false
 47+ $this->assertFalse(MenuParser::getExpandedParameter("MenuItem"));
 48+ }
 49+
 50+ public function testGetExpandedParameterWhenNotExpanded(){
 51+ $this->assertFalse(MenuParser::getExpandedParameter("-MenuItem"));
 52+ }
 53+
 54+ public function testGetExpandedParameterWhenExpanded(){
 55+ $this->assertTrue(MenuParser::getExpandedParameter("+MenuItem"));
 56+ }
 57+
 58+ public function testGetTextParameter(){
 59+ $this->assertEquals("MenuItem",MenuParser::getTextParameter("+***MenuItem"));
 60+ $this->assertEquals("+MenuItem",MenuParser::getTextParameter("+***+MenuItem"));
 61+ $this->assertEquals("MenuItem",MenuParser::getTextParameter("-MenuItem"));
 62+ $this->assertEquals("MenuItem",MenuParser::getTextParameter("-*MenuItem"));
 63+ $this->assertEquals("MenuItem",MenuParser::getTextParameter("MenuItem"));
 64+ $this->assertEquals("+*MenuItem",MenuParser::getTextParameter("+***+*MenuItem"));
 65+ }
 66+
 67+ public function testGetMenuItemWhenInputIsNull(){
 68+ $this->setExpectedException('InvalidArgumentException');
 69+ $this->assertNull(MenuParser::getMenuItem(null));
 70+ }
 71+
 72+ public function testGetMenuItemWhenInputIsEmpty(){
 73+ $this->setExpectedException('InvalidArgumentException');
 74+ $this->assertNull(MenuParser::getMenuItem(""));
 75+ }
 76+
 77+ public function testGetMenuItemWhenInputIsValid(){
 78+ $data = "MenuItem";
 79+ $menuItem = MenuParser::getMenuItem($data);
 80+ $this->assertNotNull($menuItem);
 81+ $this->assertEquals($data,$menuItem->getText());
 82+ $this->assertFalse($menuItem->isExpanded()); //false is default
 83+ }
 84+
 85+ public function testGetMenuItemWhenInputIsValidAndExpandIsSet(){
 86+ $text = "MenuItem";
 87+ $data = "+".$text;
 88+ $menuItem = MenuParser::getMenuItem($data);
 89+ $this->assertNotNull($menuItem);
 90+ $this->assertEquals($text,$menuItem->getText());
 91+ $this->assertTrue($menuItem->isExpanded()); //false is default
 92+ }
 93+
 94+ public function testParseDataIntoHierarchicalArray(){
 95+ $data = "MenuItem";
 96+ $array = MenuParser::parseDataIntoHierarchicalArray($data);
 97+ $this->assertNotNull($array);
 98+ $this->assertEquals($data,$array[0]);
 99+ }
 100+
 101+ public function testParseDataIntoHierarchicalArrayWithSubLevel(){
 102+ $lines = array("MenuItem","*SubMenuItem");
 103+ $data = join("\n",$lines);
 104+ $array = MenuParser::parseDataIntoHierarchicalArray($data);
 105+ $this->assertNotNull($array);
 106+ $this->assertArrayHasKey($lines[0],$array);
 107+ $this->assertEquals(
 108+ array(
 109+ 'MenuItem' => array(
 110+ '*SubMenuItem'
 111+ )
 112+ ),$array
 113+ );
 114+ }
 115+
 116+ public function testParseDataIntoHierarchicalArrayWithSeveralSubLevels(){
 117+ $lines = array("MenuItem","*SubMenuItem","*SubMenuItem2","**SubMenuItemOf2");
 118+ $data = join("\n",$lines);
 119+ $array = MenuParser::parseDataIntoHierarchicalArray($data);
 120+ $this->assertNotNull($array);
 121+ $this->assertEquals(
 122+ array(
 123+ 'MenuItem' => array(
 124+ '*SubMenuItem',
 125+ '*SubMenuItem2' => array(
 126+ '**SubMenuItemOf2'
 127+ )
 128+ )
 129+ ),$array
 130+ );
 131+ }
 132+
 133+ public function testParseDataIntoHierarchicalArrayWithSubLevelAndBack(){
 134+ $lines = array("MenuItem","*SubMenuItem","MenuItem2");
 135+ $data = join("\n",$lines);
 136+ $array = MenuParser::parseDataIntoHierarchicalArray($data);
 137+ $this->assertNotNull($array);
 138+ $this->assertEquals(
 139+ array(
 140+ 'MenuItem' => array(
 141+ '*SubMenuItem'
 142+ ),
 143+ 'MenuItem2'
 144+ ),$array
 145+ );
 146+ }
 147+
 148+ public function testParseDataIntoHierarchicalArrayWithSubLevelAndBackSeveralLevels(){
 149+ $lines = array("MenuItem","*SubMenuItem1","**SubMenuItem2","***SubMenuItem3","MenuItem2");
 150+ $data = join("\n",$lines);
 151+ $array = MenuParser::parseDataIntoHierarchicalArray($data);
 152+ $this->assertNotNull($array);
 153+ $this->assertEquals(
 154+ array(
 155+ 'MenuItem' => array(
 156+ '*SubMenuItem1' => array(
 157+ '**SubMenuItem2' => array(
 158+ '***SubMenuItem3'
 159+ )
 160+ )
 161+ ),
 162+ 'MenuItem2'
 163+ ),$array
 164+ );
 165+ }
 166+
 167+
 168+ public function testGetMenuWithInvalidInput(){
 169+ $this->assertNull(MenuParser::getMenuTree(null));
 170+ $this->assertNull(MenuParser::getMenuTree(""));
 171+ }
 172+
 173+ public function testGetMenuWithValidInput(){
 174+ $menu = MenuParser::getMenuTree("MenuItem");
 175+ $this->assertNotNull($menu);
 176+ $this->assertTrue($menu->isRoot());
 177+ $this->assertEquals(1,sizeof($menu->getChildren()));
 178+
 179+ $children = $menu->getChildren();
 180+ $this->assertEquals("MenuItem",$children[0]->getText());
 181+ }
 182+
 183+ public function testGetMenuWithValidComplexInput(){
 184+ $data = array(
 185+ 'MenuItem1',
 186+ '*SubMenuItem1',
 187+ '*SubMenuItem2',
 188+ '*SubMenuItem3',
 189+ '**SubMenuItem1Of1',
 190+ '**SubMenuItem2Of1',
 191+ 'MenuItem2',
 192+ '*SubMenuItem1OfMenuItem2'
 193+ );
 194+ $menu = MenuParser::getMenuTree(join("\n",$data));
 195+ $this->assertNotNull($menu);
 196+ $this->assertEquals(2,sizeof($menu->getChildren()));
 197+
 198+ }
 199+
 200+ public function testGetMenuWithSeveralLineBreaks(){
 201+ $data = array(
 202+ '',
 203+ 'MenuItem1',
 204+ '',
 205+ ''
 206+ );
 207+ $menu = MenuParser::getMenuTree(join("\n",$data));
 208+ $this->assertNotNull($menu);
 209+ $this->assertEquals(1,sizeof($menu->getChildren()));
 210+
 211+ $children = $menu->getChildren();
 212+ $this->assertEquals("MenuItem1",$children[0]->getText());
 213+
 214+ }
 215+}
Index: trunk/extensions/SideBarMenu/test/MenuItemTest.php
@@ -0,0 +1,104 @@
 2+<?php
 3+
 4+class MenuItemTest extends MediaWikiTestCase
 5+{
 6+ private $menuItem;
 7+
 8+ protected function setUp()
 9+ {
 10+ $this->menuItem = new MenuItem();
 11+ }
 12+
 13+ public function testIsRoot(){
 14+ $this->assertTrue($this->menuItem->isRoot());
 15+ }
 16+
 17+ public function testIsNotRoot(){
 18+ $this->menuItem->setParent(new MenuItem());
 19+ $this->assertFalse($this->menuItem->isRoot());
 20+ }
 21+
 22+ public function testGetLevelWhenRoot(){
 23+ $this->assertEquals(0,$this->menuItem->getLevel());
 24+ }
 25+
 26+ public function testGetLevelWhenChild(){
 27+ $this->menuItem->setParent(new MenuItem());
 28+ $this->assertEquals(1,$this->menuItem->getLevel());
 29+ }
 30+
 31+ public function testGetLevelWhenSeveralChildren(){
 32+ $prev = $this->menuItem;
 33+ for($x = 0; $x < 10; $x++){
 34+ $child = new MenuItem();
 35+ $child->setParent($prev);
 36+ $prev = $child;
 37+
 38+ }
 39+ $this->assertEquals(10,$prev->getLevel());
 40+ }
 41+
 42+ public function testAddChildAlsoAddsParent(){
 43+ $child = new MenuItem();
 44+ $this->menuItem->addChild($child);
 45+ $this->assertContains($child,$this->menuItem->getChildren());
 46+ $this->assertEquals($child->getParent(),$this->menuItem);
 47+ }
 48+
 49+ public function testAddSameChildSeveralTimes(){
 50+ $child = new MenuItem();
 51+ for($x = 0; $x < 3; $x++){
 52+ $this->menuItem->addChild($child);
 53+ }
 54+ $this->assertEquals(1,sizeof($this->menuItem->getChildren()));
 55+ }
 56+
 57+ public function testAddParentAlsoAddsChild(){
 58+ $parent = new MenuItem();
 59+ $this->menuItem->setParent($parent);
 60+ $this->assertContains($this->menuItem,$parent->getChildren());
 61+ }
 62+
 63+ public function testToHTMLOnRootMenuItem(){
 64+ $html = $this->menuItem->toHTML();
 65+ $this->assertEquals("",$html);
 66+ }
 67+
 68+ public function testToHTMLOnProperMenuItem(){
 69+ $menuItemChild = new MenuItem();
 70+ $menuItemChild->setText("MenuItem1");
 71+ $this->menuItem->addChild($menuItemChild);
 72+ $html = $this->menuItem->toHTML();
 73+ $this->assertEquals('<ul class="sidebar-menu sidebar-menu-0"><li class="sidebar-menu-item sidebar-menu-item-1 sidebar-menu-item-collapsed"><div class="sidebar-menu-item-text sidebar-menu-item-text-1">MenuItem1</div></li></ul>',$html);
 74+ }
 75+
 76+ public function testToHTMLOnSeveralMenuItems(){
 77+ $menuItemChild1 = new MenuItem();
 78+ $menuItemChild1->setText("MenuItem1");
 79+ $menuItemChild2 = new MenuItem();
 80+ $menuItemChild2->setText("MenuItem2");
 81+
 82+ $this->menuItem->addChild($menuItemChild1);
 83+ $this->menuItem->addChild($menuItemChild2);
 84+
 85+ $html = $this->menuItem->toHTML();
 86+ $this->assertEquals('<ul class="sidebar-menu sidebar-menu-0"><li class="sidebar-menu-item sidebar-menu-item-1 sidebar-menu-item-collapsed"><div class="sidebar-menu-item-text sidebar-menu-item-text-1">MenuItem1</div></li><li class="sidebar-menu-item sidebar-menu-item-1 sidebar-menu-item-collapsed"><div class="sidebar-menu-item-text sidebar-menu-item-text-1">MenuItem2</div></li></ul>',$html);
 87+ }
 88+
 89+ public function testToHTMLOnSeveralMenuItemsWithSublevels(){
 90+ $menuItemChild1 = new MenuItem();
 91+ $menuItemChild1->setText("MenuItem1");
 92+ $menuItemChild2 = new MenuItem();
 93+ $menuItemChild2->setText("MenuItem2");
 94+
 95+ $this->menuItem->addChild($menuItemChild1);
 96+ $this->menuItem->addChild($menuItemChild2);
 97+
 98+ $subLevel1 = new MenuItem();
 99+ $subLevel1->setText("SubMenuItem1");
 100+ $subLevel1->setParent($menuItemChild2);
 101+
 102+ $html = $this->menuItem->toHTML();
 103+ $this->assertEquals('<ul class="sidebar-menu sidebar-menu-0"><li class="sidebar-menu-item sidebar-menu-item-1 sidebar-menu-item-collapsed"><div class="sidebar-menu-item-text sidebar-menu-item-text-1">MenuItem1</div></li><li class="sidebar-menu-item sidebar-menu-item-1 sidebar-menu-item-collapsed"><div class="sidebar-menu-item-text sidebar-menu-item-text-1">MenuItem2</div><ul class="sidebar-menu sidebar-menu-1"><li class="sidebar-menu-item sidebar-menu-item-2 sidebar-menu-item-collapsed"><div class="sidebar-menu-item-text sidebar-menu-item-text-2">SubMenuItem1</div></li></ul></li></ul>',$html);
 104+ }
 105+}
Index: trunk/extensions/SideBarMenu/SideBarMenu.body.php
Index: trunk/extensions/SideBarMenu/SideBarMenu.i18n.php
Index: trunk/extensions/SideBarMenu/SideBarMenu.php
@@ -0,0 +1,63 @@
 2+<?php
 3+
 4+if (!defined('MEDIAWIKI')) {
 5+ die('Not an entry point.');
 6+}
 7+
 8+$wgExtensionCredits['parserhook'][] = array(
 9+ 'path' => __FILE__,
 10+ 'name' => 'SideBarMenu',
 11+ 'version' => 0.1,
 12+ 'author' => 'Kim Eik',
 13+ 'url' => 'https://www.mediawiki.org/wiki/Extension:SideBarMenu',
 14+ 'descriptionmsg' => 'A simple sidebar menu parser which creates collapsable/expandable menus and sub-menus.'
 15+);
 16+
 17+
 18+// Specify the function that will initialize the parser function.
 19+$wgHooks['ParserFirstCallInit'][] = 'init';
 20+
 21+// Specify the function that will register the magic words for the parser function.
 22+$wgHooks['LanguageGetMagic'][] = 'registerMagicWords';
 23+
 24+// Sepcify phpunit tests
 25+$wgHooks['UnitTestsList'][] = 'registerUnitTests';
 26+
 27+//Autoload
 28+$wgMyExtensionIncludes = dirname(__FILE__) . '/includes';
 29+## Special page class
 30+$wgAutoloadClasses['MenuParser'] = $wgMyExtensionIncludes . '/MenuParser.php';
 31+$wgAutoloadClasses['MenuItem'] = $wgMyExtensionIncludes . '/MenuItem.php';
 32+
 33+
 34+function init(&$parser){
 35+ $parser->setHook('sidebarmenu','renderFromTag');
 36+ return true;
 37+}
 38+
 39+function registerMagicWords(&$magicWords, $langCode){
 40+ $magicWords['sidebarmenu'] = array(0,'sidebarmenu');
 41+ return true;
 42+}
 43+
 44+function renderFromTag( $input, array $args, Parser $parser, PPFrame $frame ){
 45+ try{
 46+ $menuHTML = MenuParser::getMenuTree($input)->toHTML();
 47+ return $parser->recursiveTagParse($menuHTML,$frame);
 48+ }catch(Exception $x){
 49+ wfDebug("An error occured during parsing of: '$input' caught exception: $x");
 50+ return "FATAL ERROR: Could not parse the following input:</br><pre>$input</pre>";
 51+ }
 52+}
 53+
 54+function registerUnitTests( &$files ) {
 55+ $testDir = dirname( __FILE__ ) . '/test/';
 56+ $testFiles = scandir($testDir);
 57+ foreach($testFiles as $testFile){
 58+ $absoluteFile = $testDir . $testFile;
 59+ if(is_file($absoluteFile)){
 60+ $files[] = $absoluteFile;
 61+ }
 62+ }
 63+ return true;
 64+}
Index: trunk/extensions/SideBarMenu/includes/MenuParser.php
@@ -0,0 +1,123 @@
 2+<?php
 3+class MenuParser {
 4+
 5+ public static function isRoot($line)
 6+ {
 7+ return !self::startsWith($line, '*');
 8+ }
 9+
 10+ public static function isValidInput($data)
 11+ {
 12+ return !(is_null($data) || strlen($data) == 0);
 13+ }
 14+
 15+
 16+ public static function getLevel($line)
 17+ {
 18+ return substr_count($line, '*');
 19+ }
 20+
 21+ public static function getExpandedParameter($line)
 22+ {
 23+ if (self::startsWith($line, '+')) {
 24+ return true;
 25+ } else {
 26+ return false;
 27+ }
 28+ }
 29+
 30+ public static function getTextParameter($line)
 31+ {
 32+ return preg_filter("/\+|\-?\**(.*)/", "$1", $line);
 33+ }
 34+
 35+
 36+ public static function getMenuTree($data){
 37+ if(self::isValidInput($data)){
 38+ $data = self::cleanupData($data);
 39+ $root = new MenuItem();
 40+ $root->setExpanded(true);
 41+ $arrayData = self::parseDataIntoHierarchicalArray($data);
 42+ self::addChildrenToMenuItemFromArrayData($root,$arrayData);
 43+ return $root;
 44+ }
 45+ }
 46+
 47+
 48+ public static function getMenuItem($line)
 49+ {
 50+ $line = trim($line);
 51+ if(self::isValidInput($line)){
 52+ $menuItem = new MenuItem();
 53+ $menuItem->setExpanded(self::getExpandedParameter($line));
 54+ $menuItem->setText(self::getTextParameter($line));
 55+ return $menuItem;
 56+ }else{
 57+ throw new InvalidArgumentException();
 58+ }
 59+ }
 60+
 61+ public static function parseDataIntoHierarchicalArray($data)
 62+ {
 63+ $rootArray = array();
 64+ $prevArray = &$rootArray;
 65+ $prevLevel = 0;
 66+ $levelArray[0] = &$rootArray;
 67+ foreach(preg_split("/\n/",$data) as $line){
 68+ $level = self::getLevel($line);
 69+ if($level == $prevLevel){
 70+ $levelArray[$level][] = $line;
 71+ }else if($level-1 == $prevLevel){
 72+ //child of previous line
 73+ $parent = array_pop($levelArray[$level-1]);
 74+ $levelArray[$level-1][$parent][] = $line;
 75+ $levelArray[$level] = &$levelArray[$level-1][$parent];
 76+ }else if($level < $prevLevel){
 77+ //back some levels
 78+ $levelArray[$level][] = $line;
 79+ }else{
 80+ //syntax error
 81+ throw new InvalidArgumentException();
 82+ }
 83+ $prevLevel = $level;
 84+ }
 85+ return $rootArray;
 86+ }
 87+
 88+ public static function addChildrenToMenuItemFromArrayData(&$rootMenuItem,$arrayData)
 89+ {
 90+ foreach ($arrayData as $key => $val) {
 91+ if (is_string($key)) {
 92+ $menuItem = self::getMenuItem($key);
 93+ $rootMenuItem->addChild($menuItem);
 94+ self::addChildrenToMenuItemFromArrayData($menuItem,$val);
 95+ } else {
 96+ $menuItem = self::getMenuItem($val);
 97+ $rootMenuItem->addChild($menuItem);
 98+ }
 99+ }
 100+ }
 101+
 102+ private static function startsWith($haystack, $needle)
 103+ {
 104+ $length = strlen($needle);
 105+ return (substr($haystack, 0, $length) === $needle);
 106+ }
 107+
 108+ private static function cleanupData($data){
 109+ for($x = 0; $x < 2; $x++){
 110+ $data = self::removeLineBreaksFromStartOfString($data);
 111+ $data = strrev($data);
 112+ }
 113+ return $data;
 114+ }
 115+
 116+ private static function removeLineBreaksFromStartOfString($data)
 117+ {
 118+ while (self::startsWith($data, "\n")) {
 119+ $data = substr($data, 1);
 120+ }
 121+ return $data;
 122+ }
 123+
 124+}
\ No newline at end of file
Index: trunk/extensions/SideBarMenu/includes/MenuItem.php
@@ -0,0 +1,99 @@
 2+<?php
 3+
 4+class MenuItem
 5+{
 6+ private $expanded;
 7+ private $children = array();
 8+ private $parent = null;
 9+ private $text;
 10+
 11+ public function setExpanded($expanded)
 12+ {
 13+ $this->expanded = $expanded;
 14+ }
 15+
 16+ public function isExpanded()
 17+ {
 18+ return $this->expanded;
 19+ }
 20+
 21+ public function setText($link)
 22+ {
 23+ $this->text = $link;
 24+ }
 25+
 26+ public function getText()
 27+ {
 28+ return $this->text;
 29+ }
 30+
 31+ public function addChild(MenuItem $child)
 32+ {
 33+ if(!in_array($child,$this->children)){
 34+ $this->children[] = $child;
 35+ $child->setParent($this);
 36+ }
 37+ }
 38+
 39+ public function getChildren()
 40+ {
 41+ return $this->children;
 42+ }
 43+
 44+ public function hasChildren()
 45+ {
 46+ return sizeof($this->children) > 0;
 47+ }
 48+
 49+ public function setParent(MenuItem $parent)
 50+ {
 51+ if($this->parent !== $parent){
 52+ $this->parent = $parent;
 53+ $parent->addChild($this);
 54+ }
 55+ }
 56+
 57+ public function getParent()
 58+ {
 59+ return $this->parent;
 60+ }
 61+
 62+ public function isRoot(){
 63+ return is_null($this->parent);
 64+ }
 65+
 66+ public function getLevel(){
 67+ if($this->isRoot()){
 68+ return 0;
 69+ }else{
 70+ return 1+$this->getParent()->getLevel();
 71+ }
 72+ }
 73+
 74+ public function toHTML()
 75+ {
 76+ $output = "";
 77+ if($this->isRoot()){
 78+ $output .= $this->childrenToHTML();
 79+ }else{
 80+ $output .= "<li class=\"sidebar-menu-item sidebar-menu-item-".$this->getLevel().' '.($this->isExpanded() ? 'sidebar-menu-item-expanded' : 'sidebar-menu-item-collapsed')."\"><div class=\"sidebar-menu-item-text sidebar-menu-item-text-".$this->getLevel()."\">".$this->getText()."</div>";
 81+ $output .= $this->childrenToHTML();
 82+ $output .= "</li>";
 83+ }
 84+
 85+ return $output;
 86+ }
 87+
 88+ private function childrenToHTML()
 89+ {
 90+ if($this->hasChildren()){
 91+ $output = "<ul class=\"sidebar-menu sidebar-menu-".$this->getLevel()."\">";
 92+ foreach ($this->getChildren() as $child) {
 93+ $output .= $child->toHTML();
 94+ }
 95+ $output .= "</ul>";
 96+ return $output;
 97+ }
 98+ }
 99+
 100+}
Index: trunk/extensions/SideBarMenu/README
@@ -0,0 +1,4 @@
 2+== INSTALL ==
 3+1. Copy SideBarMenu to /path/to/mediawiki/extension/
 4+2. append "require_once( "$IP/extensions/SideBarMenu/SideBarMenu.php" );" to LocalSettings.php
 5+

Comments

#Comment by 😂 (talk | contribs)   17:34, 7 March 2012

Rather than DIY on the newline trimming in removeLineBreaksFromStartOfString(), how about using ltrim()?

#Comment by Netbrain (talk | contribs)   17:37, 7 March 2012

Yes, that is probably better. fixing now.

Status & tagging log