使用带编辑链接的Scribunto创建部分

时间:2016-07-12 19:00:29

标签: lua mediawiki mediawiki-extensions scribunto

我正在尝试创建一个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">...&lt;a href="..." title="..."&gt;edit&lt;/a&gt;</span>),并且整个mw-editsection范围包含在TOC文本中。

有没有办法让我在那里获得我的任意编辑链接,或者我是否必须使用无编辑部分的Scribunto部分?

2 个答案:

答案 0 :(得分:1)

你想要做的是几乎可能没有JavaScript,但不完全。

尝试#1:正常标题

首先,简单的== 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添加的部分标题不计入部分计数。因此,除非您知道第一部分是您需要编辑的部分,否则这些链接将不适合您。不幸的是,我不知道如何更改以这种方式生成的编辑链接的部分编号。

尝试#2:假标题

您试图模拟标题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

这将为您提供一个链接到正确位置的标题,看起来几乎与原始标题完全相同。只有两个问题:

  1. 链接颜色略有错误。在MediaWiki中,外部链接的颜色与内部链接略有不同。这里我们使用页面编辑模式URL的“外部”链接,但MediaWiki生成的编辑链接被赋予内部链接颜色。通过明智地使用样式可以解决这个问题,但这留下了第二个问题:
  2. “[edit]”文本包含在目录中。
  3. 不幸的是,我不知道如何在不使用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;
});