0

我正在尝试创建一个 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 部分?

4

2 回答 2

1

如果没有 JavaScript,您尝试做的事情几乎是可能的,但不完全是。

尝试#1:正常标题

首先,直接== Hello World ==从 Scribunto 不起作用的原因是您在 Scribunto 中生成的 wikitext 不会由 MediaWiki 解析器自动预处理。来自Scribunto 文档

模块函数通常应该返回一个字符串;返回的任何值都将通过 tostring() 传递,然后不带分隔符连接。该字符串作为{{#invoke:}}.

在页面解析的这一点上,模板已经被扩展,解析器函数和扩展标签已经被处理,并且预保存转换(例如签名波浪号扩展和管道技巧)已经发生。因此,模块不能在其输出文本中使用这些功能。例如,如果一个模块返回"Hello, [[world]]! {{welcome}}",页面将显示“Hello, world ! {{welcome}}”。

为了解决这个问题,您可以使用 Scribunto 的frame:preprocess方法在输出字符串之前使用 MediaWiki 解析器对字符串进行预处理。例如,预处理== Hello World ==将向解析器注册标题,并在标题标题前添加一个带标记。然后在解析过程的后期,解析器删除条形标记并添加编辑部分链接。

您可以使用以下模块代码执行此操作:

local p = {}

function p.main(frame)
    return frame:preprocess("== Hello World ==")
end

return p

当在 wiki 页面上调用时,此代码将为您提供合法的 MediaWiki 编辑链接。不幸的是,它是模块页面第一部分的链接,点击它会给你一个“不支持部分编辑”的错误。

您可以通过使用不同的框架对象进行预处理来解决这个问题。如果您希望编辑部分链接指向您从中调用模块的页面,您可以使用父框架

local p = {}

function p.main(frame)
    return frame:getParent():preprocess("== Hello World ==")
end

return p

如果您希望链接指向任意页面,您可以创建一个新的子框架

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 不允许<a>wikitext 中的标签来防止跨站点脚本攻击。[http://www.example.com Example]您可以使用 MediWiki 的外部链接语法 ( )轻松解决此问题。

这是更接近您的目标的东西:

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. “[编辑]”文本包含在目录中。

不幸的是,我不知道有一种方法可以在不使用 JavaScript 的情况下将“[edit]”文本保留在目录之外。因此,唯一能够可靠工作并使一切看起来正确的解决方案是像您所做的那样使用 JavaScript。

于 2017-05-02T13:43:17.460 回答
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;
});
于 2016-07-12T19:17:24.213 回答