وحدة:Excerpt/templates
This module is rated as beta, and is ready for widespread use. It is still new and should be used with some caution to ensure the results are as expected. |
Uses Lua: |
This submodule implements the following templates:
- Template:Excerpt — Transcludes part of an article into another article
- Template:Transclude lead excerpt — Transcludes the lead of an article as an excerpt
- Template:Transclude linked excerpt — Transcludes as an excerpt the lead of an article selected randomly from wikilinks on a page
- Template:Transclude list item excerpt — Transcludes as an excerpt the lead of an article selected randomly from list items on a page
- Template:Transclude random excerpt — Transcludes as an excerpt the lead of an article selected randomly from the parameters
- Template:Transclude selected excerpt — Transcludes the lead of a selected article as an excerpt
See the documentation of each template for usage details.
This submodule is specific to the English Wikipedia and is not designed to be reused on other wikis. For the general, abstract, cross-wiki excerpt functionality, see the Module:Excerpt.
Developers
Before saving changes to this module, please preview with:
- Template:Excerpt/testcases
- Template:Transclude lead excerpt/testcases
- Template:Transclude linked excerpt/testcases
- Template:Transclude list item excerpt/testcases
- Template:Transclude random excerpt/testcases
- Template:Transclude selected excerpt/testcases
-- Invocation functions for English Wikipedia templates
-- May not work properly or at all on other wikis
local e = require("Module:Excerpt")
local p = {}
-- Shared invocation function used by templates meant for portals
local function portal(frame, template)
local args = e.parseArgs(frame)
errors = args['errors'] or false -- disable error reporting unless requested
-- There should be at least one argument except with selected=Foo and Foo=Somepage
if #args < 1 and not (template == "selected" and args[template] and args[args[template]]) then
return e.wikiError("noPage")
end
-- Figure out the page to excerpt
local page
local candidates = {}
if template == "lead" then
page = args[1]
page = mw.text.trim(page)
if not page or page == "" then return e.wikiError("noPage") end
candidates = { page }
elseif template == "selected" then
local key = args[template]
local count = #args
if tonumber(key) then -- normalise article number into the range 1..#args
key = key % count
if key == 0 then key = count end
end
page = args[key]
page = mw.text.trim(page)
if not page or page == "" then return e.wikiError("noPage") end
candidates = { page }
elseif template == "linked" or template == "listitem" then
local source = args[1]
local text, source = e.getContent(source)
if not source then
return e.wikiError("noPage")
elseif not text then
return e.wikiError("noPage")
end
local section = args.section
if section then -- check relevant section only
text = e.getSection(text, section)
if not text then return e.wikiError("sectionNotFound", section) end
end
-- Replace annotated links with real links
text = mw.ustring.gsub(text, "{{%s*[Aa]nnotated[ _]link%s*|%s*(.-)%s*}}", "[[%1]]")
if template == "linked" then
for candidate in mw.ustring.gmatch(text, "%[%[%s*([^%]|\n]*)") do table.insert(candidates, candidate) end
else -- listitem: first wikilink on a line beginning *, :#, etc. except in "See also" or later section
text = mw.ustring.gsub(text, "\n== *See also.*", "")
for candidate in mw.ustring.gmatch(text, "\n:*[%*#][^\n]-%[%[%s*([^%]|\n]*)") do table.insert(candidates, candidate) end
end
elseif template == "random" then
for key, value in pairs(args) do
if value and type(key) == "number" then table.insert(candidates, value) end
end
end
-- Build an options array for the Excerpt module out of the arguments and the desired defaults
local options = {
errors = args['errors'] or false,
fileargs = args['fileargs'],
fileflags = e.numberFlags( args['files'] ),
paraflags = e.numberFlags( args['paragraphs'] )
}
-- Select a random candidate and make sure its valid
local text
local candidateCount = #candidates
if candidateCount > 0 then
local candidateKey = 1
local candidateString
local candidateArgs
if candidateCount > 1 then math.randomseed(os.time()) end
while (not text or text == "") and candidateCount > 0 do
if candidateCount > 1 then candidateKey = math.random(candidateCount) end -- pick a random candidate
candidateString = candidates[candidateKey]
if candidateString and candidateString ~= "" then
-- We have page or [[page]] or [[page|text]], possibly followed by |opt1|opt2...
page, candidateArgs = mw.ustring.match(candidateString, "^%s*(%[%b[]%])%s*|?(.*)")
if page and page ~= "" then
page = mw.ustring.match(page, "%[%[([^|%]]*)") -- turn [[page|text]] into page, discarding text
else -- we have page or page|opt...
page, candidateArgs = mw.ustring.match(candidateString, "%s*([^|]*[^|%s])%s*|?(.*)")
end
-- candidate arguments (even if value is "") have priority over global arguments
if candidateArgs and candidateArgs ~= "" then
for _, t in pairs(mw.text.split(candidateArgs, "|")) do
local k, v = mw.ustring.match(t, "%s*([^=]-)%s*=(.-)%s*$")
if k == 'files' then options.fileflags = e.numberFlags(v)
elseif k == 'paragraphs' then options.paraflags = e.numberFlags(v)
elseif k == 'more' then args.more = v
else options[k] = v end
end
end
if page and page ~= "" then
local section = mw.ustring.match(page, "[^#]+#?([^#]*)") -- save the section
text, page = e.getContent(page) -- make sure the page exists
if page and page ~= "" and text and text ~= "" then
if args.nostubs then
local isStub = mw.ustring.find(text, "%s*{{[^{|}]*%-[Ss]tub%s*}}")
if isStub then text = nil end
end
page = page .. '#' .. section -- restore the section
text = e.get(page, options)
end
end
end
table.remove(candidates, candidateKey) -- candidate processed
candidateCount = candidateCount - 1 -- ensure that we exit the loop after all candidates are done
end
end
if not text or text == "" then return e.wikiError("No valid pages found") end
if args.showall then
local separator = args.showall
if separator == "" then separator = "{{clear}}{{hr}}" end
for _, candidate in pairs(candidates) do
local t = e.get(candidate, options)
if t ~= "" then
text = text .. separator .. t
end
end
end
-- If more= then append a link to article for more info
if args.more then
local more = "Read more..." -- default text
if args.more ~= "" then more = args.more end -- use the given text
text = text .. " '''[[" .. page .. "|" .. more .. "]]'''"
end
-- Add a collapsed list of pages which might appear
if args.list and not args.showall then
local list = args.list
if list == "" then list = "Other articles" end
text = text .. "{{collapse top|title={{resize|85%|" ..list .. "}}|bg=fff}}{{hlist"
for _, candidate in pairs(candidates) do
if mw.ustring.match(candidate, "%S") then text = text .. "|[[" .. mw.text.trim(candidate) .. "]]" end
end
text = text .. "}}\n{{collapse bottom}}"
end
return frame:preprocess(text)
end
-- Invocation function used by {{Excerpt}}
local function excerpt(frame)
local args = e.parseArgs(frame)
-- Make sure the requested page exists
local page = args[1] or args.article or args.source or args.page
if not page then return e.wikiError("noPage") end
local title = mw.title.new(page)
if not title then return e.wikiError("noPage") end
if title.isRedirect then title = title.redirectTarget end
if not title.exists then return e.wikiError("pageNotFound", page) end
page = title.prefixedText
-- Define some useful variables
local section = args[2] or args.section or mw.ustring.match(args[1], "[^#]+#([^#]+)")
local tag = args.tag or 'div'
-- Define the HTML elements
local block = mw.html.create(tag):addClass('excerpt-block')
if e.is(args.indicator) then block:addClass('excerpt-indicator') end
local style = frame:extensionTag{ name = 'templatestyles', args = { src = 'Excerpt/styles.css' } }
local hatnote
if not args.nohat then
if args.this then
hatnote = args.this
elseif args.indicator then
hatnote = 'This is'
elseif args.only == 'file' then
hatnote = 'This file is'
elseif args.only == 'file' then
hatnote = 'These files are'
elseif args.only == 'list' then
hatnote = 'This list is'
elseif args.only == 'lists' then
hatnote = 'These lists are'
elseif args.only == 'table' then
hatnote = 'This table is'
elseif args.only == 'tables' then
hatnote = 'These tables are'
else
hatnote = 'This section is'
end
hatnote = hatnote .. ' an excerpt from '
if section then
hatnote = hatnote .. '[[' .. page .. '#' .. section .. '|' .. page .. ' § ' .. section .. ']]'
else
hatnote = hatnote .. '[[' .. page .. ']]'
end
hatnote = hatnote .. "''" .. '<span class="mw-editsection-like plainlinks"><span class="mw-editsection-bracket">[</span>['
hatnote = hatnote .. title:fullUrl('action=edit') .. ' edit'
hatnote = hatnote .. ']<span class="mw-editsection-bracket">]</span></span>' .. "''"
hatnote = require('Module:Hatnote')._hatnote(hatnote, {selfref=true}) or e.wikiError('Error generating hatnote')
end
-- Build the module options out of the template arguments and the desired defaults
local options = {
fileflags = e.numberFlags( args['files'] or 1 ),
paraflags = e.numberFlags( args['paragraphs'] ),
filesOnly = e.is( args['only'] == 'file' or args['only'] == 'files' ),
listsOnly = e.is( args['only'] == 'list' or args['only'] == 'lists'),
tablesOnly = e.is( args['only'] == 'table' or args['only'] == 'tables' ),
keepTables = e.is( args['tables'] or true ),
keepRefs = e.is( args['references'] or true ),
keepSubsections = e.is( args['subsections'] ),
nobold = not e.is( args['bold'] ),
fragment = args['fragment']
}
-- Get the excerpt itself
if section then page = page .. '#' .. section end
local ok, excerpt = pcall(e.get, page, options)
if not ok then return e.wikiError(excerpt) end
excerpt = "\n" .. excerpt -- line break is necessary to prevent broken tables and lists
if mw.title.getCurrentTitle().isContentPage then excerpt = excerpt .. '[[Category:Articles with excerpts]]' end
excerpt = frame:preprocess(excerpt)
excerpt = mw.html.create(tag):addClass('excerpt'):wikitext(excerpt)
-- Combine and return the elements
return block:node(style):node(hatnote):node(excerpt)
end
-- Entry points for English Wikipedia templates
function p.lead(frame) return portal(frame, "lead") end -- {{Transclude lead excerpt}} reads a randomly selected article linked from the given page
function p.linked(frame) return portal(frame, "linked") end -- {{Transclude linked excerpt}} reads a randomly selected article linked from the given page
function p.listitem(frame) return portal(frame, "listitem") end -- {{Transclude list item excerpt}} reads a randomly selected article listed on the given page
function p.random(frame) return portal(frame, "random") end -- {{Transclude random excerpt}} reads any article (default for invoke with one argument)
function p.selected(frame) return portal(frame, "selected") end -- {{Transclude selected excerpt}} reads the article whose key is in the selected= parameter
function p.excerpt(frame) return excerpt(frame) end -- {{Excerpt}} transcludes part of an article into another article
return p