Extension:SectionHide

The SectionHide extension adds a [hide] link wherever there is a section heading [edit] link. This link will hide all content between that section header and the next section header of the same level, changing itself to read [show] in the process. Clicking [show] will restore the section to view.

Installation
Create the Extensions\SectionHide folder and add the following files

SectionHide.php
<?php /** * SectionHide extension - implements a hide/show link on sections on any ordinary page. * * @package MediaWiki * @subpackage Extensions * @author Simon Oliver * @copyright Â© 2013 Simon Oliver * @licence GNU General Public Licence 2.0 or later * * add the following line to localsettinge.php to use * require_once("$IP/extensions/SectionHide/SectionHide.php"); */ if( !defined( 'MEDIAWIKI' ) ) { echo( "This file is an extension to the MediaWiki software and cannot be used standalone.\n" ); die( 1 ); } $wgExtensionCredits['other'][] = array( 	'name' => 'SectionHide',  	'author' => 'Simon Oliver',  	'url' => 'http://www.mediawiki.org/wiki/Extension:SectionHide', 	'description' => 'Hide/show link on section headings', ); $wgHooks['ParserAfterParse'][] = 'SectionHideHooks::onParserAfterParse'; $wgHooks['ParserSectionCreate'][] = 'SectionHideHooks::onParserSectionCreate'; $wgAutoloadClasses[ 'SectionHideHooks' ] = __DIR__. '/SectionHideHooks.php'; $wgExtensionMessagesFiles[ 'UserSnoop' ] = __DIR__. '/SectionHide.i18n.php'; $wgExtensionMessagesFiles[ 'UserSnoopAlias' ] = __DIR__. '/SectionHide.alias.php';

SectionHideHooks.php
 0) { 			$hidelink = '&lt;span class="editsection visibilitytoggle">[&lt;a href="#" onclick="toggleSectionVisibility(this, '.$section.",'".wfMsg( 'sectionhide-show' )."','".wfMsg( 'sectionhide-hide' )."'".')">'.wfMsg( 'sectionhide-hide' ).'&lt;/a>]&lt;/span>'; $divstart = '&lt;div class="sectionblocks" id="sectionblock'.$section.'">'; $divend = '&lt;/div id="sectionblock'.$section.'">'; $sectionContent = preg_replace(	'/&lt;h[2-6]>/', "\n$0$hidelink", $sectionContent); $sectionContent = preg_replace(	'/&lt;\/h[2-6]>/',	"$0\n$divstart\n", $sectionContent); $sectionContent = $sectionContent."\n$divend\n"; } 		return true; } 	public static function onParserAfterParse( &$parser, &$text, &$sstate ) { 		// need to nest sections by levels by moving around the closing tags $numberofmatches = preg_match_all('#&lt;h[2-6].*&lt;\/h[2-6]>\n&lt;div class="sectionblocks"#', $text, $matches, PREG_OFFSET_CAPTURE); $closingdivmatches = preg_match_all('#&lt;\/div id=#', $text, $divmatches, PREG_OFFSET_CAPTURE); if($numberofmatches == $closingdivmatches && $numberofmatches > 1) { 			$headlevel = array; $i = 0; foreach($matches[0] as $match) { 				$headlevel[$i] = substr($match[0],2,1); // heading level always third character $i++; } 			$headlevel[$i] = 1; // make sure it terminates correctly for($i = 0 ; $i &lt; $numberofmatches - 1 ; $i++) { 				// the rule is: // for each heading if the next level is lower, move the closing div to after the closing div of that level and re-test // length of closing divs is &lt;/div id="sectionblock2"> = 24 + number of digits of id (which is $i+1) $divlength = 25 + ($i>98 ? 2 : ($i>8 ? 1 : 0)); //NB this should cope with up to 999 heading sections. Articles with more than that deserve to be broken $j = 1; while(($i+$j) &lt; $numberofmatches && $headlevel[$i+$j] > $headlevel[$i]) { 					// insert a closing div before the next heading, or at the end if no more headings $text = insertAtLoc($text 						, '&lt;/div id="sectionblock'.($i+1).'">' 							, $divmatches[0][$i+$j][1] + $divlength + (($i+$j>98 && $i &lt;= 8) ? 2 : ((($i+$j>98 && $i &lt;= 98) || ($i+$j > 8 && $i &lt;= 8)) ? 1 : 0))); // deal with situations where sublevel div is longer than parent level $text = removeAtLoc($text, $divlength, $divmatches[0][$i][1]);	// remove the closing div from its previous location // update the current positions $divmatches[0][$i][1] = $divmatches[0][$i+$j][1]; // is now where the sublevel div was $divmatches[0][$i+$j][1] = $divmatches[0][$i+$j][1]-$divlength; // moves by divlength towards the start $matches[0][$i+$j][1] = $matches[0][$i+$j][1]-$divlength; // moves by sublevel heading towards the start $j++; } 				} 			} 		return true; }	 	} # end of SectionHideHooks class function insertAtLoc($subject, $toinsert, $atloc) { 	return substr($subject,0,$atloc).$toinsert.substr($subject,$atloc); } function removeAtLoc($subject, $remlength, $atloc) { 	return substr($subject,0,$atloc).substr($subject,$atloc+$remlength); }
 * 1) hooks class

SectionHide.i18n.php
Only the English to get started, add languages as you need them please.

 'Section Hide', 	'sectionhide-desc' => 'Hook extension to provide a hide/show link on each section', 	'sectionhide-hide' => 'hide', 	'sectionhide-show' => 'show', ); ?>

SectionHide.alias.php
 array( 'SectionHide' ), ); ?>

Mediawiki:Common.js
Add this here, or in individual skins

function toggleSectionVisibility(fieldObj, id, txt1, txt2) {  var e = document.getElementById('sectionblock'+id); if(fieldObj.innerHTML == txt1) {    fieldObj.innerHTML = txt2; e.style.display = 'block'; }  else {    fieldObj.innerHTML = txt1; e.style.display = 'none'; }  }

Configuration parameters
None

User rights
None

Author Notes
Several of these have been done in the past, but they are not maintained and didn't do quite what I needed.