Index: includes/parser/CoreParserFunctions.php
===================================================================
--- includes/parser/CoreParserFunctions.php	(revision 68718)
+++ includes/parser/CoreParserFunctions.php	(working copy)
@@ -69,6 +69,7 @@
 		$parser->setFunctionHook( 'subjectpagenamee', array( __CLASS__, 'subjectpagenamee' ), SFH_NO_HASH );
 		$parser->setFunctionHook( 'tag',              array( __CLASS__, 'tagObj'           ), SFH_OBJECT_ARGS );
 		$parser->setFunctionHook( 'formatdate',       array( __CLASS__, 'formatDate'       ) );
+		$parser->setFunctionHook( 'pageicon',         array( __CLASS__, 'pageicon'        ) );
 
 		if ( $wgAllowDisplayTitle ) {
 			$parser->setFunctionHook( 'displaytitle', array( __CLASS__, 'displaytitle' ), SFH_NO_HASH );
@@ -624,6 +625,11 @@
 		}
 	}
 
+	public static function pageicon( $parser, $id, $text = '' ) {
+		$parser->mOutput->addPageIcon( $id, $parser->recursiveTagParse( $text ) );
+		return '';
+	}
+
 	/**
 	 * Parser function to extension tag adaptor
 	 */
Index: includes/parser/ParserOutput.php
===================================================================
--- includes/parser/ParserOutput.php	(revision 68718)
+++ includes/parser/ParserOutput.php	(working copy)
@@ -28,7 +28,8 @@
 		$mSections = array(),         # Table of contents
 		$mProperties = array(),       # Name/value pairs to be cached in the DB
 		$mTOCHTML = '';	              # HTML of the TOC
-	private $mIndexPolicy = '';	      # 'index' or 'noindex'?  Any other value will result in no change.
+	private $mIndexPolicy = '',	      # 'index' or 'noindex'?  Any other value will result in no change.
+		$mPageIcons = array();        # Array of icons to show for the page (like Protect, Featured, etc)
 
 	function ParserOutput( $text = '', $languageLinks = array(), $categoryLinks = array(),
 		$containsOldMagic = false, $titletext = '' )
@@ -59,6 +60,7 @@
 	function getWarnings()               { return array_keys( $this->mWarnings ); }
 	function getIndexPolicy()            { return $this->mIndexPolicy; }
 	function getTOCHTML()                { return $this->mTOCHTML; }
+	function getPageIcons()              { return $this->mPageIcons; }
 
 	function containsOldMagic()          { return $this->mContainsOldMagic; }
 	function setText( $text )            { return wfSetVar( $this->mText, $text ); }
@@ -251,6 +253,15 @@
 	}
 
 	/**
+	 * Add page icons to the parser output.
+	 * @param File $file A valid file
+	 * @param String $alt Alt text, if any
+	 */
+	function addPageIcon( $key, $text ) {
+		$this->mPageIcons[$key] = $text;
+	}
+
+	/**
 	 * Override the title to be used for display
 	 * -- this is assumed to have been validated
 	 * (check equal normalisation, etc.)
Index: includes/OutputPage.php
===================================================================
--- includes/OutputPage.php	(revision 68718)
+++ includes/OutputPage.php	(working copy)
@@ -39,6 +39,7 @@
 	var $mParseWarnings = array();
 	var $mSquidMaxage = 0;
 	var $mRevisionId = null;
+	var $mPageIcons = array();
 	protected $mTitle = null;
 
 	/**
@@ -1079,6 +1080,7 @@
 		$this->addCategoryLinks( $parserOutput->getCategories() );
 		$this->mNewSectionLink = $parserOutput->getNewSection();
 		$this->mHideNewSectionLink = $parserOutput->getHideNewSection();
+		$this->mPageIcons = $parserOutput->getPageIcons();
 
 		$this->mParseWarnings = $parserOutput->getWarnings();
 		if ( !$parserOutput->isCacheable() ) {
Index: includes/SkinTemplate.php
===================================================================
--- includes/SkinTemplate.php	(revision 68718)
+++ includes/SkinTemplate.php	(working copy)
@@ -230,6 +230,13 @@
 		$tpl->set( 'pageclass', $this->getPageClasses( $this->mTitle ) );
 		$tpl->set( 'skinnameclass', ( 'skin-' . Sanitizer::escapeClass( $this->getSkinName() ) ) );
 
+		$icons = '<ul class="mw-pageicons">';
+		foreach( $out->mPageIcons as $id => $iconText ) {
+			$icons .= Html::rawElement( 'li', array( 'id' => $id ), $iconText ) . "\n";
+		}
+		$icons .= '</ul>';
+		$tpl->set( 'pageicons', $icons );
+
 		$nsname = MWNamespace::exists( $this->mTitle->getNamespace() ) ?
 					MWNamespace::getCanonicalName( $this->mTitle->getNamespace() ) :
 					$this->mTitle->getNsText();
Index: languages/messages/MessagesEn.php
===================================================================
--- languages/messages/MessagesEn.php	(revision 68718)
+++ languages/messages/MessagesEn.php	(working copy)
@@ -356,6 +356,7 @@
 	'url_path'               => array( 0,    'PATH' ),
 	'url_wiki'               => array( 0,    'WIKI' ),
 	'url_query'              => array( 0,    'QUERY' ),
+	'pageicon'               => array( 1,    'pageicon' ),
 );
 
 /**
