我正在尝试创建一个Scribunto模块,除其他外,它可以在其输出中创建一个节头。
如果返回的字符串包含例如== Hello World ==
,则生成的页面会正确显示该部分,甚至包括TOC中的部分。但是,该部分没有编辑部分链接。
在某种程度上,这是可以理解的;该部分实际上并不存在于页面的源代码中。但我希望能够将编辑链接放到该部分内容的来源。我尝试了buildHeader
函数的两个不同版本:
-- version 1:
function p.buildHeader(level, title, page)
local open = '<span class="mw-editsection-bracket">[</span>'
local close = '<span class="mw-editsection-bracket">]</span>'
local link = '<a href="/w/index.php?title='..p.urlsafe(page)..'&action=edit" title="Edit section: '..title..'">edit</a>'
local edit = '<span class="mw-editsection">'..open..link..close..'</span>'
local text = '<span id="'..p.urlsafe(title)..'" class="mw-headline">'..title..'</span>'
return '<h'..level..'>'..title..edit..'</h'..level..'>'
end
-- version 2:
function p.buildHeader(level, title, page)
local result = mw.html.create('h'..level)
result:tag('span')
:attr({id=p.urlsafe(title), class='mw-headline'})
:wikitext(title)
:done()
:tag('span')
:attr('class', 'mw-editsection'):tag('span')
:attr('class', 'mw-editsection-bracket')
:wikitext('[')
:done()
:tag('a')
:attr({href='/w/index.php?title='..p.urlsafe(page)..'&action=edit', title='Edit section: '..title})
:wikitext('edit')
:done()
:tag('span')
:attr('class', 'mw-editsection-bracket')
:wikitext(']')
:allDone()
return tostring(result)
end
在这两种情况下,锚标记的HTML都被转义(例如,<span class="mw-editsection">...<a href="..." title="...">edit</a></span>
),并且整个mw-editsection范围包含在TOC文本中。
有没有办法让我在那里获得我的任意编辑链接,或者我是否必须使用无编辑部分的Scribunto部分?
答案 0 :(得分:1)
你想要做的是几乎可能没有JavaScript,但不完全。
首先,简单的== Hello World ==
无法在Scribunto中运行的原因是您在Scribunto中生成的wikitext不会被MediaWiki解析器自动预处理。来自the Scribunto docs:
模块函数通常应该返回一个字符串;随你 返回的值将通过tostring()然后传递 连接没有分隔符。这个字符串被合并到 wikitext是
的结果{{#invoke:}}
。在页面解析的这一点上,模板已经扩展, 解析器函数和扩展标记已经被处理,并且 预保存变换(例如签名波浪扩展和管道 诀窍)已经发生了。因此模块不能使用这些 输出文本中的功能。例如,如果模块返回
"Hello, [[world]]! {{welcome}}"
,则页面将显示为“Hello,world!{{welcome}}”。
要解决此问题,您可以使用Scribunto的frame:preprocess方法在输出字符串之前使用MediaWiki解析器预处理字符串。例如,预处理== Hello World ==
将使用解析器注册标题,并在标题标题之前添加strip marker。然后在解析过程中,解析器删除条带标记并添加编辑部分链接。
您可以使用以下模块代码执行此操作:
local p = {}
function p.main(frame)
return frame:preprocess("== Hello World ==")
end
return p
在维基页面上调用时,此代码将为您提供合法的MediaWiki编辑链接。不幸的是,它是指向“模块”页面第一部分的链接,单击它将为您提供“不支持部分编辑”错误。
您可以通过使用不同的帧对象进行预处理来解决此问题。如果您希望编辑部分链接指向您从中调用模块的页面,则可以使用parent frame:
local p = {}
function p.main(frame)
return frame:getParent():preprocess("== Hello World ==")
end
return p
如果您希望链接指向任意页面,则可以创建新的child frame:
local p = {}
function p.main(frame)
local childFrame = frame:newChild{title = "Your page here"}
return childFrame:preprocess("== Hello World ==")
end
return p
上述两个示例的问题在于它们都指向页面上的第一部分 - 并且通过#invoke添加的部分标题不计入部分计数。因此,除非您知道第一部分是您需要编辑的部分,否则这些链接将不适合您。不幸的是,我不知道如何更改以这种方式生成的编辑链接的部分编号。
您试图模拟标题HTML实际上非常接近。您遇到的问题是MediaWiki不允许wikitext中的<a>
标记来防止跨站点脚本攻击。您可以使用MediWiki的外部链接语法([http://www.example.com Example]
)轻松解决此问题。
这里的内容更接近你的目标:
local p = {}
function p.makeHeading(title, page)
local result = mw.html.create('h2')
result
:tag('span')
:attr({id = title, class='mw-headline'})
:wikitext(title)
:done()
:tag('span')
:addClass('mw-editsection')
:addClass('plainlinks')
:tag('span')
:attr('class', 'mw-editsection-bracket')
:wikitext('[')
:done()
:wikitext(string.format(
'[%s %s]',
tostring(mw.uri.fullUrl(page, {action = 'edit'})),
'edit'
))
:tag('span')
:attr('class', 'mw-editsection-bracket')
:wikitext(']')
return tostring(result)
end
return p
这将为您提供一个链接到正确位置的标题,看起来几乎与原始标题完全相同。只有两个问题:
不幸的是,我不知道如何在不使用JavaScript的情况下将“[edit]”文本保留在目录之外。因此,唯一能够可靠地工作并使一切看起来正确的解决方案就是使用JavaScript。
答案 1 :(得分:0)
我的工作解决方案(但不是我首选的解决方案)是使用JavaScript插入链接。 buildHeader
函数变为:
function p.buildHeader(level, title, page)
local result = mw.html.create('h'..level)
result:attr('data-source', page):wikitext(title)
return tostring(result)
end
然后,在MediaWiki:Common.js中,我添加:
$('h1[data-source],h2[data-source],h3[data-source],h4[data-source],h5[data-source],h6[data-source]').append(function() {
var source = $(this).data('source'),
title = $(this).text(),
$editsection = $('<span>').attr('class', 'mw-editsection'),
$open = $('<span>').attr('class', 'mw-editsection-bracket').text('['),
$close = $('<span>').attr('class', 'mw-editsection-bracket').text(']'),
$link = $('<a>').attr('title', 'Edit section: ' + title)
.attr('href', '/w/index.php?title=' + source + '&action=edit')
.text('edit');
$editsection.append($open).append($link).append($close);
return $editsection;
});