Module:Firehose links
From PickiPedia: A knowledge base of bluegrass, old time psychedelic jams, and other public domain music
Jump to navigationJump to search
Documentation for this module may be created at Module:Firehose links/doc
-- Helpers for Template:Firehose.
--
-- The firehose runs its #ask with link=none, because Semantic MediaWiki
-- otherwise hands the template a pre-rendered link for every value, which
-- defeats both #titleparts and any attempt to relabel the episode link.
--
-- The cost of link=none is that topic names arrive as plain text, comma-joined
-- when an episode has more than one. Linking that string whole would produce a
-- single broken redlink -- one link containing "Sam Bush, Jerry Douglas" -- so
-- split it and link each name on its own.
--
-- Note for future editors: do not wrap this header in a --[==[ ]==] block
-- comment containing wiki link syntax. Lua reads the inner brackets as nested
-- long brackets and refuses to load the module.
local p = {}
-- Values the title parser sometimes yields that are not entities, and so
-- should be shown but never linked.
local NOT_AN_ENTITY = {
["and more"] = true,
["more"] = true,
["etc"] = true,
["etc."] = true,
}
local function split( raw )
local out = {}
for name in ( ( raw or "" ) .. "," ):gmatch( "%s*(.-)%s*," ) do
if name ~= "" then
table.insert( out, name )
end
end
return out
end
local function link( name )
if NOT_AN_ENTITY[ name:lower() ] then
return name
end
return "[[" .. name .. "]]"
end
-- Which of these names are pages in Category:People.
--
-- One query for the whole row rather than one per name, since a tribute
-- episode can name nine people and a firehose shows twenty-five rows.
local function peopleAmong( frame, names )
local candidates = {}
for _, name in ipairs( names ) do
if not NOT_AN_ENTITY[ name:lower() ] then
table.insert( candidates, name )
end
end
if #candidates == 0 then
return {}
end
local found = frame:callParserFunction( "#ask", {
"[[Category:People]][[" .. table.concat( candidates, "||" ) .. "]]",
"format=list",
"link=none",
"sep=;",
"searchlabel=",
"limit=50",
} )
-- SMW wraps each value in span markup, even with link=none, and may hand
-- the result back as a strip marker. Reduce it to the bare names first, or
-- "<span class=smw-value>Billy Strings</span>" never equals Billy Strings
-- and every person gets filed as a topic.
found = mw.text.unstrip( found ):gsub( "<[^>]+>", "" )
local set = {}
for name in ( found .. ";" ):gmatch( "%s*(.-)%s*;" ) do
if name ~= "" then
set[ name ] = true
end
end
return set
end
-- Every subject of an episode, linked, and filed as people or topics.
--
-- A page in Category:People is a person. A page that exists and is not in it —
-- a band, a festival, a tune — is a topic. A name with no page yet is filed
-- with the people, because nothing yet says otherwise and nearly everything
-- the title parser extracts is a personal name. That default corrects itself:
-- the moment somebody writes East Nash Grass up as a band, it moves across.
function p.subjects( frame )
local names = split( frame.args[1] )
if #names == 0 then
return ""
end
local people = peopleAmong( frame, names )
local persons, topics = {}, {}
for _, name in ipairs( names ) do
local title = mw.title.new( name )
if people[ name ] then
table.insert( persons, link( name ) )
elseif title and title.exists then
table.insert( topics, link( name ) )
else
table.insert( persons, link( name ) )
end
end
local parts = {}
if #persons > 0 then
table.insert( parts, "people " .. table.concat( persons, ", " ) )
end
if #topics > 0 then
table.insert( parts, "topics " .. table.concat( topics, ", " ) )
end
return table.concat( parts, " · " )
end
-- Every subject linked, unlabelled. Kept for callers that want a plain list.
function p.topiclinks( frame )
local out = {}
for _, name in ipairs( split( frame.args[1] ) ) do
table.insert( out, link( name ) )
end
return table.concat( out, ", " )
end
-- Former name, kept so an older revision of a calling template does not break.
p.guestlinks = p.topiclinks
return p