Mediawiki 程式說明:修訂版本之間的差異
| 第 1 行: | 第 1 行: | ||
[[分類:Mediawiki]] | [[分類:Mediawiki]] | ||
| + | |||
| + | ==檔案架構== | ||
| + | <table border=1 cellspacing=0 color=black> | ||
| + | <tr><th>名稱</th><th>說明</th></tr> | ||
| + | <tr> | ||
| + | <td> math</td> | ||
| + | <td> 存放解析數學公式的程式碼,一般而言不會接觸到,但若是數學公式功能無法成功安裝,可藉由目錄下的資訊來除錯。</td> | ||
| + | </tr> | ||
| + | <tr> | ||
| + | <td> bin</td> | ||
| + | <td> 存放在開發MediaWiki時會用到的批次檔,一般管理者或開發者不會接觸到。</td> | ||
| + | </tr> | ||
| + | <tr> | ||
| + | <td> config</td> | ||
| + | <td> 存放預設的MediaWiki設定檔(LocalSettings.php),只會於安裝時接觸到。</td> | ||
| + | </tr> | ||
| + | <tr> | ||
| + | <td> docs</td> | ||
| + | <td> 存放說明文件,對於要擴充功能的開發者很具有參考價值。</td> | ||
| + | </tr> | ||
| + | <tr> | ||
| + | <td> extensions</td> | ||
| + | <td> 存放擴充套件之目錄,對於想要擴充功能的開發者是必須要瞭解的目錄。</td> | ||
| + | </tr> | ||
| + | <tr> | ||
| + | <td> images</td> | ||
| + | <td> 存放檔案以及圖片的目錄。</td> | ||
| + | </tr> | ||
| + | <tr> | ||
| + | <td> includes</td> | ||
| + | <td> 存放主要的程式碼,要深入瞭解MediaWiki程式架構此程式碼必深入研究。</td> | ||
| + | </tr> | ||
| + | <tr> | ||
| + | <td> languages</td> | ||
| + | <td> 存放各種語系的翻譯檔案。</td> | ||
| + | </tr> | ||
| + | <tr> | ||
| + | <td> maintenance</td> | ||
| + | <td> 存放維護程式碼,例如資料庫SQL指令、升級程式碼。</td> | ||
| + | </tr> | ||
| + | <tr> | ||
| + | <td> skins</td> | ||
| + | <td> 存放佈景主題程式碼,可用來修改軟體外觀。</td> | ||
| + | </tr> | ||
| + | </table> | ||
| + | |||
| + | ==可擴充功能== | ||
| + | <table border=1 cellspacing=0 color=black class=nicetable> | ||
| + | <tr><th>名稱</th><th>用途</th></tr> | ||
| + | <tr> | ||
| + | <th> Tag Extension</th> | ||
| + | <td> 擴充MediaWiki語法,用XML格式來方式,其語法為<b>&lt;語法名稱 參數一="參數值" 參數二="參數值"&gt;傳入內容&lt;/語法名稱&gt; </b>;Tag Extension傳回內容只能是Wiki所接受的HTML語法。</td> | ||
| + | </tr> | ||
| + | <tr> | ||
| + | <th> Parser Function</th> | ||
| + | <td> 擴充MediaWiki語法,其語法為<b>{{ #函式名稱: 參數一 | 參數二 | 參數三 }}</b>;Parser Function傳回的內容可以是Wiki語法並且參數能夠傳入MediaWiki的變數在函式中處理,例如<b>{{{CURRENTDATE}}}</b>。</td> | ||
| + | </tr> | ||
| + | <tr> | ||
| + | <th> Hook</th> | ||
| + | <td> Hook可以用來欄截MediaWiki軟體中的事件,例如儲存頁面、上傳檔案、登入…等等;在使用Hook時要指定由哪個函式來執行,語法為<b>$wgHooks['event'][] = 'function';</b>。其中的function會根據每個Hook的不同而有不同的型式,例如傳入兩個參數或是需指定一個物件,下面為傳入兩個參數的函式範例<b>someFunction($param1, $param2);</b>。</td> | ||
| + | </tr> | ||
| + | <tr> | ||
| + | <th> Special Page</th> | ||
| + | <td> 在MediaWiki中有Special Page,意思是特殊頁面,例如帳號登入、網站統計、權限管理…等較特殊的功能都會在Special Page中實作。</td> | ||
| + | </tr> | ||
| + | </table> | ||
| + | ===Tag Extension=== | ||
| + | 擴充程式 | ||
| + | <pre> | ||
| + | $wgExtensionFunctions[] = '掛勾函式'; | ||
| + | function 掛勾函式() { | ||
| + | global $wgParser; | ||
| + | $wgParser->setHook('標籤名', '標籤的實體化函式'); | ||
| + | } | ||
| + | function 標籤的實體化函式($input) { | ||
| + | … | ||
| + | return 實體化字串; | ||
| + | }</pre> | ||
| + | LocalSettings.php 中 | ||
| + | include_once( "$IP/extensions/擴充程式" ); | ||
| + | |||
| + | ===Parser Function=== | ||
| + | 擴充程式 | ||
| + | <pre> | ||
| + | $wgAutoloadClasses['類別名'] = 類別定義檔; | ||
| + | $wgHooks['ParserFirstCallInit'][] = '掛勾函式'; | ||
| + | function 掛勾函式( $parser ) { | ||
| + | global $wgPFEnableStringFunctions, $wgPFEnableConvert; | ||
| + | $parser->setFunctionHook( '魔術字', '類別名::方法'); | ||
| + | … | ||
| + | }</pre> | ||
| + | LocalSettings.php 中 | ||
| + | include_once( "$IP/extensions/擴充程式" ); | ||
| + | |||
| + | ==延伸套件== | ||
| + | [http://www.mediawiki.org/wiki/Category:Extensions_by_category 分類總目錄] | ||
| + | *嵌入影片 | ||
| + | *#參考[http://www.mediawiki.org/wiki/Extension:VideoFlash VideoFlash] | ||
| + | *#製造 extensions/videoflash.php 。 | ||
| + | *#在 LocalSettings.php 中加「require_once("$IP/extensions/videoflash.php");」。 | ||
| + | *#在共筆頁中使用 videoflash 標籤。 | ||
| + | *解除 HTML 標籤使用限制 | ||
| + | *#找到 includes 資料夾下的 Sanitizer.php | ||
| + | *#找到 Sanitizer 類別中的 removeHTMLtags 方法 | ||
| + | *#改變要移除 tags 的清單 | ||
| + | *嵌入含圖連結 | ||
| + | *#參考[http://www.mediawiki.org/wiki/Extension:LinkedImage LinkedImage] | ||
| + | *#在 LocalSettings.php 中加「require_once( "$IP/extensions/LinkedImages.php" );」。 | ||
| + | *#在共筆頁中使用 videoflash 標籤。 | ||
| + | |||
| + | ==[http://svn.wikimedia.org/doc/GlobalFunctions_8php.html 全域函式]== | ||
| + | wfFindFile | ||
| + | |||
| + | wfLocalFile($title) | ||
| + | 傳回物件,此物件的getURL方法即可找出檔案之所在 | ||
| + | |||
| + | ==主程式== | ||
| + | ===index.php=== | ||
| + | 請參考 indej.php 中丁丁的註解 | ||
| + | # $preIP = dirname( __FILE__ ); // 取得路徑 | ||
| + | # require_once( "$preIP/includes/WebStart.php" ); | ||
| + | # … | ||
| + | # $mediaWiki->finalCleanup( $wgOut ); // by jj 輸出頁面 | ||
| + | # … | ||
| + | ====includes/Wiki.php==== | ||
| + | class MediaWiki 內的 | ||
| + | |||
| + | 方法 finalCleanup 中的: | ||
| + | $output->output(); | ||
| + | |||
| + | ====includes/OutputPage.php==== | ||
| + | class OutputPage 內的 | ||
| + | |||
| + | 方法 output 中的: | ||
| + | $sk->outputPage( $this ); | ||
| + | |||
| + | ====includes/SkinTemplate.php==== | ||
| + | class SkinTemplate extends Skin 內的 | ||
| + | |||
| + | 方法 outputPage 中的: | ||
| + | $res = $tpl->execute(); | ||
| + | |||
| + | ====includes/SkinTemplate.php==== | ||
| + | abstract class QuickTemplate 抽象類別內的 | ||
| + | |||
| + | 抽象方法 execute 無內容,由其 sub class 在繼承之後實作該方法的細節。 | ||
| + | abstract public function execute(); | ||
| + | |||
| + | ====skins/Vector.php==== | ||
| + | class VectorTemplate extends QuickTemplate 類別內的 | ||
| + | |||
| + | 方法 execute ,找到 &lt;!-- bodytext --&gt;,在其下插入要顯示的部分, | ||
| + | |||
| + | ==設定== | ||
| + | ===includes/DefaultSettings.php=== | ||
| + | $wgFileExtensions = array( 'png', 'gif', 'jpg', 'jpeg' ,'svg'); // 允許上傳的附檔名 | ||
| + | |||
| + | ==includes/WebStart.php== | ||
| + | |||
| + | ==includes/Linker.php== | ||
| + | Linker::normalizeSubpageLink方法;將含「.、..、/」的title正規化成合法的title | ||
| + | |||
| + | ==includes/Title.php== | ||
| + | Title 類別內的 | ||
| + | #userCanRead 方法:判斷能不能讀取目前的共筆頁 | ||
| + | #getArticleID():查此頁是第幾層的嵌入文,最外層為1,逐層加1 | ||
| + | #getPrefixedText():未處理前的頁名 | ||
| + | #getText():處理後的頁名 | ||
| + | #isTalkPage() | ||
| + | #setFragment( '' ) | ||
| + | #isConversionTable() | ||
| + | |||
| + | ==includes/Article.php== | ||
| + | Article 類別 | ||
| + | |||
| + | 見[[Mediawiki 程式說明/取段落]] | ||
| + | == include/Sanitizer.php== | ||
| + | 文字過濾程式。內含 Sanitizer.php,$htmlsingle,$htmlsingleonly,$htmlnest,$tabletags,$htmllist,$listtags 諸陣列,控制各種 HTML tag,如何表現,可用不可用。 | ||
| + | |||
| + | ==includes/parser/Parser.php== | ||
| + | 本程式為 wiki 語法解析的核心。 | ||
| + | ===製造分段描述陣列$Article->mParserOutput->mSections=== | ||
| + | Parser 類別中 | ||
| + | |||
| + | parse方法叫用internalParse($text)方法=> | ||
| + | |||
| + | internalParse($text)中叫用formatHeadings($text,$origText,$isMain)=> | ||
| + | |||
| + | 方法formatHeadings($text,$origText,$isMain)中做出分段描述陣列$tocraw,並以 | ||
| + | $this->mOutput->setSections($tocraw); | ||
| + | 送去給includes/parser/ParserOutput.php中的ParserOutput類別的 | ||
| + | function setSections($toc){return wfSetVar($this->mSections,$toc);} | ||
| + | 將$toc派給了$Article->mParserOutput->mSections | ||
| + | |||
| + | ===從整篇wiki文中提取其中某段的wiki原文=== | ||
| + | private function extractSections(wiki文字,段編號,$mode,取代文) | ||
| + | #第一段的段編號為1,餘類推。段編號0代表要拉出第一段之前的導言文字 | ||
| + | #$mode有兩個值:get或replace | ||
| + | #extractSections只有物件內部才能叫用,外部調用者應該使用以下兩種方法getSection和replaceSection | ||
| + | |||
| + | public function getSection($text $section,$deftext=""){ | ||
| + | return $this->extractSections($text,$section,"get",$deftext); | ||
| + | } | ||
| + | |||
| + | public function replaceSection($oldtext,$section,$text){ | ||
| + | return $this->extractSections($oldtext,$section,"replace",$text); | ||
| + | } | ||
| + | |||
| + | ===跨wiki提取某頁=== | ||
| + | LocalSettings.php中必須設: | ||
| + | $wgEnableScaryTranscluding=true; // 預設值為假 | ||
| + | includes/db/Database.php提供資料庫呼叫的抽象層類別DatabaseBase,其中: | ||
| + | function select(表,欄,條件,…) // 叫selectSQLText | ||
| + | function selectSQLText(表,欄,條件,…) | ||
| + | 負責叫用資料表。 | ||
| + | |||
| + | includes/Interwiki.php提供Interwiki類別,其中的 | ||
| + | function load(網站前置字) | ||
| + | load方法從interwiki表中抽取網站前置字相符的資料,交給loadFromArray方法做成Interwiki物件然後回傳。 | ||
| + | |||
| + | Parser類別中的interwikiTransclude方法負責將$title代表的跨站頁嵌入: | ||
| + | function interwikiTransclude($title,$action){ | ||
| + | global $wgEnableScaryTranscluding; | ||
| + | if(!$wgEnableScaryTranscluding){ // 如不許跨wiki嵌入 | ||
| + | return wfMsgForContent('scarytranscludedisabled'); | ||
| + | } | ||
| + | $url=$title->getFullUrl("action=$action");// 取$title的URL | ||
| + | if(strlen($url)>255){ // URL如太長 | ||
| + | return wfMsgForContent('scarytranscludetoolong'); | ||
| + | } | ||
| + | return $this->fetchScaryTemplateMaybeFromCache($url);// 真的嵌入 | ||
| + | } | ||
| + | |||
| + | Parser類別中的braceSubstitution方法有一小段負責叫用interwikiTransclude | ||
| + | |||
| + | function braceSubstitution(…){ | ||
| + | … | ||
| + | # Interwiki transclusion | ||
| + | // 如outtype(ot)要求為html,就嵌入解譯後的結果 | ||
| + | if($this->ot['html'] && !$forceRawInterwiki){ | ||
| + | $text=$this->interwikiTransclude($title,'render'); | ||
| + | $isHTML=true; | ||
| + | }else{// 否則就先取回wiki原文,再仿樣板進行預處理 | ||
| + | $text=$this->interwikiTransclude($title,'raw'); | ||
| + | # Preprocess it like a template | ||
| + | $text=$this->preprocessToDom($text,self::PTD_FOR_INCLUSION); | ||
| + | $isChildObj=true; | ||
| + | } | ||
| + | … | ||
| + | } | ||
| + | 而Title類中getFullURL裡負責處理interwiki的部分有錯,需抑制修改: | ||
| + | // 因<nowiki>{{</nowiki>…}}的關係,造成$namespace變成Template,使URL插入多餘的 | ||
| + | // 「Template:」,為糾正此錯誤須抑制修改以下各行 by jj | ||
| + | #$namespace = wfUrlencode( $this->getNsText() ); | ||
| + | #if ( $namespace != '' ) { | ||
| + | # # Can this actually happen? Interwikis shouldn't be parsed. | ||
| + | # # Yes! It can in interwiki transclusion. But... it probably shouldn't. | ||
| + | # $namespace .= ':'; | ||
| + | #} | ||
| + | #$url = str_replace( '$1', $namespace . $this->mUrlform, $baseUrl ); | ||
| + | $url = str_replace( '$1', $this->mUrlform, $baseUrl ); | ||
| + | |||
| + | ===嵌入=== | ||
| + | 展開<nowiki>{{</nowiki>…}之braceSubstitution函式處理流程如下: | ||
| + | 一次性替代(subst) | ||
| + | 變數 | ||
| + | 魔術字訊息 | ||
| + | 解析函式名稱 | ||
| + | 重整 title 並做$title物件 | ||
| + | 從資料表找出樣板內容 | ||
| + | 內部title | ||
| + | 外部title | ||
| + | 如未找到替代文,我們也做完了,傳回wiki原文 | ||
| + | 在 child frame 展開 DOM-style 並傳回其值 | ||
| + | 詳解請看 includes/parser/braceSubstitution解說.php | ||
[https://www.mediawiki.org/wiki/Manual:$wgEnableScaryTranscluding 跨 wiki 嵌入的說明] | [https://www.mediawiki.org/wiki/Manual:$wgEnableScaryTranscluding 跨 wiki 嵌入的說明] | ||
| + | |||
==includes/Title.php== | ==includes/Title.php== | ||
而Title類中 getLocalURL 方法中負責處理 interwiki 的部分有錯,因<nowiki>{{</nowiki>…}}的關係,造成 $namespace 變成 Template ,使URL插入多餘的「Template:」,需抑制修改: | 而Title類中 getLocalURL 方法中負責處理 interwiki 的部分有錯,因<nowiki>{{</nowiki>…}}的關係,造成 $namespace 變成 Template ,使URL插入多餘的「Template:」,需抑制修改: | ||
2014年8月26日 (二) 14:49的修訂版本
目錄
檔案架構
| 名稱 | 說明 |
|---|---|
| math | 存放解析數學公式的程式碼,一般而言不會接觸到,但若是數學公式功能無法成功安裝,可藉由目錄下的資訊來除錯。 |
| bin | 存放在開發MediaWiki時會用到的批次檔,一般管理者或開發者不會接觸到。 |
| config | 存放預設的MediaWiki設定檔(LocalSettings.php),只會於安裝時接觸到。 |
| docs | 存放說明文件,對於要擴充功能的開發者很具有參考價值。 |
| extensions | 存放擴充套件之目錄,對於想要擴充功能的開發者是必須要瞭解的目錄。 |
| images | 存放檔案以及圖片的目錄。 |
| includes | 存放主要的程式碼,要深入瞭解MediaWiki程式架構此程式碼必深入研究。 |
| languages | 存放各種語系的翻譯檔案。 |
| maintenance | 存放維護程式碼,例如資料庫SQL指令、升級程式碼。 |
| skins | 存放佈景主題程式碼,可用來修改軟體外觀。 |
可擴充功能
| 名稱 | 用途 |
|---|---|
| Tag Extension | 擴充MediaWiki語法,用XML格式來方式,其語法為<語法名稱 參數一="參數值" 參數二="參數值">傳入內容</語法名稱> ;Tag Extension傳回內容只能是Wiki所接受的HTML語法。 |
| Parser Function | 擴充MediaWiki語法,其語法為{{ #函式名稱: 參數一 | 參數二 | 參數三 }};Parser Function傳回的內容可以是Wiki語法並且參數能夠傳入MediaWiki的變數在函式中處理,例如{{{CURRENTDATE}}}。 |
| Hook | Hook可以用來欄截MediaWiki軟體中的事件,例如儲存頁面、上傳檔案、登入…等等;在使用Hook時要指定由哪個函式來執行,語法為$wgHooks['event'][] = 'function';。其中的function會根據每個Hook的不同而有不同的型式,例如傳入兩個參數或是需指定一個物件,下面為傳入兩個參數的函式範例someFunction($param1, $param2);。 |
| Special Page | 在MediaWiki中有Special Page,意思是特殊頁面,例如帳號登入、網站統計、權限管理…等較特殊的功能都會在Special Page中實作。 |
Tag Extension
擴充程式
$wgExtensionFunctions[] = '掛勾函式';
function 掛勾函式() {
global $wgParser;
$wgParser->setHook('標籤名', '標籤的實體化函式');
}
function 標籤的實體化函式($input) {
…
return 實體化字串;
}
LocalSettings.php 中
include_once( "$IP/extensions/擴充程式" );
Parser Function
擴充程式
$wgAutoloadClasses['類別名'] = 類別定義檔;
$wgHooks['ParserFirstCallInit'][] = '掛勾函式';
function 掛勾函式( $parser ) {
global $wgPFEnableStringFunctions, $wgPFEnableConvert;
$parser->setFunctionHook( '魔術字', '類別名::方法');
…
}
LocalSettings.php 中
include_once( "$IP/extensions/擴充程式" );
延伸套件
- 嵌入影片
- 參考VideoFlash
- 製造 extensions/videoflash.php 。
- 在 LocalSettings.php 中加「require_once("$IP/extensions/videoflash.php");」。
- 在共筆頁中使用 videoflash 標籤。
- 解除 HTML 標籤使用限制
- 找到 includes 資料夾下的 Sanitizer.php
- 找到 Sanitizer 類別中的 removeHTMLtags 方法
- 改變要移除 tags 的清單
- 嵌入含圖連結
- 參考LinkedImage
- 在 LocalSettings.php 中加「require_once( "$IP/extensions/LinkedImages.php" );」。
- 在共筆頁中使用 videoflash 標籤。
全域函式
wfFindFile
wfLocalFile($title) 傳回物件,此物件的getURL方法即可找出檔案之所在
主程式
index.php
請參考 indej.php 中丁丁的註解
- $preIP = dirname( __FILE__ ); // 取得路徑
- require_once( "$preIP/includes/WebStart.php" );
- …
- $mediaWiki->finalCleanup( $wgOut ); // by jj 輸出頁面
- …
includes/Wiki.php
class MediaWiki 內的
方法 finalCleanup 中的:
$output->output();
includes/OutputPage.php
class OutputPage 內的
方法 output 中的:
$sk->outputPage( $this );
includes/SkinTemplate.php
class SkinTemplate extends Skin 內的
方法 outputPage 中的:
$res = $tpl->execute();
includes/SkinTemplate.php
abstract class QuickTemplate 抽象類別內的
抽象方法 execute 無內容,由其 sub class 在繼承之後實作該方法的細節。
abstract public function execute();
skins/Vector.php
class VectorTemplate extends QuickTemplate 類別內的
方法 execute ,找到 <!-- bodytext -->,在其下插入要顯示的部分,
設定
includes/DefaultSettings.php
$wgFileExtensions = array( 'png', 'gif', 'jpg', 'jpeg' ,'svg'); // 允許上傳的附檔名
includes/WebStart.php
includes/Linker.php
Linker::normalizeSubpageLink方法;將含「.、..、/」的title正規化成合法的title
includes/Title.php
Title 類別內的
- userCanRead 方法:判斷能不能讀取目前的共筆頁
- getArticleID():查此頁是第幾層的嵌入文,最外層為1,逐層加1
- getPrefixedText():未處理前的頁名
- getText():處理後的頁名
- isTalkPage()
- setFragment( )
- isConversionTable()
includes/Article.php
Article 類別
include/Sanitizer.php
文字過濾程式。內含 Sanitizer.php,$htmlsingle,$htmlsingleonly,$htmlnest,$tabletags,$htmllist,$listtags 諸陣列,控制各種 HTML tag,如何表現,可用不可用。
includes/parser/Parser.php
本程式為 wiki 語法解析的核心。
製造分段描述陣列$Article->mParserOutput->mSections
Parser 類別中
parse方法叫用internalParse($text)方法=>
internalParse($text)中叫用formatHeadings($text,$origText,$isMain)=>
方法formatHeadings($text,$origText,$isMain)中做出分段描述陣列$tocraw,並以
$this->mOutput->setSections($tocraw);
送去給includes/parser/ParserOutput.php中的ParserOutput類別的
function setSections($toc){return wfSetVar($this->mSections,$toc);}
將$toc派給了$Article->mParserOutput->mSections
從整篇wiki文中提取其中某段的wiki原文
private function extractSections(wiki文字,段編號,$mode,取代文)
- 第一段的段編號為1,餘類推。段編號0代表要拉出第一段之前的導言文字
- $mode有兩個值:get或replace
- extractSections只有物件內部才能叫用,外部調用者應該使用以下兩種方法getSection和replaceSection
public function getSection($text $section,$deftext=""){
return $this->extractSections($text,$section,"get",$deftext);
}
public function replaceSection($oldtext,$section,$text){
return $this->extractSections($oldtext,$section,"replace",$text);
}
跨wiki提取某頁
LocalSettings.php中必須設:
$wgEnableScaryTranscluding=true; // 預設值為假
includes/db/Database.php提供資料庫呼叫的抽象層類別DatabaseBase,其中:
function select(表,欄,條件,…) // 叫selectSQLText function selectSQLText(表,欄,條件,…)
負責叫用資料表。
includes/Interwiki.php提供Interwiki類別,其中的
function load(網站前置字)
load方法從interwiki表中抽取網站前置字相符的資料,交給loadFromArray方法做成Interwiki物件然後回傳。
Parser類別中的interwikiTransclude方法負責將$title代表的跨站頁嵌入:
function interwikiTransclude($title,$action){
global $wgEnableScaryTranscluding;
if(!$wgEnableScaryTranscluding){ // 如不許跨wiki嵌入
return wfMsgForContent('scarytranscludedisabled');
}
$url=$title->getFullUrl("action=$action");// 取$title的URL
if(strlen($url)>255){ // URL如太長
return wfMsgForContent('scarytranscludetoolong');
}
return $this->fetchScaryTemplateMaybeFromCache($url);// 真的嵌入
}
Parser類別中的braceSubstitution方法有一小段負責叫用interwikiTransclude
function braceSubstitution(…){
…
# Interwiki transclusion
// 如outtype(ot)要求為html,就嵌入解譯後的結果
if($this->ot['html'] && !$forceRawInterwiki){
$text=$this->interwikiTransclude($title,'render');
$isHTML=true;
}else{// 否則就先取回wiki原文,再仿樣板進行預處理
$text=$this->interwikiTransclude($title,'raw');
# Preprocess it like a template
$text=$this->preprocessToDom($text,self::PTD_FOR_INCLUSION);
$isChildObj=true;
}
…
}
而Title類中getFullURL裡負責處理interwiki的部分有錯,需抑制修改:
// 因{{…}}的關係,造成$namespace變成Template,使URL插入多餘的
// 「Template:」,為糾正此錯誤須抑制修改以下各行 by jj
#$namespace = wfUrlencode( $this->getNsText() );
#if ( $namespace != ) {
# # Can this actually happen? Interwikis shouldn't be parsed.
# # Yes! It can in interwiki transclusion. But... it probably shouldn't.
# $namespace .= ':';
#}
#$url = str_replace( '$1', $namespace . $this->mUrlform, $baseUrl );
$url = str_replace( '$1', $this->mUrlform, $baseUrl );
嵌入
展開{{…}之braceSubstitution函式處理流程如下:
一次性替代(subst) 變數 魔術字訊息 解析函式名稱 重整 title 並做$title物件 從資料表找出樣板內容
內部title 外部title
如未找到替代文,我們也做完了,傳回wiki原文 在 child frame 展開 DOM-style 並傳回其值
詳解請看 includes/parser/braceSubstitution解說.php 跨 wiki 嵌入的說明
includes/Title.php
而Title類中 getLocalURL 方法中負責處理 interwiki 的部分有錯,因{{…}}的關係,造成 $namespace 變成 Template ,使URL插入多餘的「Template:」,需抑制修改:
#$namespace = $this->getNsText();
#if ( $namespace != ) {
# Can this actually happen? Interwikis shouldn't be parsed.
# Yes! It can in interwiki transclusion. But... it probably shouldn't.
# $namespace .= ':';
#}
#$url = $interwiki->getURL( $namespace . $this->getDBkey() );// by jj
includes/parser/Parser.php
本程式為 wiki 語法解析的核心。
負責取回跨 wiki 內容的方法發生問題,結果傳回[抱歉,模板https://zh.wikibooks.org/wiki/%E5%88%9D%E4%B8%AD%E6%95%B8%E5%AD%B8/%E6%A0%B9%E8%99%9F?action=render讀取失敗]。將有問題段落列在後面:
function fetchScaryTemplateMaybeFromCache( $url ) {
global $wgTranscludeCacheExpiry;// 跨 wiki 快取生命週期,為 3600 秒,即一小時
$dbr = wfGetDB( DB_SLAVE );
// 暫存條件:目前時間減跨 wiki 快取生命週期
$tsCond = $dbr->timestamp( time() - $wgTranscludeCacheExpiry );
// 取transcache表tc_time及tc_contents欄,條件為tc_url為$url且tc_time長於暫存條件
$obj = $dbr->selectRow( 'transcache', array( 'tc_time', 'tc_contents' ),
array( 'tc_url' => $url, "tc_time >= " . $dbr->addQuotes( $tsCond ) ) );
// 如果找到快取內容,傳回
if ( $obj ) {
return $obj->tc_contents;
}
// 執行includes/HttpFunctions.php中MWHttpRequest類別的factory方法,以產生 HTTP 的請求物件
$req = MWHttpRequest::factory( $url );
// 執行請求,會得到結果狀態物件
$status = $req->execute(); // Status object
// 執行請求後取回的內容是空值
$text = $req->getContent();
// 執行請求後,結果狀態不是 OK,所以$text得到空值
if ( $status->isOK() ) {
$text = $req->getContent();
// 執行請求後,getStatus()得 200 ,所以scarytranscludefailed-httpstatus錯誤提示不會執行
} elseif ( $req->getStatus() != 200 ) { // Though we failed to fetch the content, this status is useless.
return wfMessage( 'scarytranscludefailed-httpstatus', $url, $req->getStatus() /* HTTP status */ )->inContentLanguage()->text();
// 執行請求後,getStatus()得 200 ,所以傳回[抱歉,模板https://zh.wikibooks.org/wiki/%E5%88%9D%E4%B8%AD%E6%95%B8%E5%AD%B8/%E6%A0%B9%E8%99%9F?action=render讀取失敗]
} else {
return wfMessage( 'scarytranscludefailed', $url )->inContentLanguage()->text();
}
// 以下更新跨 wiki 快取的欄值
$dbw = wfGetDB( DB_MASTER );
$dbw->replace( 'transcache', array( 'tc_url' ), array(
'tc_url' => $url,
'tc_time' => $dbw->timestamp( time() ),
'tc_contents' => $text)
);
// 執行請求後,結果狀態如果是OK,傳回$text
return $text;
}