Mediawiki擴展編寫實戰
Wikipedia大家都很熟悉,而Mediawiki則是Wikipedia背后的功臣,整個Wikipedia都構建在mediawiki之上,mediawiki的穩定性和高效性值得信賴,同時Mediawiki非常易于擴展,可以通過Extension的方式添加非常多的功能,而且Mediawiki的Extension社區也非常活躍,大家可以到Mediawiki Extension目錄下去下載自己需要的擴展程序。
上周末,幫朋友寫了一些Mediawiki的擴展,立即被Mediawiki的強大擴展性折服,主要實現的功能有:增加Google Analytics統計、自定義標題、增加Google Adsense廣告之類,寫Mediawiki的擴展,最好的參考是Mediawiki擴展手冊:http://www.mediawiki.org/wiki/Manual:Extensions。
Mediawiki的擴展主要有Tag Extension、Parser Functions、Hooks、Special Pages、Skins、Magic Words,對應的中文是:標簽擴展(自定義wiki標簽,比如xxxx)、解析擴展(和標簽類似,不過呈現方式稍有不通,為{{#foo : bar}})、鉤子、特殊頁面、皮膚、魔術關鍵字,我這里演示的是Parser Functions和Hooks,其他的差不多類似。
一、增加Google Analytics統計和Google Adsense廣告
原理很簡單,我們在頁面顯示之前,把Google Analytics和Google Adsense的代碼append到要顯示的內容即可,代碼:
/**
* 安全設置,防止惡意調用
*/
if (!defined('MEDIAWIKI')) {
die( 'This file is a MediaWiki extension, it is not a valid entry point' );
}
/**
* 擴展的基本信息
*/
$wgExtensionCredits['other'][] = array(
'path' => __FILE__,
'name' => '插件名稱',
'version' => '1.0',
'author' => '作者',
'descriptionmsg' => '簡要說明',
'url' => '作者地址',
);
/**
* 注冊一個鉤子,在頁面顯示之前,處理頁面顯示內容
*
* 全部鉤子列表:http://www.mediawiki.org/wiki/Manual:Hooks
*
*/
$wgHooks['BeforePageDisplay'][] = 'dzBeforePageDisplay';
function dzBeforePageDisplay(&$out, &$skin) {
/**
* 在LocalSettings.php定義$wgDangZhiAppendHtml
* 把要添加的Google Analytics和Google Adsense代碼放里面
*/
global $wgDangZhiAppendHtml;
// 頁面添加HTML
$out->addHTML($wgDangZhiAppendHtml);
// 記得返回true,收工
return true;
}
短短幾行代碼,完成添加Google Analytics統計和Google Adsense廣告代碼,當然,你還可以添加任意你想添加到網頁最后的代碼,可以查看示例網站的源代碼,Google Analytics的代碼布在每個頁面上。
二、自定義文章標題
自定義文章標題對搜索引擎來說非常重要,Mediawiki默認的標題只能和內容條目一樣,缺乏靈活性,這里的原理是增加一個{{#title: 標題內容}}的標簽,在頁面顯示之前替換成網頁標題,示例網站的首頁就自定了HTML標題。
* 還是第一示例中的顯示前處理函數,這里是部分內容
*/
function dzBeforePageDisplay(&$out, &$skin) {
// 如果頁面中存在{{#title: 標題內容}},那么指定文章標題
preg_match('/\{\{#title: ?(.*)\}\}/U', $out->mBodytext, $matches);
if ($matches) {
$out->mBodytext = str_replace($matches[0], '', $out->mBodytext);
$out->mHTMLtitle = $matches[1];
}
return true;
}
三、文章在新窗口打開
Mediawiki是外國人做的東西,國外少有默認新窗口打開鏈接的習慣,國人的習慣可不是這樣,讓Mediawiki默認新窗口打開的做法非常的簡單。
* 還記得這個函數吧
*/
function dzBeforePageDisplay(&$out, &$skin) {
// 新窗口打開鏈接
$p = array('/(<a href=\"\/index.php\?title=.+\")/U', '/(<a href=\"\/wiki\/.+\")/U');
$r = '$1 target="_blank"';
$out->mBodytext = preg_replace($p, $r, $out->mBodytext);
return true;
}
在頁面輸出之前,給需要的a標簽加個target=”_blank”的屬性即可。
四、解析HTML標簽
Mediawiki為了安全考慮,不允許在內容中使用非安全HTML標簽,我們可以使用一種加密HTML的方法來達到安全性和易用性的平衡。在內容中增加{{#html: 加密碼 | html內容}},其中加密碼是系統密鑰和html內容的md5值,如果符合則顯示。
* 初始化Parser Functions
*/
$wgHooks['ParserFirstCallInit'][] = 'dzParserSetup';
$wgHooks['LanguageGetMagic'][] = 'dzMagicSetup';
/**
* 設置解析函數
*/
function dzParserSetup(&$parser) {
$parser->setFunctionHook('html', 'dzParseHtml');
// 可以設置多個,$parser->setFunctionHook('foo', 'dzParseFoo');
return true;
}
/**
* 初始化Parser關鍵字
*/
function dzMagicSetup(&$magicWords, $langCode) {
$magicWords['html'] = array(0, 'html');
// 可以設置多個,$magicWords['foo'] = array(0, 'foo');
return true;
}
/**
* 解析HTML
*/
function dzParseHtml($parser, $param1 = '', $param2 = '') {
// 在LocalSettings.php定義HTML加密密鑰
global $wgHtmlSalt;
$key = md5($wgHtmlSalt . $param2);
if ($key == $param1) {
return array($param2, 'noparse' => true, 'isHTML' => true);;
}
return 'bad html';
}
Mediawiki的擴展寫起來還是相當容易,文中提到的效果可以在這里體驗,老外寫的東西對Extension都很重視,wordpress也是這樣,不似國內的某些項目,稍做修改都得hack代碼,hack的壞處是升級的時候容易悲劇。