Extension:Wikiskin.php
From Organic Design wiki
<?php
# Extension:WikiSkin
# - Uses a wikitext article for the skin instead of a PHP file. Special items like search box and login link use magic words
# - See http://www.mediawiki.org/wiki/Extension:WikiSkin for installation and usage details
# - Licenced under LGPL (http://www.gnu.org/copyleft/lesser.html)
# - Author: http://www.organicdesign.co.nz/nad
if (!defined('MEDIAWIKI')) die('Not an entry point.');
define('WIKISKIN_VERSION','0.1.12, 2007-10-16');
if (!isset($wgWikiSkinArticle)) $wgWikiSkinArticle = 'WikiSkin';
$wgWikiSkinArticle = isset($_REQUEST['skin']) ? $_REQUEST['skin'] : $wgWikiSkinArticle;
$wgWikiSkinMagic = array(
'CURRENTUSER',
'TITLE',
'SUBTITLE',
'SITELOGO',
'TEXT',
'SEARCH',
'PERSONAL',
'LOGIN',
'ACTIONS',
'SITENOTICE',
'INFO',
'CATLINKS',
'FOOTER'
);
$wgExtensionFunctions[] = 'wfSetupWikiSkin';
$wgHooks['MagicWordMagicWords'][] = 'wfWikiSkinMagicWord';
$wgHooks['MagicWordwgVariableIDs'][] = 'wfWikiSkinVariableID';
$wgHooks['LanguageGetMagic'][] = 'wfWikiSkinLangMagic';
$wgHooks['ParserGetVariableValueSwitch'][] = 'wfWikiSkinGetVariable';
$wgExtensionCredits['other'][] = array(
'name' => 'WikiSkin',
'author' => '[http://www.organicdesign.co.nz/nad User:Nad]',
'description' => 'Allows normal wikitext articles to define skin content and layout',
'url' => 'http://www.mediawiki.org/wiki/Extension:WikiSkin',
'version' => WIKISKIN_VERSION
);
function wfWikiSkinMagicWord(&$magicWords) {
global $wgWikiSkinMagic;
foreach($wgWikiSkinMagic as $var) $magicWords[] = "MAG_$var";
return true;
}
function wfWikiSkinVariableID(&$variables) {
global $wgWikiSkinMagic;
foreach($wgWikiSkinMagic as $var) $variables[] = constant("MAG_$var");
return true;
}
function wfWikiSkinLangMagic(&$langMagic, $langCode = 0) {
global $wgWikiSkinMagic;
foreach($wgWikiSkinMagic as $var) {
$magic = "MAG_$var";
$langMagic[defined($magic) ? constant($magic) : $magic] = array(0,$var);
}
return true;
}
function wfWikiSkinGetVariable(&$parser,&$cache,&$index,&$ret) {
switch ($index) {
case MAG_CURRENTUSER:
$parser->disableCache();
$ret = $GLOBALS['wgUser']->mName;
break;
# These ones are all replaced by a token to be filled by skin when rendering page
case MAG_TITLE:
case MAG_SUBTITLE:
case MAG_SITELOGO:
case MAG_TEXT:
case MAG_SEARCH:
case MAG_PERSONAL:
case MAG_LOGIN:
case MAG_ACTIONS:
case MAG_SITENOTICE:
case MAG_INFO:
case MAG_CATLINKS:
case MAG_FOOTER:
$magic = constant($index);
$ret = "((((WikiSkin:$magic))))";
break;
}
return true;
}
# Define new skin class, create an instance and make it current
function wfSetupWikiSkin() {
# Create skin class based on monobook which parses the skin article and embeds the content
class SkinWikiSkin extends SkinTemplate {
function initPage(&$out) {
global $wgWikiSkinArticle;
SkinTemplate::initPage($out);
$this->skinname = $wgWikiSkinArticle;
$this->stylename = $wgWikiSkinArticle;
$this->template = 'WikiSkinTemplate';
}
}
class WikiSkinTemplate extends QuickTemplate {
# Expand templates in CSS before expanding
function expandcss($data) {
$css = $this->data[$data];
$css = str_replace('action=raw','action=raw&templates=expand',$css);
$css = str_replace('&usemsgcache=yes','',$css);
print $css;
}
function execute() {
# Build the HTML, HEAD and BODY elements and send to output
wfSuppressWarnings();
?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="<?php $this->text('lang') ?>" lang="<?php $this->text('lang') ?>" dir="<?php $this->text('dir') ?>">
<head>
<meta http-equiv="Content-Type" content="<?php $this->text('mimetype') ?>; charset=<?php $this->text('charset') ?>" />
<?php $this->html('headlinks') ?>
<title><?php $this->text('pagetitle') ?></title>
<meta http-equiv="imagetoolbar" content="no" />
<?php print Skin::makeGlobalVariablesScript( $this->data ); ?>
<script type="<?php $this->text('jsmimetype') ?>" src="<?php $this->text('stylepath' ) ?>/common/wikibits.js"><!-- wikibits js --></script>
<?php if($this->data['jsvarurl' ]) { ?>
<script type="<?php $this->text('jsmimetype') ?>" src="<?php $this->text('jsvarurl' ) ?>"><!-- site js --></script>
<?php } ?>
<?php if($this->data['pagecss' ]) { ?>
<style type="text/css"><?php $this->expandcss('pagecss') ?></style>
<?php }
if($this->data['usercss' ]) { ?>
<style type="text/css"><?php $this->expandcss('usercss') ?></style>
<?php }
if($this->data['userjs' ]) { ?>
<script type="<?php $this->text('jsmimetype') ?>" src="<?php $this->text('userjs' ) ?>"></script>
<?php }
if($this->data['userjsprev']) { ?>
<script type="<?php $this->text('jsmimetype') ?>"><?php $this->html('userjsprev') ?></script>
<?php }
if($this->data['trackbackhtml']) print $this->data['trackbackhtml']; ?>
<!-- Head Scripts -->
<?php $this->html('headscripts') ?>
</head>
<body <?php if($this->data['body_ondblclick']) { ?>ondblclick="<?php $this->text('body_ondblclick') ?>"<?php } ?>
<?php if($this->data['body_onload' ]) { ?>onload="<?php $this->text('body_onload') ?>"<?php } ?>
class="mediawiki <?php $this->text('nsclass') ?> <?php $this->text('dir') ?> <?php $this->text('pageclass') ?>">
<a name="top" id="top"></a>
<?php
# Build list of special fields and their content
$replace = array();
$replace['TITLE'] = $this->data['displaytitle'] ? htmlspecialchars($this->data['title']) : $this->data['title'];
$replace['SEARCH'] = '<div id="p-search" class="portlet">'
. '<h5><label for="searchInput">'.htmlspecialchars($this->translator->translate('search')).'</label></h5>'
. '<div id="searchBody" class="pBody">'
. '<form action="'.htmlspecialchars($this->data['searchaction']).'" id="searchform"><div>'
. '<input id="searchInput" name="search" type="text" '
. ($this->haveMsg('accesskey-search') ? 'accesskey="'.htmlspecialchars($this->translator->translate('accesskey-search')).'"' : '')
. (isset($this->data['search']) ? ' value="'.htmlspecialchars($this->data['search']).'"' : '')
. ' /><input type="submit" name="go" class="searchButton" id="searchGoButton" '
. 'value="'.htmlspecialchars($this->translator->translate('go')).'" /> '
. '<input type="submit" name="fulltext" class="searchButton" '
. 'value="'.htmlspecialchars($this->translator->translate('search')).'" /></div></form>'
. '</div></div>';
$replace['SITELOGO'] = '<div class="portlet" id="p-logo">'
. '<a style="background-image: url('.htmlspecialchars($this->data['logopath']).');" '
. 'href="'.htmlspecialchars($this->data['nav_urls']['mainpage']['href']).'" '
. 'title="'.htmlspecialchars($this->translator->translate('mainpage')).'"></a></div>'
. '<script type="'.htmlspecialchars($this->data['jsmimetype']).'"> if (window.isMSIE55) fixalpha(); </script>';
$replace['SITENOTICE'] = $this->data['sitenotice'] ? '<div id="siteNotice">'.$this->data['sitenotice'].'</div>' : '';
$replace['SUBTITLE'] = '<h3 id="siteSub">'.htmlspecialchars($this->translator->translate('tagline')).'</h3>'
. '<div id="contentSub">'.$this->data['subtitle'].'</div>';
$replace['INFO'] = ($this->data['undelete'] ? '<div id="contentSub2">'.$this->data['undelete'].'</div>' : '')
. ($this->data['newtalk'] ? '<div class="usermessage">'.$this->data['newtalk'].'</div>' : '')
. ($this->data['showjumplinks'] ? '<div id="jump-to-nav">'
. htmlspecialchars($this->translator->translate('jumpto'))
. '<a href="#column-one">'.htmlspecialchars($this->translator->translate('jumptonavigation')).'</a>'
. ', <a href="#searchInput">'.htmlspecialchars($this->translator->translate('jumptosearch')).'</a></div>' : '');
$replace['TEXT'] = $this->data['bodytext'];
$replace['CATLINKS'] = $this->data['catlinks'] ? '<div id="catlinks">'.$this->data['catlinks'].'</div>' : '';
$replace['ACTIONS'] = '<ul>';
foreach ($this->data['content_actions'] as $key => $tab)
$replace['ACTIONS'] .= '<li id="ca-'.htmlspecialchars($key).'"'
. ($tab['class'] ? ' class="'.htmlspecialchars($tab['class']).'"' : '')
. '><a href="'.htmlspecialchars($tab['href']).'">'.htmlspecialchars($tab['text']).'</a></li>';
$replace['ACTIONS'] .= '</ul>';
$replace['PERSONAL'] = '<ul>';
foreach ($this->data['personal_urls'] as $key => $item) {
$replace['PERSONAL'] .= '<li id="pt-'.htmlspecialchars($key).'"'
. ($item['active'] ? ' class="active"' : '')
. '><a href="'.htmlspecialchars($item['href']).'"'
. (!empty($item['class']) ? ' class="'.htmlspecialchars($item['class']).'"' : '')
. '>'.htmlspecialchars($item['text']).'</a></li>';
if ($key == 'pt-login' || $key == 'pt-anonlogin')
$replace['LOGIN'] = '<a href="'.htmlspecialchars($item['href']).'">'.htmlspecialchars($item['text']).'</a>';
}
$replace['PERSONAL'] .= '</ul>';
# Read and parse the skin article
global $wgUser,$wgTitle,$wgParser,$wgWikiSkinArticle;
$skin = new Article(Title::newFromText("MediaWiki:$wgWikiSkinArticle"));
$opt = ParserOptions::newFromUser($wgUser);
$out = $wgParser->parse(preg_replace('/^\\s+/m','',$skin->fetchContent(0,false,false)),$wgTitle,$opt,true,true);
$content = $out->getText();
# Replace all the fields and send to output
echo preg_replace('/\\({4}WikiSkin:MAG_(.+?)\\){4}/ie','$replace["$1"]',$content);
?>
<script type="text/javascript"> if (window.runOnloadHook) runOnloadHook();</script>
<?php $this->html('reporttime') ?>
</body></html>
<?php
wfRestoreWarnings();
}
} # end of class definition
# Make the new skin current (now and after login/logout)
wfApplyWikiSkin();
global $wgHooks;
$wgHooks['UserLoginComplete'][] = 'wfApplyWikiSkin';
$wgHooks['UserLogoutComplete'][] = 'wfApplyWikiSkin';
} # end of setup function
function wfApplyWikiSkin() {
global $wgUser,$wgWikiSkinArticle;
$wgUser->setOption('skin',$wgWikiSkinArticle);
$wgUser->mSkin =& new SkinWikiSkin;
return true;
}
?>