用户:37664861
MediaWiki模板
请勿删除本页面
该页面包含一些未完工的模板
而且可以通过历史版本查看以前的代码
一些工具
参考代码
模板
模板使用
{{赛马娘窗体|CSS初始化}} {{赛马娘窗体|开始|标题=这是绿色窗体|宽=50%|高=auto|颜色=绿}} {{赛马娘窗体|结束}}
模板建立
<noinclude> <pre> {{带星头像|102701}}{{带星头像|104501}}<br>{{带星头像|103801}} <//pre> {{带星头像|102701}}{{带星头像|104501}}<br>{{带星头像|103801}} </noinclude> <includeonly><div style="margin:0px 75px 65px 0px;display:inline-block;"><div style="position:absolute;">[[文件:Chr_icon_{{padleft:|4|{{{1}}}}}_{{{1}}}_01.png|72px|link=]]</div><div style="position:absolute;overflow:hidden;">[[文件:Star_{{#ask:[[分类:赛马娘]][[ID::{{{1}}}]]|?初始星级|headers=hide|mainlabel=-}}_mask.png|72px|link=]]</div></div></includeonly>
禁止模板页面生效
编写模板时,部分标记会在“模板:xxx”的页面也生效,可通过判断名字空间的方法,使其仅在主空间生效。
{{#ifeq: {{NAMESPACENUMBER}} | 0 | 【要在主空间生效的代码】 | }}
禁止重复加载
可以使用判断变量是否已定义的方法来保证某个功能(如CSS)在模板被多次调用时只生效一次。
{{#if: {{#varexists: 定义的变量}} | |{{#vardefine: 定义的变量| 0 }}【只加载一次的内容】}}
解析函数
形如{{#函数名:参数1|参数2|...}}
称为解析函数,所有的解析函数可在特殊:版本中的“解析器函数钩子”中找到。
常用解析函数
以下解析函数在构建模板时常常用到
#ask
{{#ask:[[分类:赛马娘]][[觉醒材料1::长距离]]|link=none}} {{#ask:[[分类:赛马娘]][[初始星级::3]]|?ID|headers=hide|mainlabel=-}}
#if
{{#if: 测试字串 | 字串非空输出值 | 字串空(或只有空白字符)输出值 }}
#ifeq
{{#ifeq: 测试字串1 | 测试字串2 | 相同时输出值 | 不相同时输出值 }}
#switch
{{#switch: 比较字串 | 情况字串1 = 返回结果1 | 情况字串2 = 返回结果2 | ... | 情况字串n = 返回结果n | 默认结果 }}
更全解析函数用法
https://wiki.biligame.com/wiki/%E5%B8%AE%E5%8A%A9:%E8%A7%A3%E6%9E%90%E5%87%BD%E6%95%B0
更全版本:https://thwiki.cc/%E5%B8%AE%E5%8A%A9:%E8%A7%A3%E6%9E%90%E5%87%BD%E6%95%B0
SMW
SMW是语义wiki(Semantic MediaWik)的简称,它充当了整个wiki的内部数据库,参见:SMW官网
数据的读取
在wiki中,每个页面都有隐藏的属性,在右上角“WIKI功能”->“浏览属性”中可以查看到当前页面的属性。
例如在页面特殊:浏览/:特别周列出了“特别周”所存储的数据,可以使用#ask或#show解析函数在任意主命名空间的页面下读取其数值。
例如:
解析结果如下:
特别周的三围是:B81·W56·H81
数据的属性
在上述例子中,“三围”为属性名,“B81·W56·H81”为属性值,默认情况下,属性值都是文本类型,即使写的是数字,其也是以文本保存的,这种保存方式会在排序上出现问题。
若要以数值类型,需要在“属性”名字空间下加入声明
例如:在页面属性:友情加成中定义了“友情加成”这个属性是以数值方式存储的。
P.S.如果某属性名下的属性值非常多,在更换数值类型时需要SMW的缓存更新,这一过程十分缓慢,“WIKI功能”->“刷新”中手动更新当前页的属性值。
声明为数值型后,可使用数值筛选:
例如,下述代码查询了友情加成大于35时,以“训练效果提升”和“突破等级”为排序条件,前10张支援卡:
运行结果如下:
支援卡 | 友情加成 | 训练效果提升 | 得意率提升 | 干劲效果提升 |
---|---|---|---|---|
【一粒の安らぎ】スーパークリーク#突破4 | 35 | 15 | 55 | |
【感謝は指先まで込めて】ファインモーション#突破4 | 35 | 15 | 35 | 30 |
【Take Them Down!】ナリタタイシン#突破4 | 35 | 15 | 65 | 20 |
【Cocoon】エアシャカール#突破4 | 35 | 15 | 80 | 30 |
【感謝は指先まで込めて】ファインモーション#突破3 | 35 | 13 | 35 | 15 |
【一粒の安らぎ】スーパークリーク#突破3 | 35 | 13 | 55 | |
【カワイイ+カワイイは~?】マヤノトップガン#突破4 | 35 | 10 | 55 | 20 |
【天嗤う鏑矢】ナリタブライアン#突破4 | 35 | 10 | 55 | 30 |
【駆けよ、駆けよ、駆けよ!!】オグリキャップ#突破4 | 35 | 10 | 50 | |
【緋色の君へ風が吹く】ダイワスカーレット#突破4 | 40 | 10 | 80 | 20 |
...更多结果 |
数据的定义
要定义一个页面的属性,可使用#set函数:
“|+sep=,”表示该属性名具有多个值,并以【,】分割。 注意:使用模板的方式引入#set,也会在引入的界面中生效。
子属性
使用#subobject函数可以定义子属性:
定义子属性可以区分一个页面不同条件下的属性值,例如特殊:浏览/:【日本一のステージを】スペシャルウィーク中具有在不同突破条件下的子属性,每个子属性具有不同的值,例如:特殊:浏览/:【日本一のステージを】スペシャルウィーク-23突破0 和 特殊:浏览/:【日本一のステージを】スペシャルウィーク-23突破1
参考资料
更多关于SMW用法参见:https://thwiki.cc/帮助:SMW
Lua模块
模块创建
模块一般位于Module/模块名字空间,创建以『模块:』为前缀的页面即可创建一个模块。
目前模块仅支持lua语法,详见Scribunto
一个简单的模块模板如下:
local p = {} --p代表包(package)
p["测试"]=function(frame)
local text=frame.args["参数名"]
return text.."的说~"
end
return p
模块调用
在非模块名字空间页面中,可使用#invoke来调用模块,格式为:
{{#invoke:模块名|函数名|参数1名=参数1值|参数2名=参数2值|……}}
例如,将上述模块保存到“模块:测试模块”页面中,在调用时可以这样写:
调用后会产生这样的结果:
你好的说~
模块在调用后整个#invoke会变成调用函数的返回值。上述模块return text.."的说~",因此显示的是传入的参数+的说~。
模块最终的返回结果一定是字符串变量(string)。
模块解析优先级
由于#invoke本身算一种解析函数,因此模块返回的解析函数不能再次被解析。
例如,如果返回的字符串为:
...
return "<div style='color:#FF0000'>特别周</div>{{#show:特别周|?ID}}[[特别周]][[file:Chr_icon_1001_100101_01.png|32px]]"
其产生的结果为:
{{#show:特别周|?ID}}特别周
双括弧加#show构成解析函数,便以字符串的形式返回了,而div标签和双中括号均正常解析。
这是由于解析函数的优先级要低于标签和双中括号,双中括号等需要在解析函数执行之后再进行解析,因此可以正常显示。
wiki解析顺序的优先级一般如下:
普通标签(如<div>)> wiki表格({|...|}) > 双中括号([[...]]) > 双括弧({{..}})> 三括弧({{{...}}})> 特殊标签(如:<pre>)
优先级越高,解析顺序越靠后。
注1:有些机制会使某些特殊的函数看上去不符合上述顺序;
注2:有时候会出现wiki表格无法解析的情况,这是因为{|...|}的判定比较严格,需要按照固定的格式,例如大括弧必须顶格,行之间必须回车等,若不符合其规则便不能成功解析。
在模块中调用解析函数
如果你想在模块中使用解析函数,可以使用frame:callParserFunction方法:
frame:callParserFunction{ name = '#函数名', args = { '参数1', '参数2' } } frame:callParserFunction( '#函数名', { '参数1', '参数2' } )
例如,如果你想使{{#show:特别周|?ID}}在模块中生效,可以这样写:
return "特别周的ID是:"..frame:callParserFunction{name='#show',args={"特别周","?ID"}}
其结果和 特别周的ID是:{{#show:特别周|?ID}} 相同。
在模块中调用模板
可以使用frame:expandTemplate方法在模块中使用模板:
frame:expandTemplate{ title = '模板名', args = { '参数1', '参数2', 参数3名 = '参数3' } }
例如:
return "头像是:"..frame:expandTemplate{ title = '模板:带星头像', args = { '100101' ,稀有度='3'} }
其结果和 头像是:{{模板:带星头像|100101|稀有度=3}} 相同。
模块调试
在模块编辑页的下方,提供了一个可用于调试的控制台,使得在不保存页面的条件下调试代码。
可将以下语句粘贴进该控制台并回车,以对某个参数进行调试:
frame = {}
frame["args"] ={}
frame.args["参数名"]="参数值"
p["函数名"](frame)
减小模块开销
避免重复加载数据
有时一个模块需要大量数据,例如模块:翻译数据库。而且有时这些模块会在一个页面中使用多次。每次{{#invoke:}}都解析这些数据十分耗时。可使用mw.loadData()避免这个问题。
local data1 = mw.loadData( '模块:翻译数据库' ) --一个页面只会加载一次,但从加载的模块返回的值必须是表,不能是函数
local data2 = require('模块:翻译数据库') --每次调用#invoke都会加载,如果数据库大比较耗时
-- 调用数据库数据
local data = data1.text_data_147
避免重复调用
有时,一些值会在页面上多次使用,如果每次都调用#invoke十分浪费资源。此时可以使用#vardefine和#var解析函数来避免。
例如,下列代码生成一个随机数组,并把结果通过#vardefine函数保存在『随机数组』变量中:
local p={}
p["随机数组"]=function(frame)
math.randomseed(tostring(os.time()):reverse():sub(1, 7))
local left=tonumber(frame.args["开始"])
local right=tonumber(frame.args["结束"])
local sum=tonumber(frame.args["个数"])
local num
local random_array = ''
if left > right then
local tmp = right
right = left
left = tmp
end
for i=1,sum do
num = math.random(left,right)
random_array = random_array..","..num
--mw.log("已产生随机数:",num)
end
mw.log("已产生随机数组:",string.sub(random_array, 2))
frame:callParserFunction{name='#vardefine',args={"随机数组",string.sub(random_array, 2)}}
return
end
return p
在调用时只需要使用#var函数即可,不需要再次调用#invoke。
注:上述示例中,如果要生成另外一个不同的随机数组,必须再调用#invoke,并将结果重新保存在另外一个变量名中。
参考资料
官方用户手册:https://www.mediawiki.org/wiki/Extension:Scribunto/Lua_reference_manual/zh
Lua语法:https://www.runoob.com/lua/
Widget
Widget建立
函数:
<script> var 类名 = { 函数名:function (arg) { var Element=document.getElementById(arg["id"]) Element.value = arg["text"] } //调用方法:类名.函数名({id:'控件ID', text:'改变的文本'}); } </script>
控件:
<button name = "<!--{$name|escape:'html'}-->" id = "<!--{$id|escape:'html'}-->" class = "<!--{$class|escape:'html'}-->" style = "<!--{$style|escape:'html'}-->" onclick = "<!--{$onclick|escape:'html'}-->"><!--{$text|escape:'html'}--></button> //一定要带escape,否则会把数据原封不动传到wiki上,包括js脚本。这会使得普通用户可以毫无限制地使用各种js,产生安全隐患。 //调用:{{#Widget:Button|text=あ|class="small_btn"|onclick="c1('あ')" }}
Widget使用
按钮:
{{#Widget:Button|text=あ|class=small_btn|onclick=c1('あ') }}
输入框:
{{#Widget:Input|type=text|id=Text_input|style=width:300px}}
调用函数:
{{#Widget:JsText}} --引入函数类 {{#Widget:Input|type=text|id=testId|style=width:300px}} --创建一个输入框 {{#Widget:Button|text=SetText|class=small_btn|onclick=JsText.setValueById({id:'testId', text:'改变文本'});}} --创建一个按钮,按下时调用JsText的setValueById函数
页面加载完成后再调用函数
jqurey有时需要等待其加载完成,但因加载顺序的问题会使得找不到定义。此时可以用以下widget在页面加载完成后再运行函数:
{{#Widget:页面加载完成后运行函数|function=函数名()}}
Mediawiki API
API沙盒: https://wiki.biligame.com/umamusume/%E7%89%B9%E6%AE%8A:ApiSandbox
JS中使用api
一个简单的调用api创建页面示例
//GET操作,固定函数
function getApi(url,callback=false,callbackE=false){
let ajax=new XMLHttpRequest()
if(!callback){
ajax.open("GET",url,false)
ajax.send()
let json=JSON.parse(ajax.responseText)
return json
}
ajax.open("GET",url)
ajax.send()
ajax.onreadystatechange=function(){
if(ajax.readyState==4){
if(ajax.status==200){
callback(ajax.responseText)
}
else if(ajax.status==404&&callbackE){
callbackE(true)
}
}
}
}
//POST操作,固定函数
function postFdApi(url,fd,callback=false,callbackE=false){
let ajax=new XMLHttpRequest()
if(!callback){
ajax.open("POST",url,false)
ajax.send(fd)
let json=JSON.parse(ajax.responseText)
return json
}
ajax.open("POST",url)
ajax.send(fd)
ajax.onreadystatechange=function(){
if(ajax.readyState==4){
if(ajax.status==200){
callback(ajax.responseText)
}
else if(ajax.status==404&&callbackE){
callbackE(true)
}
}
}
}
// 检查权限
if(mw.config.get('wgUserGroups').indexOf("sysop")==-1){
console.log("你没有管理员权限!")
}
// 设置变量
var UserToken = ""
var Title_OCC = "Sandbox"
var Text_OCC = "This is the second test!"
// 数据
var fd=new FormData()
fd.append("action","edit")
fd.append("title",Title_OCC)
fd.append("summary","Create by API")
fd.append("text",Text_OCC)
fd.append("format","json")
console.log(fd)
// 获取token
getApi("https://wiki.biligame.com/umamusume/api.php?action=query&meta=tokens&format=json",function(json){
let token=JSON.parse(json).query.tokens.csrftoken;
console.log(token)
UserToken = token;
})
//添加token
fd.append("token",UserToken)
//POST
postFdApi("https://wiki.biligame.com/umamusume/api.php",fd,function(json){
console.log(json);
//取得操作结果
let result=JSON.parse(json).edit.result;
console.log(result);
})