Extension:Header Footer

Limitation
This extension does not (currently) integrate well in installations with parser caching functionality enabled.

HeaderFooter.php
<?php /* * HeaderFooter.php * * MediaWiki extension * @author: Jean-Lou Dupont (http://www.bluecortex.com) * * Purpose: insert an header and/or footer to an article *         upon a 'view' action. * * Features: * ********* * - Recursive (bottom-up) search for "Header" and "Footer" subpages * - section support * - Configurable per-namespace recursive level depth * - Configurable per-namespace enable/disable flag (all disable per default) * * DEPENDANCIES: * - ArticleCacheClass (for recursive search function) * * * Tested Compatibility: MW 1.8.2, 1.9.3 * * HISTORY: * -- Version 1.1:	added support for and * -- Version 1.11: changed interface to ArticleCacheClass: using singleton *          */ $wgExtensionCredits['other'][] = array( 	'name'    => 'HeaderFooter Extension', 	'version' => '1.11',	'author'  => 'Jean-Lou Dupont', 	'url'     => 'http://www.bluecortex.com', ); require_once("HeaderFooterClass.php"); $hfObj = &HeaderFooterClass::singleton; $wgHooks['ArticleAfterFetchContent'][] = array( $hfObj, 'hAddHeaderFooter' ); ?>

HeaderFooterClass.php
<?php /* * HeaderFooterClass.php * * MediaWiki extension * @author: Jean-Lou Dupont (http://www.bluecortex.com) * */ class HeaderFooterClass {	var $cache; var $level; var $inproc; var $nsPar = array; public static function &singleton {		static $instance; if ( !isset( $instance ) ) $instance = new HeaderFooterClass; return $instance; }	// deprecated interface: use "singleton" functionality. static function getGlobalObjectName { return "hfObj";          } static function &getGlobalObject   { return $GLOBALS['hfObj']; } public function HeaderFooterClass {		$this->cache = &ArticleCacheClass::singleton; $this->level = 0 ; }	/*	 *  Parameters: *  ==========	 *   Enable => true/false *  Level  => 0, 1, 2 etc.	 *             IF 0 THEN recurse to top of namespace (top:  NS:header, NS:footer) *            IF 1 THEN just check the current level e.g. NS:base/header, NS:base/footer */	public function setNsParams( $ns, $p ) { $this->nsPar[$ns] = $p; } public function hAddHeaderFooter( &$article, &$content ) {		global $action; // only show up the header/footer on page views if ($action != 'view') return true; // check the per-namespace enable/disable attribute. $ns = $article->mTitle->getNamespace; if (!$this->nsPar[$ns]['enable']) return true; // Re-entrancy check // If this function is called recursively, // that probably means a processor code page // is being fetched. Get out. if ($this->inproc) return true; $this->inproc= true; $name = $article->mTitle->getPrefixedDBkey; // Check if the title name ends with either "header" or "footer" // and skip if true. $e = explode("/", $name); $t = $e[count($e)-1]; $u=strtolower($t); // take care of namespace prefix if present. $v=explode(":", $u); if (count($v)>1) $u= $v[1]; $hdisable=false; $fdisable=false; // check for disabling directives. if (strpos($content, " ")!==false) $hdisable=true; if (strpos($content, " ")!==false) $fdisable=true; $content = preg_replace('//si','', $content); $content = preg_replace('//si','', $content); if ($u<>"header" and $u<>"footer") {				if (!$hdisable) $h = $this->cache->recurseGetArticleContent($name, "Header", $this->nsPar[$ns]['level'] ); if (!$fdisable) $f = $this->cache->recurseGetArticleContent($name, "Footer", $this->nsPar[$ns]['level'] ); if (!empty($h)) $h = preg_replace( '/ .*<\/noinclude>/si', '', $h ); if (!empty($f)) $f = preg_replace( '/ .*<\/noinclude>/si', '', $f ); $content = $h.$content.$f; }				// RESET re-entrancy flag. $this->inproc= false; return true; } } // END CLASS DEFINITION ?>