LLWiki正在建設中,歡迎加入我們

LLWiki:管理員技術手冊

出自LLWiki
於 2023年3月17日 (五) 13:29 由 Bhsd留言 | 貢獻 所做的修訂 (// 使用Wikiplus小工具快速编辑)
(差異) ←上個修訂 | 最新修訂 (差異) | 下個修訂→ (差異)
跳至導覽 跳至搜尋
內容缺失.png 此頁面內容嚴重缺失,急需您幫忙補充!(點此編輯)
可參考同類條目添加所需內容,並從官方等可靠渠道搜集資料編寫,亦建議附上資料來源。

由於LLWiki使用的不是最新版本的MediaWiki系統以及MediaWiki的幫助頁面可能未得到及時和正確的更新,編輯這個頁面時請不要簡單地複製或翻譯來自MediaWiki的內容,應該在條件允許的情況下先實際測試。

全站CSS

這裡所說的全站CSS包含common.cssmobile.css和各CSS小工具,有時由於功能的相似性也會涉及用戶CSS(common.cssvector.cssminerva.css)。LLWiki暫時沒有建立針對不同用戶組的專門CSS頁面。

優先加載的CSS

一些CSS會以<link rel="stylesheet">的形式在首次渲染前完成加載,包括common.css和各純CSS小工具,這些CSS頁面適合處理靜態HTML元素就需要的樣式。注意純CSS小工具即使在定義時規定了targets=mobile也一定會在桌面版加載,因此手機版的專用CSS需要添加.skin-minerva選擇器。

由於common.css本身就會優先加載,桌面版專用的全站CSS寫入該頁面即可,與手機版通用的CSS寫入gadget-site-styles.css。某個小工具專用的CSS如果需要用於靜態HTML元素,請將CSS部分單獨定義為type=styles(可省略,但添加後方便區分)的純CSS小工具,然後以peers=<纯CSS小工具名称>的語法添加到對應的JS小工具上。參見#小工具定義

滯後加載的CSS

一些CSS的加載需要依賴JS,加載時機可能晚於首次渲染,包括mobile.css和除純CSS小工具以外的CSS小工具,這些CSS頁面適合處理依賴JS動態加載的HTML元素。

由於mobile.css加載滯後,靜態HTML元素需要的手機版樣式請添加.skin-minerva選擇器後寫入gadget-site-styles.css

CSS小工具分類

定義為type=styles的小工具應添加純CSS小工具分類,其他CSS小工具應添加CSS小工具分類。其他分類與JS小工具一致,參見#小工具分類

Widget(小部件)

小部件頁面格式

小部件分類

小部件JS的特殊之處

Gadget(小工具)和全站JS

這裡所涉及的JS頁面包含common.jsmobile.js和各JS小工具,有時由於功能的相似性也會涉及用戶JS(common.jsvector.jsminerva.js)。LLWiki暫時沒有建立針對不同用戶組的專門JS頁面。

ResourceLoader和JS模塊

common.jsmobile.js用戶JSMediaWiki:Gadgets-definition頁面定義的小工具等JS頁面會作為ResourceLoader的模塊加載,這些JS將在語法檢查和壓縮後由load.php打包下載,且可以作為mw.loader.getState()方法、mw.loader.using()方法的參數。

作為ResourceLoader的模塊加載時,不可使用ES6語法。這裡的語法指關鍵字、算符等,不包括對象原型方法,例如Object.fromEntries()方法或new Map()構造器仍可照常使用。下表列出一些常見的JS模塊不可使用的語法及其替代。

ES6以上語法 替代
=> output function() { return output; }
class NewClass extends Parent {
  constructor(params) { super(params); }
}
function NewClass(params) { NewClass.super.call(this, params); }
OO.inheritClass(NewClass, Parent);
{key} {key: key}
`firstline
secondline`
'firstline\n' + 'secondline'
`string${variable}` 'string' + variable
[variable] = array; variable = array[0];
{key: variable} = {key: value}; variable = {key: value}['key'];
function(params = defaults) function() { params = params || defaults; }
[...iterator] Array.from( iterator )
array2 = [...array1]; array2 = array1.slice();
[...array1, ...array2] array1.concat( array2 )
[element, ...rest] = array; element = array[0], rest = array.slice(1);
let[1] var
2**3[2] Math.pow(2, 3)
async function()[2] function() { return new Promise(resolve, reject); }
try { variable = await func(); } catch {}[2] func().then(function(result) { variable = result; }, function() {});
obj1 = {...obj2};[2] obj1 = $.extend(true, {}, obj2);
{...object1, ...object2}[2] $.extend(object1, object2)Object.assign(object1, object2)[3]

不作為模塊的JS腳本

小工具定義

小工具簡介

小工具分類

MediaWiki核心模塊介紹

本章節介紹LLWiki使用或曾經使用的MediaWiki核心模塊,更完整的列表參見MediaWikiJSDuck

mediawiki

mediawiki是任何頁面都會預加載的兩個環境模塊之一,包含不少功能[4]。這裡只介紹LLWiki常使用的一些屬性和方法。

mw.config
這個屬性提供了大量重要的站點、頁面和用戶信息[5],一般常用mw.config.get()方法獲取對應的變量值。下表整理了LLWiki常用的一些變量:
變量名 說明 手機版可用性
skin 皮膚 桌面版為「vector」,手機版為「minerva」,這也是區分桌面版和手機版的主要依據
wgFormattedNamespaces 儲存了所有命名空間本地化譯名的數組,不過目前除了「模塊」都是英文 可用
wgNamespaceIds 儲存了所有可接受的中英文命名空間名稱對應的編號,注意英文名稱中的空格都顯示為下劃線 可用
wgScript /mediawiki/index.php,在LLWiki也可簡化為/zh,主要用於不同MediaWiki站點間的代碼通用,非必需且不推薦使用 可用
wgAction index.php的action參數[6] 相比於桌面版,手機版由於添加了Special:歷史而少了「history」這個可能值
wgArticleId 內容頁面編號,不存在時值為0,可以用於判斷是否是內容頁面且頁面是否已建立 需要注意查看歷史差異時值為0
wgCanonicalSpecialPageName 標準化的特殊頁面名,也可被wgPageName取代,主要用於不同MediaWiki站點間的代碼通用,非必需 可用,而且多了「History」和"MobileDiff"等可能的取值[7]
wgCategories 當前閱讀的歷史版本所屬的分類,不含命名空間,下劃線顯示為空格,且總是包含隱藏分類。繁簡規則遵從實際分類頁面 僅LLWiki可用
wgCurRevisionId 頁面最新的版本編號,不存在時值為0 歷史差異頁面不可用
wgIsArticle 是否是內容頁面(包含由某個頁面的Wikitext原始碼解析生成的HTML,可能是歷史頁面和差異下方的歷史頁面) 由於差異頁面不可同時顯示歷史頁面,此時不可用
wgIsRedirect 最新版本是否是重定向頁面 歷史差異頁面不可用
wgIsProbablyEditable 是否可能可以編輯 歷史差異頁面不可用
wgNamespaceNumber 命名空間編號 歷史差異頁面會顯示為-1
wgPageContentModel 頁面內容模型,特殊頁面為「wikitext」 由於歷史差異是特殊頁面,會錯誤地顯示為「wikitext」
wgPageName 頁面名稱,空格顯示為下劃線 歷史差異頁面不可用
wgRedirectFrom 跳轉自重定向時為對應的重定向頁,空格顯示為下劃線 可用
wgRelevantPageName 關聯的頁面名稱,空格顯示為下劃線 可以用於歷史差異頁面,此時效果與桌面版一致
wgRelevantArticleId 關聯的內容頁面編號,不存在時值為0 可以用於歷史差異頁面,此時效果與桌面版一致
wgRelevantUserName 關聯的用戶名 使用者貢獻頁面不可用
wgRelevantPageIsProbablyEditable 關聯的頁面是否可能可以編輯 可以用於歷史差異頁面,此時效果與桌面版一致
wgRestrictionEdit 編輯保護,不存在的頁面(含受保護的標題)或特殊頁面為null,存在的內容頁面受全保護時為["sysop"],受半保護時為["autoconfirmed"],未保護為[];不包含命名空間保護和級聯保護 歷史差異頁面不可用,另外未保護的內容頁面為["*"]
wgRestrictionMove 移動保護,不存在的頁面或特殊頁面為null,存在的內容頁面受全保護時為["sysop"],受半保護時為["autoconfirmed"],未保護為[];不包含命名空間保護和級聯保護 歷史差異頁面不可用
wgRevisionId 當前顯示的頁面版本的編號,不存在時值為0。注意和index.php的oldid參數可能不同 由於差異頁面不可同時顯示歷史頁面,此時不可用
wgTitle 不含命名空間的頁面名稱,下劃線顯示為空格 歷史差異頁面不可用
wgUserEditCount 當前用戶的編輯次數 可用
wgUserGroups 當前用戶所屬的用戶組,未登入時為["*"] 可用
wgUserLanguage 當前用戶使用的界面語言 可用
wgUserName 當前用戶的用戶名,下劃線顯示為空格 可用
wgUserRegistration 當前用戶的註冊時間,顯示為毫秒數;可以使用mw.user.getRegistration()方法替代,該方法會生成Date對象 可用
wgUserVariant 當前用戶閱讀頁面時的內容語言,在不可更改內容語言的頁面總是為該用戶的默認內容語言 可用
wgDiffOldId 差異頁面位於左側的版本的編號 不可用
wgDiffNewId 差異頁面位於右側的版本的編號 不可用
mw.hook()
這個方法是LLWiki建立異步JS框架的重要一環。常用以下兩個方法:
  • mw.hook(hook).fire(data): 用於喚起一個Hook事件,其中data為傳遞給事件處理程序的可選參數。
  • mw.hook(hook).add(handler): 用於處理一個Hook事件,handler為該事件處理函數,參數傳遞自mw.hook().fire()方法。
這個方法應與jQuery的event delegation和各Promise對象結合使用,以在恰當的時機執行恰當的函數。以下列舉LLWiki常用的Hook事件。
Hook名稱 說明
MediaWiki預定義的Hook
postEdit 一次非空編輯提交成功,一般發生在自動重載頁面後,可以搭配mw.config.get( 'wgPostEdit' )。需要注意各類編輯小工具提交編輯後的頁面重載均未適配這個事件
structuredChangeFilters.ui.initialized 近期變更相關變更監視清單頁面的過濾器加載完成,一般至多發生一次
wikipage.categories 頁面下方的div#catlinks加載完成。特殊頁面或沒有添加任何分類時也能觸發,因為此時#catlinks仍然存在只是隱藏起來
wikipage.collapsibleContent 某個或某組mw-collapsible類的元素添加摺疊JS完成
wikipage.content 最常用的Hook,表示頁面內容(一般即div#mw-content-text)加載完成,幾乎無處不在,與$.ready最大的區別在於這個事件可能多次觸發
wikipage.diff 差異(一般即table.diff)加載完成
wikipage.editform 編輯區加載完成,需要注意此時WikiEditor的工具欄可能尚未加載完成
codeEditor.configure 切換至CodeEditor
LLWiki定義的Hook
code.prettify 代碼高亮完成
codemirror.config CodeMirror擴展的設置下載完成
hotcat.ready HotCat小工具加載完成
local.comments 簽名時間替換為本地時區
to.bottom 添加滾動至底部的按鈕
transclusion.preview 用於預覽嵌入頁面的編輯區加載完成
wikiplus.dialog 打開Wikiplus小工具的對話框
mw.loader
mw.loader包含了很多用於ResourceLoader的方法。
  • mw.loader.addStyleTag(),用於在header的末尾插入一個<style>。由於返回的是一個HTML元素,後續操作不如mw.util.addCSS()返回的StyleSheet對象方便,但在不需要後續操作的場合可以不用加載mediawiki.util模塊。由於mediawiki.util在LLWiki的廣泛使用,這個方法幾乎沒有任何優點。
  • mw.loader.getScript(),用於加載外部JS腳本,相比mw.loader.load()方法優點在於會返回一個Promise對象。
  • mw.loader.getState(),用於獲取模塊的當前狀態,不可用的模塊返回null,可用但未加載的模塊返回'registered',可用且正在加載的模塊可能返回'loaded''loading',已加載完成的模塊返回'ready'。注意加載完成的模塊未必已經執行完。
  • mw.loader.load(),用於加載模塊、其他JS或其他CSS,加載模塊時參數為模塊名或一個模塊名構成的數組,加載JS或CSS時填寫url,加載CSS還需要額外填寫第二參數'text/css'。缺點在於不會返回一個Promise對象。
  • mw.loader.using(),用於加載模塊,相比mw.loader.load()方法優點在於會返回一個Promise對象,任一模塊加載失敗即返回rejected。
mw.notify()
調用這個方法可以在桌面版的右上角、手機版的上方顯示一個泡泡通知。LLWiki一般使用這個方法取代window.alert()或OO.ui.alert()。
方法mw.notify(message, options)接受兩個參數。第一個必需參數message指定通知內容,可以是字符串、HTML元素對象或元素對象數組、jQuery對象或mw.message對象;第二個可選參數options則指定自定義選項,是一個JS對象。
options中可自定義的選項有:
  • autoHide:布爾值,決定通知是否會自行消失。默認為true
  • autoHideSeconds:如果啟用了autoHide(如默認情形),則指定通知自行消失的時間。默認為'short'(5秒),可以指定為'long'(30秒)。
  • tag:字符串,指定通知的標籤,類似於HTML的ID。如果發送多個擁有同一個tag的通知,會導致之前的通知被後來的在原位覆蓋。
  • title:標題。如果指定,則會於內容上方加粗顯示。
  • type:字符串,指定通知的種類。除默認效果外其他可選類型為'success''warn''error'
mw.now()
這個方法理論上和Date.now()差不多,但實際測試表明和Date.now()的取值不同,因此請勿混合使用。非必需,基本可以完全被Date.now()替換。
mw.messages
用於改善代碼結構,在代碼開頭使用mw.messages.set()方法結合wgULS()和wgUCS()設置自定義消息的繁簡名稱,然後使用mw.msg()方法即可調用。使用這一方法時,還能以$1的形式設置待定參數,或使用部分解析器函數。

jquery

jquery是任何頁面都會預加載的兩個環境模塊之一,尤其在DOM操作和Ajax請求方面功能強大,非常推薦在JS編程之前預先熟悉API文檔。考慮到mw.loader已經集成了不少的常用Ajax方法,這裡主要推薦熟練掌握DOM相關的內容,包括事件DOM操作選擇器遍歷。特別需要提醒的是濫用htmlString有造成XSS的風險,因此請儘量使用如$('<p>', {html: $('<a>', {text: '文字', href: 'https://llwiki.org'})})$('<p>').append( $('<a>').text('文字').attr('href', 'https://llwiki.org') )等語法進行規避。

因未被mw.loader包含而可能用到的Ajax方法主要為$.getJSON(),需要注意在MW的默認設置下調用jQuery的Ajax方法必須手動設置{cache: true}

另外jQuery也提供了一些工具方法,可以用於緩解ResourceLoader的JS模塊不允許使用ES6語法的問題,或是方便鍵值對相關的語句的書寫,或是方便連鎖。比如用$.extend()方法代替...算符、用$.each(obj, (key, val) => {})方法代替for (const key in obj) {}等。

應用jQuery時可能出現的一些常見錯誤列舉如下:

  • 混淆.attr()方法和.prop()方法。
  • 混淆jQuery對象的.data()方法和HTML元素的.dataset屬性。
  • 使用.toggle().fadeToggle()等方法時不慎破壞較複雜的CSS布局。
  • 錯誤使用.remove().clone()等方法造成丟失數據和事件處理程序。
  • 混淆event.targetevent.currentTargetevent.delegateTargetthis關鍵字。
  • 混淆$.when()方法和Promise.all()方法的參數格式和回調函數。

mediawiki.api

這個模塊提供了一系列方法用於簡化API請求。使用這一模塊時,需要首先建立一個mw.Api對象,常用語法為const api = new mw.Api();。以下列舉這個mw.Api對象常用的方法,沒有出現在以下列表中的方法可能不僅是不推薦使用,而是因為未適配中文的繁簡轉換而不應在LLWiki使用。

  • api.get(),這是最基礎的兩個方法之一,用於提交類型為GET的Ajax請求,參數基本與api.php的參數一致,區別在於返回的格式已經限定為JSON對象,即可省略參數{action: 'query', format: "json"}。API請求的參數列表詳見API文檔,這裡特別推薦一下generator參數[8]的強大功能和{formatversion: 2}這個參數。
  • api.post(),這是最基礎的兩個方法之一,用於提交類型為POST的Ajax請求,用法與api.get()方法高度相似。一般情形下,{action: 'query'}的請求應該使用api.get()方法以充分利用瀏覽器緩存等優點;但如果請求的數據量過大,可能不得不使用api.post()方法代替。
  • api.postWithToken(),提交改動時一般使用這個快捷方法而非傳統的api.post(),但在很多情形下都可以替換為下述更為方便的方法,只有用於{action: 'patrol'}時難以替代。
  • api.postWithEditToken(),相當於api.postWithToken('csrf', params),主要用於提交編輯。大部分情況下不推薦使用api.edit()方法替代,因為api.edit()在大多數應用場合會造成重複而不必要的{action: 'query', prop: 'revisions'}請求。為了避免編輯衝突,在LLWiki請儘可能使用mw.safeEdit()方法。另外在建立新頁面({createonly: 1}或直接應用api.create()方法)時,請務必先檢查對應的繁簡中文標題是否已經存在。
  • api.newSection(),這個方法相比api.postWithEditToken()可以進一步簡化添加新章節的代碼。
  • api.rollback(),相當於api.postWithToken('rollback', params),用於回退。
  • api.watch(),相當於api.postWithToken('watch', params),用於監視。
  • api.unwatch(),相當於api.postWithToken('watch', params),用於取消監視。
  • api.upload(),相當於api.postWithEditToken()的{action: 'upload'}。注意這個方法只能上傳本地文件,需要通過url上傳的請使用api.postWithEditToken()方法。
  • api.parse(),用於解析HTML的快捷方法,常用於生成預覽。如果要獲得現存頁面的HTML,還需要加載mediawiki.Title,此時建議可以直接使用標準的api.get()方法代替。

mediawiki.util

mediawiki.util提供了很多非常方便的方法,可以用於滿足形形色色的需要。這個模塊會在加載很多其他模塊時加載,如mediawiki.api、mediawiki.Title和mediawiki.Uri等。

  • mw.util.addCSS(),相比mw.loader.addStyleTag()方法,因為返回值是一個StyleSheet對象而更便於後續動態操作。
  • mw.util.addPortletLink(),實際上並不如直接使用jQuery自由度更大,但這個方法可能會出現在一些從其他維基導入的小工具里,不推薦使用。
  • mw.util.debounce(),這個方法用於降低一個函數被調用的頻率,常見的比如scroll事件。
  • mw.util.escapeRegExp(),mw.util還有其他的轉義方法[9],但應用較少,不再贅述。
  • mw.util.getParamValue(),提取php參數,能夠滿足可能存在的各種奇怪情形,不建議使用自己寫的正則匹配替代。
  • mw.util.getUrl(),獲取頁面對應的相對網址,一般來說使用mw.config.get('wgScript') + '/' + pageName即可。但如果頁面名稱中含需要轉義的字符(如?&),使用這個方法還是挺方便的。
  • mw.util.wikiUrlencode(),非常好用的方法,相比encodeURIComponent不會轉義:/,相比encodeURI則增加了對?&的轉義,是轉義頁面名稱的最佳選擇,同時在用做url時也比mw.util.getUrl()方法有更大的自由度。

mediawiki.Uri

除了可以替代mw.util.getParamValue()方法用於獲得URI的各項參數,mediawiki.Uri還可以方便地修改或生成URI。使用時首先需要應用const uri = new mw.Uri(str, options);語法來構建一個mw.Uri對象,強烈推薦在options中設置{overrideKeys: true}以免後續出現未預期的JS語法錯誤。

  • uri.fragment,獲得#後的章節名。
  • uri.host,在LLWiki總是為'llwiki.org'
  • uri.path,在LLWiki的內容頁面一般總是為'/zh''/mediawiki/index.php'(兩者等效)。
  • uri.protocol,在LLWiki總是為'https'
  • uri.query,包含了所有php參數的JS對象,在規定了{overrideKeys: true}時每個值都是字符串,否則重複參數的值為數組。
  • uri.clone(),複製mw.Uri對象。
  • uri.extend({key: value}),添加或覆蓋php參數,這在URI以#結尾時非常方便。如果需要刪除php參數的話,可以直接使用delete uri.query.param的語法。
  • uri.getQueryString(),獲得整個php請求字符串。
  • uri.getRelativePath(),獲得相對地址。
  • uri.toString(),獲得包含協議的絕對地址。

mediawiki.Title

徹底解決關於頁面名稱或文件名稱的各種煩惱,包括大小寫、空格/下劃線、命名空間別名等等。通常用法為先使用const title = new mw.Title(str);的語法構建一個mw.Title對象。與mw.util的很多方法以及new mw.Uri()不同,new mw.Title(str)不會以當前頁面作為默認參數。因為未統一大小寫、空格/下劃線等,請勿直接訪問title.title屬性,而是根據需要使用下列方法。

  • title.getExtension(),獲取文件名的擴展名。
  • title.getFragment(),如果頁面名稱中含#,獲取章節名。也可以直接使用title.fragment屬性訪問。
  • title.getMain(),獲取頁面名,首字母大寫,空格替換為下劃線。
  • title.getMainText(),獲取頁面名,首字母大寫,下劃線被替換為空格。
  • title.getName(),獲取文件名,不含擴展名,首字母大寫,空格替換為下劃線。
  • title.getNameText(),獲取文件名,不含擴展名,首字母大寫,下劃線替換為空格。
  • title.getNamespaceId(),獲取命名空間,能識別一切別名。也可以直接使用title.namespace屬性訪問。
  • title.getNamespacePrefix(),獲取標準命名空間前綴,含:
  • title.toString(),獲取完整頁面名稱,命名空間使用標準前綴,不含#,空格替換為下劃線。
  • title.toText(),相比title.toString()方法,下劃線替換為空格。
  • title.getRelativeText(nsid),相比title.toText()方法,會命名空間編號匹配時移除命名空間前綴。
  • title.getSubjectPage(),生成討論頁對應的主頁面的mw.Title對象。
  • title.getTalkPage(),生成對應的討論頁的mw.Title對象。
  • title.getUrl(),生成地址,可以添加JS對象格式的php參數。
  • title.isTalkPage(),是否是討論頁。

此外,mediawiki.Title還有一些靜態方法用於生成mw.Title對象。

  • mw.Title.makeTitle(nsid, title),給定命名空間編號和標題生成對象。不存在的命名空間會報錯。僅當命名空間為0時,會根據標題生成正確的命名空間。
  • mw.Title.newFromFileName(filename),給定文件名生成對象。
  • mw.Title.newFromImg(node),給定<img>節點或對應的jQuery對象生成mw.Title對象。
  • mw.Title.newFromText(title, nsid),相比mw.Title.makeTitle()方法,錯誤的命名空間編號也不會報錯,且當標題含命名空間前綴時總是覆蓋第二個命名空間參數。

mediawiki.storage

mediawiki.storage提供了處理localStorage或sessionStorage的便利方法。注意出於安全性的考慮,請勿使用localStorage存儲用戶的個人信息。mw.storage對象對應localStorage,mw.storage.session對象對應sessionStorage,這兩個對象擁有相同的方法,所以以下只介紹mw.storage對象。

  • mw.storage.get(),相當於localStorage.getItem()方法,所以使用價值不高。
  • mw.storage.set(),相當於localStorage.setItem()方法,所以使用價值不高。
  • mw.storage.remove(),相當於localStorage.removeItem()方法。
  • mw.storage.getObject(),相當於JSON.parse( localStorage.getItem(key) )
  • mw.storage.setObject(),相當於localStorage.setItem(key, JSON.stringify(value))

user.options

用於方便地獲取用戶設置。

  • mw.user.options.values,存儲了所有用戶設置。
  • mw.user.options.get()方法,用於獲取特定用戶設置。比如想獲取用戶有無啟用某一小工具,可以使用mw.user.options.get( 'gadget-name' )方法。如果不想加載user.options模塊,也可以使用['loaded', 'loading', 'ready'].includes( mw.loader.getState( 'ext.gadget.name' ) )代替,但兩者會因手動加載小工具(如mw.loader.load( 'ext.gadget.name' )或在手機版檢查僅在桌面版註冊的小工具而產生差異。

下表整理了一些JS中常用的用戶設置,完整列表請參閱MediaWiki

設置名 說明
date 日期格式
timecorrection 時區
multimediaview-enable 啟用媒體查看器
diffonly 差異下方不顯示頁面內容
norollbackdiff 回退不顯示差異
showhiddencats 顯示隱藏分類
numberheadings 標題自動編號
showrollbackconfirmation 回退確認
editsectiononrightclick 右鍵段落編輯
editondblclick 雙擊編輯
minordefault 默認小編輯
useeditwarning 提示未保存的編輯
usebetatoolbar 使用WikiEditor的增強工具欄
previewontop 在編輯框上方顯示預覽
uselivepreview Ajax預覽
extendwatchlist 監視列表顯示所有更改
rcenhancedfilters-disable 禁用最近更改過濾器
wlenhancedfilters-disable 禁用監視列表過濾器

jquery.makeCollapsible

用於摺疊.mw-collapsible類,使用語法非常簡單。

jquery.tablesorter

用於table.sortable的排序,使用語法非常簡單。

jquery.textSelection

用於快速處理textarea相關的操作。比如CharInsert擴展就是主要基於這個模塊開發的。

  • textSelection(command, [options])方法,以下所有指令均藉助這一方法執行。
  • 'encapsulateSelection',在選中的文字前後插入文字。
  • 'getCaretPosition',獲取光標位置。
  • 'getSelection',獲取選中文字。
  • 'replaceSelection',替換選中文字。
  • 'scrollToCaretPosition',滾動到光標位置。
  • 'setSelection',設置選中區域。

jquery.client

用於查詢用戶設備和瀏覽器的相關信息,相比直接使用navigator,這個模塊使用起來更加簡便和友好。這個模塊會在加載mediawiki.util時加載。

  • const profile = $.client.profile();,以對象的形式輸出設備和瀏覽器信息。
  • profile.platform,可識別的設備類型:iphone、linux、mac、win。
  • profile.name,可識別的瀏覽器類型:android、chrome(包括手機chrome、edge、opera等)、iphone、edge(舊版edge)、firefox(包括手機firefox)、opera(舊版opera)、safari等。
  • profile.layout,可識別的引擎類型:edge、gecko、konqueror、opera、trident、webkit。

jquery.color

可以進行CSS顏色的十六進制、RGB和HSL的轉換或計算亮度,但因為這個模塊在手機版未註冊,請謹慎使用。如確有必要在手機版調用此模塊,請聯繫有後台訪問權限的管理人員。

jquery.ui

jquery.tipsy

用於統一tooltip的顯示樣式,使用語法非常簡單,同時效果也相比一些瀏覽器的默認行為更加美觀和醒目。然而這個模塊並未在手機版註冊,同時對窄屏的適配也欠佳,因此請替換為mw.tipsy()方法

jquery.chosen

用於將select元素轉化爲combo box,語法非常簡單,但該模塊未在手機版註冊,請替換為OO.ui.ComBoxInputWidget對象。

jquery.confirmable

用於以內聯形式添加一個確認步驟,需要根據使用場所調整需要的CSS,也因此用起來相對繁瑣。另外這個模塊也未在手機版註冊,請替換為mw.confirm()方法

oojs-ui-core

對於各種用於用戶交互的HTML元素,如<button>、<select>、<input>等,不同瀏覽器往往會默認添加不同的樣式。為了統一這些表單元素的外觀,MediaWiki的界面UI大多基於OOUI設計,oojs-ui-core則包含了OOUI的最基本元素。這些元素往往藉助<div>等基本HTML元素和CSS/JavaScript模擬出表單元素的效果。下表列出oojs-ui-core中供直接使用的對象實例:

對象實例 說明
ActionFieldLayout 包含一個輸入元素、一個按鈕和一個可選的幫助信息
ButtonGroupWidget 可包含一組ButtonWidget
ButtonInputWidget 用於FormLayout的按鈕
ButtonWidget 最基礎的按鈕
CheckboxInputWidget 複選框,最好置於設置為{align: 'inline'}的各種layout內
CheckboxMultiSelectInputWidget 用於FormLayout的真正意義上的「複選框」
CheckboxMultiSelectWidget 真正意義上的「複選框」
ComboBoxInputWidget 既可鍵盤輸入,又可選擇選項
DecoratedOptionWidget 用於SelectWidget的帶圖標的選項
DropdownInputWidget 用於FormLayout的下拉選單
DropdownWidget 下拉選單
FieldLayout 包含一個輸入元素和標籤或幫助信息
FieldSetLayout FieldLayout的組合
FormLayout 用於構建表單
HorizontalLayout 行內樣式的layout
HtmlSnippet 用於插入htmlString
IconWidget 圖標
IndicatorWidget 另一種小圖標
LabelWidget 標籤
MultilineTextInputWidget 相當於textarea
NumberInputWidget 帶增減按鈕的輸入僅限數字的文本框,由min/max/step/required設置代替validate設置
PanelLayout 占據整個父容器的layout
PopupButtonWidget PopupWidget的開關
PopupWidget 相當於tooltip
ProgressBarWidget 進度條
RadioInputWidget 一個單獨的單選框,一般下不應使用
RadioSelectInputWidget 用於FormLayout的單選框
RadioSelectWidget 單選框
SearchInputWidget 搜索框
SelectFileInputWidget 上傳本地文件,不可拖拽
TextInputWidget 文本框

oojs-ui-windows

oojs-ui-windows在oojs-ui-core的基礎上補充了各類對話框及相關元素。下表列出了oojs-ui-windows添加供直接使用的對象實例:

對象實例 說明
ActionWidget 用於對話框的按鈕
Dialog 最基礎的對話框,所有對話框均必須使用WindowManager打開,且大部分無法直接使用
MessageDialog 消息對話框,唯一一種可直接使用的自定義對話框
ProcessDialog 進程對話框,無法直接使用
WindowManager 用來打開各種對話框
OO.ui.alert() 相當於window.alert(),但手機版的CSS設計有缺陷,請使用mw.notify()方法替代
OO.ui.confirm() 相當於window.confirm(),但返回的是Promise對象
OO.ui.prompt() 相當於window.prompt(),但返回的是Promise對象

oojs-ui-widgets

oojs-ui-widgets在oojs-ui-core的基礎上補充了一些更複雜的元素。下表列出了oojs-ui-widgets添加供直接使用的對象實例:

對象實例 說明
BookletLayout 左側分頁布局
ButtonMenuSelectWidget 點擊按鈕展開下拉選單
ButtonSelectWidget 使用按鈕的單選框
IndexLayout 分頁
MenuLayout 同時包含了菜單和內容
MenuTagMultiselectWidget 使用菜單進行多選
PopupTagMultiselectWidget 使用氣泡輸入的多選
SelectFileWidget 選擇文件
StackLayout 堆疊布局
TagMultiselectWidget 使用文本輸入生成標籤多選,是MenuTagMultiselectWidget和PopupTagMultiselectWidget的基礎類型
ToggleButtonWidget 使用按鈕開關
ToggleSwitchWidget 開關

mediawiki.widgets

LLWiki添加的全局變量和方法

window.wgULS(hans, [hant])window.wgUCS(hans, [hant])[10]
用於處理繁簡文字信息,wgULS()用於界面語言,wgUCS()用於內容語言。為方便維護,在大量使用繁簡轉換的頁面,請將所有繁簡文字以mw.messages.set()方法的形式至於代碼開頭,然後在使用時以mw.msg()方法調用即可。
mw.gadgets
這個對象儲存了所有小工具的設置。
mw.request
這個對象儲存了一個mw.standardQuery()方法返回的Promise對象,即獲取當前版本全文Wikitext的API請求。
mw.sections
這個數組的每一項對應一個mw.sectionQuery()方法返回的Promise對象,即獲取對應段落Wikitext的API請求。
mw.widget
這個對象儲存了小部件的執行情況,防止Ajax預覽造成小部件重複執行。
mw.settingsDialog[11]
這個對象是一個SettingsDialog類,用於小工具設置的圖形界面。這個類提供了多種方法,包括:獲取小工具名稱(getName)、獲取小工具對象(getObject)、獲取小工具標籤頁(getPanel)、添加小工具(addTab)、生成設置對象(generateOptions)、將設置保存到localStorage(saveOptions)、還原設置(clearOptions)和導出設置(export)。用法複雜,詳見代碼頁
mw.pagenamee()[10]
這個方法用於獲取轉義後的當前頁面名稱。需要mediawiki.util。
mw.addMobileLinks(link)[10]
這個方法生成手機版菜單需要的列表構成的數組,可以隨後加入DOM中。link為對象或對象數組,每一項包含連結地址href(可選)、FontAwesome圖標icon(默認為圓圈包裹的一個向右箭頭)、文字信息text(需要手動設置繁簡轉換,優先級低於msg)或mw.messages的鍵值msg和<li>元素屬性attr(可選)。
mw.isModule(name, [flag])[10]
這個方法用於檢測一個模塊是否正在或已經加載。name為模塊名或小工具名;flag為真時自動在小工具名name前添加前綴'ext.gadget.'
mw.apiFailure(reason, topic)[10]
這個方法用於輸出一個API請求失敗的氣泡通知。reason為API返回的錯誤信息,一般來自狀態為reject的API請求;topic為簡短的文字說明,需要手動設置繁簡轉換。
mw.timedQuery(api, params, topic)[10]
這個方法用於提交一個可自定義的API請求,並記錄用時,失敗時應用mw.apiFailure()方法生成氣泡通知並拋出錯誤。api為一個mw.Api對象;params即API參數,默認已填入{action: 'query', formatversion: 2},可以覆蓋;topic為簡短文字描述,需要手動設置繁簡轉換。需要mediawiki.api。
mw.timedParse(api, params, topic)[10]
Ajax使用POST而非GET,因此適合預覽大段Wikitext。params的默認設置為{action: 'parse', prop: 'text', title: mw.config.get( 'wgPageName' ), disablelimitreport: 1, disableeditsection: 1, pst: 1, formatversion: 2},可以覆蓋。填入page、pageid或oldid參數時請勿使用此方法,應當選用包含{action: 'parse'}參數的mw.timedQuery()。topic同樣需要手動設置繁簡轉換。需要mediawiki.api。
mw.standardQuery(api)[10]
使用mw.timedQuery()方法提交一個API請求以獲取當前版本的全文Wikitext並保存至mw.request。需要mediawiki.api。
mw.sectionQuery(api, section, [force])[10]
使用mw.timedQuery()方法提交一個API請求以獲取段落Wikitext並保存至mw.sections。section為段落編號,默認為序言;為降低錯誤編輯歷史版本的風險,想要獲取歷史版本的段落Wikitext時,必須手動添加為真的force參數。需要mediawiki.api。
mw.safeEdit(api, curRevid, params, [flag])[10]
檢查有無編輯衝突後提交編輯。api為mw.Api對象;curRevid為當前最新版本的編號,默認為mw.config.get( 'wgCurRevisionId' );parmas為API參數,默認為{action: 'edit'},可以覆蓋,但原則上請勿使用這一方法執行其他操作;flag參數對應是否開啟自動備份小工具,這會改變檢測到編輯衝突時的錯誤通知。檢測到編輯衝突拋出錯誤'editConflict',API請求失敗拋出錯誤'editFailure''revisionQueryFailure'。需要mediawiki.api。
mw.safeRedirect(api, title, target, [summary])[10]
檢查繁簡轉換後的頁面是否已經存在後創建新重定向。api為mw.Api對象;title為重定向頁標題;target為重定向目標頁標題,默認為當前頁面;summary為可選摘要。頁面已存在時拋出'pageExists',API請求失敗時拋出'createFailure''queryFailure'。需要mediawiki.api。
mw.confirm(text, [flags])[10]
藉助OO.ui.confirm()方法生成一個確認對話框。text為確認提示,可以是字符串或jQuery;flags為確認鍵的樣式數組,可選元素包括'primary''progressive''destructive',其中'primary'不能單獨生效。返回值為一個狀態為resolve的Promise對象,值為真表示確認。需要oojs-ui-windows。
mw.prompt(text, [flags], [config])[10]
藉助OO.ui.prompt()方法生成一個prompt對話框。text為文字提示,可以是字符串或jQuery;flags為確認鍵的樣式數組,可選元素包括'primary''progressive''destructive',其中'primary'不能單獨生效;config為可選的文本框設置。返回值為一個狀態為resolve的Promise對象,值為null表示取消。需要oojs-ui-windows。
mw.dialog(dialog, actions, $message, [$title])[10]
藉助OO.ui.MessageDialog對象生成一個更複雜的對話框。dialog為預先準備的OO.ui.MessageDialog對象;actions為OO.ui.ActionWidget對象構成的數組;$message為提示信息,相比mw.confirm()方法的進步之處在於可以使用jQuery或htmlString;$title為對話框標題。返回值為點擊按鈕時的Promise對象。需要oojs-ui-windows。
mw.tipsy($container, [target], [params], [$content])[10]
藉助OO.ui.PopupWidget對象生成一個手機版也有效的tooltip。$container為外部容器的jQuery對象(不能是body);target為目標元素的選擇器;params為建立OO.ui.PopupWidget對象時的參數,默認為{padded: true, width: null, classes: ['mw-tipsy']},可以覆蓋;$content為自定義的tooltip內容,默認為title或data-title屬性。需要oojs-ui-core。
mw.menu(options, [config], [unselectable])[10]
藉助於OO.ui.MenuSelectWidget生成一個浮動菜單。options為選項數組,每一項包含文本text(需要手動設置繁簡轉換)、FontAwesome圖標icon(可選)、數據data(可選)、連結href(可選)和點擊事件click(可選);config為菜單設置,默認為{classes: ['site-menu'], hideWhenOutOfView: false},可以覆蓋;unselectable為真時,菜單不會保留之前最後一次的選擇記錄。這個UI方法的用法較為複雜,詳見代碼頁
mw.convertTimezone(then, timezone)[10]
改變moment對象的時區。then為待處理的moment對象,默認為現在;timezone為時區的IANA名稱或數值表示的UTC偏移量,需要提前檢查合法性,默認為本地時區。注意這個方法的返回值不是一個真實存在的時間點,只能用於輸出而不能用於進一步運算。需要moment。
mw.resizeLyrics()[12]
重新計算.Lyrics_box的大小,並調整原文和譯文的排列方式。

JSHint

CodeEditor使用JSHint標註可能存在的語法問題。LLWiki會在大部分JS頁面添加JSHint設置/* global mw *//* jshint jquery: true, bitwise: true, curly: true, latedef: 'nofunc', nonew: true, singleGroups: true, unused: true */[13]。但在小部件頁面,為了提示小部件JS加載在模塊mediawiki和jquery之前,/* global mw *//* jshint jquery: true */被替換為/* jshint varstmt: true */。注意JSHint並不會對大多數JS模塊不允許使用的ES6語法作出警告(詳見#ResourceLoader和JS模塊),因此請勿過度依賴這一功能來除錯。另外CodeEditor安裝的JSHint版本較老,無法識別ES7以上的語法,因此在代碼中使用ES7語法可能會造成除錯時的困難。

注意事項

手機版

手機版解析器

圖片懶加載

手機版CSS

手機版LLWiki使用Minerva Neue皮膚,與桌面版的Vector皮膚相比,不僅界面有很大差異,眾多基礎HTML元素也都添加了不同的CSS樣式。為了適配窄屏設備,Minerva皮膚還添加了大量基於@media的規則,一般以設備寬度720px為分界使用不同的樣式。以下著重介紹<table><img>這兩種需要CSS修正的重災區。

手機版CSS很多時候依賴外層容器的content類來生效,與此同時#mw-content-text .mw-parser-output的外層結構也同樣有效,設計各種基於API的快速編輯工具(如Wikiplus等)的預覽界面時需要考慮。

表格

對於<table>元素及其子節點,手機版已知會自動添加以下樣式:

table, caption, tbody, tfoot, thead, tr, th, td {
	font-size: 100%;
}
table {
	border-collapse: collapse;
}
.content table {
	margin: 1em 0;
	overflow: auto;
	overflow-y: hidden;
	overflow-x: auto;
}
@media only screen and (max-width: 720px) {
	.content table {
		display: block;
		width: 100% !important;
	}
}

這裡重點說明一下第二和第四條規則造成的影響。第二條規則使得表格的外層邊框、行邊框和單元格邊框合併,可能造成一系列關於邊框的CSS規則出現不符合預期的表現,尤其是<table>cellspacing屬性會無法生效。因此一般建議避免使用cellspacing這一HTML屬性,改為使用CSS中的border-spacing。另外,在需要border-spacingborder-radius等樣式時,請同時指定border-collapse: separate;以使手機版生效。

第四條規則的本意是在窄屏上<table>元素不會將頁面撐得過寬,但這同時會造成外層的<table>和內層的<tbody>分離。特別是如果外層<table>規定了邊框或背景色時,很容易看出樣式的錯誤。為此一般需要主動指定display: table;以修復這一問題,LLWiki有很多預定義的表格CSS類也都添加了這一規則[14]。但這樣修改的話又會重新面臨過寬的表格將整個頁面撐大的問題。LLWiki現定義了table-wrapper[14],用於套在寬表格外:<div class="table-wrapper">,這個外層容器會在窄屏上通過overflow-x: auto;限制裡面的表格寬度。

圖片

皮膚界面

其他

手機版JS

手機版JS模塊

繁簡轉換

Wikitext繁簡轉換

轉換表

Template:NoteTA

基本手工轉換語法

系統消息

CSS繁簡轉換

JS繁簡轉換

濫用過濾器

測試帳戶

如果管理員需要一個沒有自確權限的測試帳戶用於濫用過濾器測試、小工具測試等,可以臨時啟用6號濫用過濾器來移除某個測試帳戶的自確權限。這個濫用過濾器的使用語法非常簡單,請根據樣例修改為對應的用戶名即可,這裡不再贅述。

參考資料

  1. const可用。
  2. 2.0 2.1 2.2 2.3 2.4 ES7以上語法雖然在不作為ResourceLoader的模塊時允許使用,但因為CodeEditor安裝的JSHint版本不支持語法分析,可能會造成代碼除錯時的困難。
  3. 注意$.extend()方法與另兩者並不完全一致,但更推薦使用$.extend()。
  4. MW:ResourceLoader/核心模塊
  5. 完整列表
  6. 完整參數列表
  7. 移動前端的擴展說明
  8. API文檔(action = query)
  9. mw.util文檔
  10. 10.00 10.01 10.02 10.03 10.04 10.05 10.06 10.07 10.08 10.09 10.10 10.11 10.12 10.13 10.14 10.15 10.16 需要加載site-lib.js
  11. 需要加載SettingsDialog.js
  12. 需要加載Widget:Lyrics
  13. 新版JSHint的設置列表,注意可能存在的版本差異。
  14. 14.0 14.1 全站CSS