Jump to content

Module:External links and Module:External links/sandbox: Difference between pages

(Difference between pages)
Page 1
Page 2
Content deleted Content added
Reduce number of links shown by default. Per WP:LINKFARM: Wikipedia is not a repository of links... excessive lists can dwarf articles and detract from the purpose of Wikipedia; Per WP:ELPOINTS: Links in the "External links" section should be kept to a minimum
 
Remove paranoid checks for if linkTemplate.[x] exists but is an empty string - that should be the config's problem, and if anything this should just error in that situation
 
Line 1: Line 1:
require('strict')
require('strict')
-- local genitive = require('Module:Genitive')._genitive
-- local genitive = require('Module:Genitive')._genitive
local contLang = mw.language.getContentLanguage()
local contLangCode = mw.language.getContentLanguage():getCode()


local cmodule = {}
local cmodule = {}
local conf = require 'Module:External links/conf'(contLang:getCode())
local conf = require 'Module:External links/conf'(contLangCode)
local hasdatafromwikidata = false
local hasdatafromwikidata = false
local hasdatafromlocal = false
local hasdatafromlocal = false
local haswikidatalink = true -- we assume it's connected
local haswikidatalink = true -- whether or not this page has a wikidata entity(?); we assume there is one at first


local p = {}
local p = {}


local function getLabel(entity, use_genitive, pagetitle)
local function getLabel(entity, use_genitive, pagetitle)
local label = (pagetitle and pagetitle ~= '') and pagetitle or nil
local label = (pagetitle ~= '') and pagetitle or nil
if not label and not entity then
if not label and not entity then
label = mw.title.getCurrentTitle().text
label = mw.title.getCurrentTitle().text
elseif not label then
elseif not label then
label = mw.wikibase.label(entity.id) or mw.title.getCurrentTitle().text
label = mw.wikibase.getLabel(entity.id) or mw.title.getCurrentTitle().text
end
end
-- return use_genitive and genitive(label, 'sitt') or label
-- return use_genitive and genitive(label, 'sitt') or label
Line 29: Line 29:


local function stringFormatter( datavalue )
local function stringFormatter( datavalue )
if datavalue == nil or datavalue['type'] ~= 'string' then
if datavalue == nil or datavalue.type ~= 'string' then
return nil
return nil
end
end
return datavalue.value
return datavalue.value
end
end

local pval = {}
pval.P1793 = { -- format as a regular expression
types = {
snaktype = 'value',
datatype = 'string',
},
}

pval.P407 = { -- language of work or name
types = {
snaktype = 'value',
datatype = 'wikibase-item',
datavalue = {
type = 'wikibase-entityid',
}
},
}

pval.P364 = { -- original language of work
types = {
snaktype = 'value',
datatype = 'wikibase-item',
datavalue = {
type = 'wikibase-entityid',
}
},
}

pval.P218 = { -- ISO 639-1 language
types = {
snaktype = 'value',
datatype = 'external-id',
datavalue = {
type = 'string',
}
},
}

pval.P305 = { -- IETF language tag
types = {
snaktype = 'value',
datatype = 'external-id',
datavalue = {
type = 'string',
}
},
}

pval.P582 = { -- end time
types = {
snaktype = 'value',
datatype = 'time',
datavalue = {
type = 'string',
}
},
}



-- This is a really makeshift crappy converter, but it'll do some basic
-- This is a really makeshift crappy converter, but it'll do some basic
-- conversion from PCRE to Lua-style patterns (note that this only work
-- conversion from PCRE to Lua-style patterns (note that this only work
-- in very few cases)
-- in very few cases)
local function regexConverter( regex )
local function regexConverterTest( regex, str )
regex = regex:gsub("\\d{(%d)}", function(num) return string.rep("%d", num) end)
local output = regex
output = string.gsub(output, "\\d{2}", "%%d%%d")
output = string.gsub(output, "\\d{3}", "%%d%%d%%d")
output = string.gsub(output, "\\d{4}", "%%d%%d%%d%%d")
output = string.gsub(output, "\\d{5}", "%%d%%d%%d%%d%%d")
output = string.gsub(output, "\\d{6}", "%%d%%d%%d%%d%%d%%d")
output = string.gsub(output, "\\d{7}", "%%d%%d%%d%%d%%d%%d%%d")
output = string.gsub(output, "\\d{8}", "%%d%%d%%d%%d%%d%%d%%d%%d")
output = string.gsub(output, "\\d", "%%d")
return string.find(str, '^' .. regex .. '$')
return output
end
end




local function getFormatterUrl( prop, value )
local function getFormatterUrl( prop, value )
local head = ""
local fUrl = ""
local statements = mw.wikibase.getBestStatements(prop, "P1630")
local tail = ""
local entity = mw.wikibase.getEntity(prop)
-- to avoid deep tests
-- to avoid deep tests
if not entity or not entity.claims then
if #statements == 0 then
return head
return ""
end
end
-- get the claims for this entity
local statements = entity.claims['P1630'] -- formatter URL
-- to avoid deep tests
if not statements then
return head
end
local formatters = {}
-- let's go through the claims
-- let's go through the claims
for _, claim in ipairs( statements ) do
for _, claim in ipairs( statements ) do
local mainsnak = claim.mainsnak -- nil will be indexed if it doesn't exist
-- to avoid deep tests
--[[
if not claim then
Checks P1793 (format as a regular expression) qualifier of formatter URL to
claim = {}
check if the given string matches the formatter URL's regex;
end
will prioritize that formatter URL if true
local valid = claim['type'] == 'statement'
]]
and claim['rank'] ~= 'deprecated'
local qualifiers = claim.qualifiers or {}
if valid then
local qualid = 'P1793' -- format as a regular expression
local mainsnak = claim.mainsnak or {}
if qualifiers[qualid] then
local preferred = claim['rank'] == 'preferred'
-- we have a regex qualifier, traverse all snaks
-- get any qualifiers for this claim (we are interested in P1793 for
for _, qualsnak in ipairs( qualifiers[qualid] ) do
-- indication of which claim is correct)
if qualsnak.snaktype == 'value'
local qualifiers = claim.qualifiers or {}
and regexConverterTest(qualsnak.datavalue.value, value)
-- now let's check the qualifier we are interested in
then
local qualid = 'P1793' -- format as a regular expression
-- it matched, this is correct and overrides any other.
-- if the claim has this qualifier
fUrl = mainsnak.datavalue.value
if qualifiers[qualid] then
break
-- it's here, let's check it out!
local items = {}
-- traverse all snaks in this qualifier
for _, qualsnak in ipairs( qualifiers[qualid] ) do
if qualsnak and pval[qualid] then
--mw.log("qualsnak = " .. dump(qualsnak))
-- check if the snak is of the correct snaktype and datatype
local valid = qualsnak.snaktype == pval[qualid].types.snaktype
and qualsnak.datatype == pval[qualid].types.datatype
if valid then
-- we'll have to convert the regex to Lua-style
local regex = regexConverter(qualsnak.datavalue.value)
local test = string.match( value, '^'..regex..'$' )
if test then
-- it matched, this is correct and overrides any other.
if preferred then
head = mainsnak.datavalue.value
else
tail = mainsnak.datavalue.value
end
end
end
end
end
else
-- we don't have any qualifier, is it preferred?
if (head == '' and preferred) or (tail == '' and not preferred) then
-- if we don't have any other, use this one
if preferred and head == '' then
head = mainsnak.datavalue.value
elseif not preferred and tail == '' then
tail = mainsnak.datavalue.value
end
end
end
end
end
elseif fUrl == '' then -- if we don't have any other, use this one
fUrl = mainsnak.datavalue.value
end
end
end
end
return head ~= '' and head or tail
return fUrl

end
end






local function getLanguageData(prop, qid)
local function getLanguageData(prop, qid, separator)
-- Formerly outputted a table, but this function was always run through table.concat() when invoked, so it has been simplified to yield a string
local head = {}
separator = separator or ''
local tail = {}
local output = ''
-- mw.log("getLanguageData, prop="..dump(prop).." qid="..dump(qid))
if not mw.wikibase.entityExists(qid) then -- yield error, which would originally happen because table.concat(nil) errors
-- get the entity we are checking
error("getLanguageData was given a nonexistent entity")
local entity = mw.wikibase.getEntityObject(qid)
-- to avoid deep tests
if not entity then
return nil
end
end
if not entity.claims then
-- get claims
local statements = mw.wikibase.getBestStatements(qid, prop)
return {}
end
-- get the claims for this entity
local statements = entity.claims[prop]
-- to avoid deep tests
-- to avoid deep tests
if not statements then
if #statements == 0 then
return {}
return ''
end
end
-- mw.log("getLanguageData going through claims="..dump(statements))
-- mw.log("getLanguageData going through claims="..dump(statements))
-- let's go through the claims
-- let's go through the claims
for _, claim in ipairs( statements ) do
for _, claim in ipairs( statements ) do
local mainsnak = claim.mainsnak
-- to avoid deep tests
if not claim then
if mainsnak.snaktype == 'value' then
-- if this is the correct P-value, dive into it and get P218 (ISO 639-1)
claim = {}
if prop == 'P364' then -- original language of work
end
output = output .. separator .. getLanguageData('P218', mainsnak.datavalue.value.id, conf:a('mod-filter-separator'))
local valid = claim['type'] == 'statement'
elseif prop == 'P218' or prop == 'P305' then -- ISO 639-1 code or IETF language tag
and claim['rank'] ~= 'deprecated'
output = output .. separator .. stringFormatter(mainsnak.datavalue)
if valid then
local mainsnak = claim.mainsnak or {}
local preferred = claim['rank'] == 'preferred'
-- verify the item is what we expect
local valid = mainsnak.snaktype == pval[prop].types.snaktype
and mainsnak.datatype == pval[prop].types.datatype
and mainsnak.datavalue.type == pval[prop].types.datavalue.type
if valid then
-- mw.log("getLanguageData claim is valid="..dump(claim))
-- if this is the correct P-value, dive into it and get P218 (ISO 639-1)
if mainsnak.property == 'P364' then -- original language of work
if preferred then
head[#head+1] = table.concat(getLanguageData('P218', 'Q'..mainsnak.datavalue.value['numeric-id']), conf:a('mod-filter-separator'))
else
tail[#tail+1] = table.concat(getLanguageData('P218', 'Q'..mainsnak.datavalue.value['numeric-id']), conf:a('mod-filter-separator'))
end
elseif mainsnak.property == 'P218' or mainsnak.property == 'P305' then -- ISO 639-1 code or IETF language tag
if preferred then
head[#head+1] = stringFormatter(mainsnak.datavalue)
else
tail[#tail+1] = stringFormatter(mainsnak.datavalue)
end
end
end
end
end
end
end
end
return output
-- mw.log("getLanguageData returning head="..dump(head).." tail="..dump(tail))
return #head>0 and head or tail
end
end


local langqvalorder = {'P407','P364'}
local langqvalorder = {'P407','P364'} -- check `language of work or name` first, `original language of film or TV show` second
local otherqvalorder = {'P582'}
local otherqvalorder = {'P582'}


local function getValuesFromWikidata(props)
local function getValuesFromWikidata(linkTemplate)
local head = {}
local output = {}
-- mw.log("getValuesFromWikidata, linkTemplate="..dump(linkTemplate))
local tail = {}
-- get statements
-- mw.log("getValuesFromWikidata, props="..dump(props))
-- get the entity we are checking
local entity = mw.wikibase.getEntity()
-- check if the entity exists
local entity = mw.wikibase.getEntityObject()
-- TODO: check if we can skip distinguishing between no entity vs. no statements
-- to avoid deep tests
if not entity then
if not entity then -- check if the entity exists
--mw.log("getValuesFromWikidata no entity")
return nil
return nil
end
end
local statements = entity:getBestStatements(linkTemplate.prop)
if not entity.claims or not props or not props.prop or props.prop == '' then
--mw.log("getValuesFromWikidata no claims or no props")
return {}
end
-- get the claims for this entity
local statements = entity.claims[props.prop]
-- to avoid deep tests
-- to avoid deep tests
if not statements then
if #statements == 0 then
return {}
return {}
end
end
-- let's go through the claims
-- let's go through the claims
for _, claim in ipairs( statements ) do
for _, claim in ipairs( statements ) do
output[#output + 1] = { value=stringFormatter(claim.mainsnak.datavalue) }
-- to avoid deep tests
--- Check if the linkTemplate wants us to search a qualifier for languagedata
if not claim then
claim = {}
local qualifiers = claim.qualifiers or {}
end
-- get the content of the claim (the identifier)
local valid = claim['type'] == 'statement'
local langcode = linkTemplate.langcode
and claim['rank'] ~= 'deprecated'
if valid then
if langcode
and string.find(langcode, "[pP]%d+")
-- mw.log("getValuesFromWikidata valid claim="..dump(claim))
then
local mainsnak = claim.mainsnak or {}
-- this is a P-value for language-code, so we'll check qualifiers for languagedata
local preferred = claim['rank'] == 'preferred'
-- get the content of the claim (the identifier)
local langcode = props.langcode
local checklangcode = nil
if props.langcode and props.langcode ~= '' then
checklangcode = string.find(langcode, "([pP]%d+)")
end
if checklangcode and checklangcode ~= "" then
-- this is a P-value for language-code, so we'll check qualifiers for languagedata
-- first get any qualifiers
local qualifiers = claim.qualifiers or {}
for _, qualid in ipairs( langqvalorder ) do
-- if the claim has this qualifier
if qualifiers[qualid] then
-- it's here, let's check it out!
local items = {}
-- traverse all snaks in this qualifier
for _, qualsnak in ipairs( qualifiers[qualid] ) do
if qualsnak and pval[qualid] then
-- mw.log("qualsnak = " .. dump(qualsnak))
-- check if the snak is of the correct snaktype and datatype
local valid = qualsnak.snaktype == pval[qualid].types.snaktype
and qualsnak.datatype == pval[qualid].types.datatype
if valid then
-- now get the actual data
langcode = table.concat(getLanguageData('P305', 'Q'..qualsnak.datavalue.value['numeric-id']), '')
end
end
end
end
-- mw.log("langcode is now="..dump(langcode))
end
if string.find(langcode, "([pP]%d+)") then
-- we still don't have any langcode, so we default to "en"
langcode = nil
end
end
local stillvalid = true
-- we should check a couple of other qualifiers as well
-- first get any qualifiers
-- first get any qualifiers
for _, qualid in ipairs( langqvalorder ) do
local qualifiers = claim.qualifiers or {}
for _, qualid in ipairs( otherqvalorder ) do
-- if the claim has this qualifier
-- if the claim has this qualifier
if qualifiers[qualid] then
if qualifiers[qualid] then
-- it's here, let's check it out!
-- it's here, let's check it out!
local items = {}
-- traverse all snaks in this qualifier
-- traverse all snaks in this qualifier
for _, qualsnak in ipairs( qualifiers[qualid] ) do
for _, qualsnak in ipairs( qualifiers[qualid] ) do
if qualsnak and pval[qualid] then
if qualsnak.snaktype == 'value' then
-- mw.log("qualsnak = " .. dump(qualsnak))
-- now get the actual data
langcode = getLanguageData('P305', qualsnak.datavalue.value.id)
-- check if the snak is of the correct snaktype and datatype
local valid = qualsnak.snaktype == pval[qualid].types.snaktype
and qualsnak.datatype == pval[qualid].types.datatype
if not valid then
-- sorry, this is not correct
mw.log("qualsnak = INCORRECT")
stillvalid = false
end
end
end
end
end
Line 344: Line 156:
-- mw.log("langcode is now="..dump(langcode))
-- mw.log("langcode is now="..dump(langcode))
end
end
if stillvalid then
if string.find(langcode, "[pP]%d+") then
-- we still don't have any langcode, so we default to "en"
if preferred then
langcode = nil
head[#head+1] = { value=stringFormatter(mainsnak.datavalue) }
if langcode and langcode ~= '' then
head[#head]['langcode'] = langcode
end
else
tail[#tail+1] = { value=stringFormatter(mainsnak.datavalue) }
if langcode and langcode ~= '' then
tail[#tail]['langcode'] = langcode
end
end
end
end
end
--[[ EDITOR'S NOTE:
I trimmed the `stillvalid` check thinking it was just doing stuff already handled by Wikibase's built-in input constraints.
However, it would've also aborted the loop iteration if "end time" was provided with `no value` or `unknown value`.
I'm not sure if that functionality would've had any purpose, given how cryptic this function is.
]]
if langcode and langcode ~= '' then
output[#output].langcode = langcode
end
end
end
end
-- mw.log("getValuesFromWikidata returning head="..dump(head).." tail="..dump(tail))
-- mw.log("getValuesFromWikidata returning head="..dump(head).." tail="..dump(tail))
return #head>0 and head or tail
return output
end
end


local function findMainLinksOnWikidata(props, pagetitle, short_links)
local function findMainLinksOnWikidata(linkTemplate, pagetitle, short_links)
local output = {}
local output = {}
local pid = nil
-- get the entity we are checking
-- get the entity we are checking
local entity = mw.wikibase.getEntityObject()
local entity = mw.wikibase.getEntity()
-- to avoid deep tests
-- to avoid deep tests
if not entity then
if not entity then
return nil
return nil
end
end
local values = getValuesFromWikidata(props)
local values = getValuesFromWikidata(linkTemplate)
for _, value in ipairs( values ) do
for _, value in ipairs( values ) do
local verified_value = nil
local verified_value = value.value
if props.regex then
if not (linkTemplate.regex and
regexConverterTest(linkTemplate.regex, value.value))
-- we have a local defined regex, so this will have to pass first
then
-- maybe we'll have to convert the regex to Lua-style
output[#output+1] = {
local regex = regexConverter(props.regex)
local test = string.match( value.value, '^'..regex..'$' )
langcode = value.langcode,
category = {}
--mw.log("testing with "..regex.. " and test="..dump(test).." and value="..id)
}
if test then
-- Search for a url formatter
-- it matched, this is correct and overrides any other.
verified_value = value.value
end
else
verified_value = value.value
end
if verified_value then
local url = ''
local url = ''
if linkTemplate.url_f then
output[#output+1] = {}
-- we have a locally defined url-formatter function from the config, use it as first priority
output[#output].langcode = value.langcode
url = linkTemplate.url_f(verified_value)
output[#output].category = {}
if linkTemplate.track and not string.find(linkTemplate.langcode, "[pP]%d+") then
if props.url_f then
output[#output].category[1] = mw.message.newRawMessage(cmodule:getMessage(contLangCode, 'track-cat-local-wd'), linkTemplate.prop):plain()
-- we have a local defined url-formatter function, use it as first priority
elseif linkTemplate.track then
url = props.url_f(verified_value)
output[#output].category[1] = mw.message.newRawMessage(cmodule:getMessage(contLangCode, 'track-cat-wd-wd'), linkTemplate.prop):plain()
if props.track and not string.find(props.langcode, "([pP]%d+)") then
output[#output].category[#output[#output].category+1] = mw.message.newRawMessage(cmodule:getMessage(contLang:getCode(), 'track-cat-local-wd'), props.prop):plain()
elseif props.track then
output[#output].category[#output[#output].category+1] = mw.message.newRawMessage(cmodule:getMessage(contLang:getCode(), 'track-cat-wd-wd'), props.prop):plain()
end
end
elseif props.url then
elseif linkTemplate.url then
-- we have a local defined url-formatter string, use it as second priority
-- we have a locally defined url-formatter string from the config, use it as second priority
url = mw.message.newRawMessage(props.url, verified_value):plain()
url = mw.message.newRawMessage(linkTemplate.url, verified_value):plain()
if props.track and not string.find(props.langcode, "([pP]%d+)") then
if linkTemplate.track and not string.find(linkTemplate.langcode, "[pP]%d+") then
output[#output].category[#output[#output].category+1] = mw.message.newRawMessage(cmodule:getMessage(contLang:getCode(), 'track-cat-local-wd'), props.prop):plain()
output[#output].category[1] = mw.message.newRawMessage(cmodule:getMessage(contLangCode, 'track-cat-local-wd'), linkTemplate.prop):plain()
elseif props.track then
elseif linkTemplate.track then
output[#output].category[#output[#output].category+1] = mw.message.newRawMessage(cmodule:getMessage(contLang:getCode(), 'track-cat-wd-wd'), props.prop):plain()
output[#output].category[1] = mw.message.newRawMessage(cmodule:getMessage(contLangCode, 'track-cat-wd-wd'), linkTemplate.prop):plain()
end
end
else
else
-- config has no url formatter; check if Wikidata has one on the property
-- get the formatvalue from the property, if it exists
local formatterUrl = getFormatterUrl(props.prop, verified_value)
local formatterUrl = getFormatterUrl(linkTemplate.prop, verified_value)
if formatterUrl ~= '' then
if formatterUrl ~= '' then
url = mw.message.newRawMessage(formatterUrl, verified_value):plain()
url = mw.message.newRawMessage(formatterUrl, verified_value):plain()
if props.track then
if linkTemplate.track then
output[#output].category[#output[#output].category+1] = mw.message.newRawMessage(cmodule:getMessage(contLang:getCode(), 'track-cat-wd-wd'), props.prop):plain()
output[#output].category[1] = mw.message.newRawMessage(cmodule:getMessage(contLangCode, 'track-cat-wd-wd'), linkTemplate.prop):plain()
end
end
end
end
end
end
if url ~= '' then
if url ~= '' then
local langlink = (value.langcode and value.langcode ~= '' and value.langcode ~= contLangCode)
local this_wiki = mw.getContentLanguage()
and mw.message.newRawMessage(conf:g('msg-langcode'), value.langcode, mw.language.fetchLanguageName(value.langcode, contLangCode))
local this_wiki_code = this_wiki:getCode()
or ""
local langlink = (value.langcode and value.langcode ~= '' and value.langcode ~= this_wiki_code) and mw.message.newRawMessage(conf:g('msg-langcode'), value.langcode, mw.language.fetchLanguageName(value.langcode, this_wiki_code)) or ""
output[#output].text =
if short_links and props.short then
mw.message.newRawMessage(short_links and linkTemplate.short or linkTemplate.message,
output[#output].text =
getLabel(entity, linkTemplate.genitive, pagetitle),
mw.message.newRawMessage(props.short,
url,
getLabel(entity, props.genitive, pagetitle),
url,
langlink,
langlink,
verified_value,
verified_value,
mw.uri.encode(verified_value, 'PATH'))
:plain()
mw.uri.encode(verified_value, 'PATH'))
:plain()
else
output[#output].text =
mw.message.newRawMessage(props.message,
getLabel(entity, props.genitive, pagetitle),
url,
langlink,
verified_value,
mw.uri.encode(verified_value, 'PATH'))
:plain()
end
end
end
end
end
Line 449: Line 239:
end
end


local function getSitelinksFromWikidata(props, entity)
local function getSitelinkFromWikidata(linkTemplate, entity)
local output = {}
--mw.log("getSitelinksFromWikidata, props="..dump(props))
-- to avoid deep tests
-- to avoid deep tests
if not entity then
if not entity then
entity = mw.wikibase.getEntityObject()
entity = mw.wikibase.getEntity()
if not entity then
if not entity then
--mw.log("getSitelinksFromWikidata no entity")
--mw.log("getSitelinkFromWikidata no entity")
return nil
return nil
end
end
end
end
local requested_sitelink = string.match(props.prop, "SL(%l+)")
local requested_sitelink = string.match(linkTemplate.prop, "SL(%l+)") -- a specific wiki to be linked to can be specified by config; otherwise, default to this wiki
local sitelinks = entity:getSitelink(requested_sitelink)
local sitelink = entity:getSitelink(requested_sitelink)
return sitelink or nil
if sitelinks and sitelinks ~= '' then
output[#output+1] = { value = sitelinks }
end
--mw.log("getSitelinksFromWikidata returning output="..dump(output))
return output
end
end


-- This function has a bug: :getSitelink does not return an object - only a string; yet this function tries to access sitelink.langcode

local function findSiteLinksOnWikidata(props, pagetitle, short_links)
local function findSiteLinksOnWikidata(linkTemplate, pagetitle, short_links)
local output = {}
local output = {}
local pid = nil
local sitelink = getSitelinkFromWikidata(linkTemplate)
-- get the entity we are checking
-- verify existence of sitelink
local entity = mw.wikibase.getEntityObject()
if not sitelink then
-- to avoid deep tests
if not entity then
return nil
return nil
end
end
if not (linkTemplate.regex and
local values = getSitelinksFromWikidata(props)
not regexConverterTest(linkTemplate.regex, sitelink))
for _, value in ipairs( values ) do
then
local verified_value = nil
output[1] = {
if props.regex then
langcode = sitelink.langcode,
-- we have a local defined regex, so this will have to pass first
category = {}
-- maybe we'll have to convert the regex to Lua-style
}
local regex = regexConverter(props.regex)
-- Search for a url-formatter
local test = string.match( value.value, '^'..regex..'$' )
local url = ''
--mw.log("testing with "..regex.. " and test="..dump(test).." and value="..id)
if test then
if linkTemplate.url_f then
-- we have a locally defined url-formatter function from the config, use it as first priority
-- it matched, this is correct and overrides any other.
url = linkTemplate.url_f(sitelink)
verified_value = value.value
elseif linkTemplate.url then
end
-- we have a locally defined url-formatter string from the config, use it as second priority
url = mw.message.newRawMessage(linkTemplate.url, sitelink):plain()
else
else
url = sitelink:gsub(' ','_')
verified_value = value.value
end
end
if verified_value then
if linkTemplate.track and not string.find(linkTemplate.langcode, "SL%l+") and (linkTemplate.url_f or linkTemplate.url) then
--mw.log("it's verified..")
output[1].category[1] = mw.message.newRawMessage(cmodule:getMessage(contLangCode, 'track-cat-local-wd'), linkTemplate.prop):plain()
local url = ''
elseif linkTemplate.track then
output[#output+1] = {}
output[1].category[1] = mw.message.newRawMessage(cmodule:getMessage(contLangCode, 'track-cat-wd-wd'), linkTemplate.prop):plain()
output[#output].langcode = value.langcode
end
output[#output].category = {}
if props.url_f then
if url ~= '' then
-- we have a local defined url-formatter function, use it as first priority
local langlink = (sitelink.langcode and sitelink.langcode ~= '' and sitelink.langcode ~= contLangCode)
url = props.url_f(verified_value)
and mw.message.newRawMessage(conf:g('msg-langcode'), sitelink.langcode, mw.language.fetchLanguageName(sitelink.langcode, contLangCode))
if props.track and not string.find(props.langcode, "(SL%l+)") then
or ""
output[#output].category[#output[#output].category+1] = mw.message.newRawMessage(cmodule:getMessage(contLang:getCode(), 'track-cat-local-wd'), props.prop):plain()
output[1].text =
elseif props.track then
mw.message.newRawMessage(short_links and linkTemplate.short or linkTemplate.message,
output[#output].category[#output[#output].category+1] = mw.message.newRawMessage(cmodule:getMessage(contLang:getCode(), 'track-cat-wd-wd'), props.prop):plain()
getLabel(entity, linkTemplate.genitive, pagetitle),
end
elseif props.url then
url,
langlink,
-- we have a local defined url-formatter string, use it as second priority
sitelink,
url = mw.message.newRawMessage(props.url, verified_value):plain()
mw.uri.encode(sitelink, 'PATH'))
if props.track and not string.find(props.langcode, "(SL%l+)") then
:plain()
output[#output].category[#output[#output].category+1] = mw.message.newRawMessage(cmodule:getMessage(contLang:getCode(), 'track-cat-local-wd'), props.prop):plain()
elseif props.track then
output[#output].category[#output[#output].category+1] = mw.message.newRawMessage(cmodule:getMessage(contLang:getCode(), 'track-cat-wd-wd'), props.prop):plain()
end
else
url = verified_value:gsub(' ','_')
if props.track then
output[#output].category[#output[#output].category+1] = mw.message.newRawMessage(cmodule:getMessage(contLang:getCode(), 'track-cat-wd-wd'), props.prop):plain()
end
end
if url ~= '' then
local this_wiki = mw.getContentLanguage()
local this_wiki_code = this_wiki:getCode()
local langlink = (value.langcode and value.langcode ~= '' and value.langcode ~= this_wiki_code) and mw.message.newRawMessage(conf:g('msg-langcode'), value.langcode, mw.language.fetchLanguageName(value.langcode, this_wiki_code)) or ""
if short_links and props.short then
output[#output].text =
mw.message.newRawMessage(props.short,
getLabel(entity, props.genitive, pagetitle),
url,
langlink,
verified_value,
mw.uri.encode(verified_value, 'PATH'))
:plain()
else
output[#output].text =
mw.message.newRawMessage(props.message,
getLabel(entity, props.genitive, pagetitle),
url,
langlink,
verified_value,
mw.uri.encode(verified_value, 'PATH'))
:plain()
end
end
end
end
end
end
Line 554: Line 306:




local function findMainLinksLocal(props, pagetitle, short_links, local_value)
local function findMainLinksLocal(linkTemplate, pagetitle, short_links, local_value)
local output = {}
local output = {}
-- to avoid deep tests
-- to avoid deep tests
if not local_value or local_value == '' -- bail out if no value is present
if not props.prop then
or (linkTemplate.regex
return nil
and not regexConverterTest(linkTemplate.regex, local_value))
then
return {}
end
end
local wikidata_property = string.find(linkTemplate.prop, "[pP]%d+")
if not local_value or local_value == '' then
local wikidata_values = nil
-- bail out if no value is present
return output
end
-- get the formatvalue from the property
local verified_value = local_value
if props.regex and props.regex ~= '' then
-- let's verify the id
-- maybe we'll have to convert the regex to Lua-style
local regex = regexConverter(props.regex)
local test = string.match( local_value, '^'..regex..'$' )
if test then
-- it matched, this is correct
verified_value = local_value
else
verified_value = nil
end
end
if not verified_value then
return output
end
local wikidata_property = string.find(props.prop, "([pP]%d+)")
local wikidata_values = {}
if wikidata_property then
if wikidata_property then
-- get any wikidata values to see if they are equal to local values
-- get any wikidata values to see if they are equal to local values
wikidata_values = getValuesFromWikidata(props)
wikidata_values = getValuesFromWikidata(linkTemplate)
if wikidata_values then
hasdatafromwikidata = true -- signal up the chain this article has a wikidata claim
end
end
end
if wikidata_property or (props.url and props.url ~= '') or (props.url_f) then
if wikidata_property or (linkTemplate.url) or (linkTemplate.url_f) then
output[#output+1] = {}
output[1] = {
output[#output].langcode = string.find(props.langcode, "([pP]%d+)") and "" or props.langcode
langcode = string.find(linkTemplate.langcode, "[pP]%d+") and "" or linkTemplate.langcode,
category = {}
--mw.log("findMainLinksLocal - props="..dump(props).." langcode="..output[#output].langcode)
}
output[#output].category = {}
assert(not wikidata_values or type(wikidata_values) == 'table', "Something went wrong: wikidata_values is neither a table nor nil")
local url = ''
if props.track and wikidata_property and wikidata_values and #wikidata_values then
if linkTemplate.track and wikidata_values then
local local_value_in_wikidata = false
local local_value_in_wikidata = false
for _,value in ipairs( wikidata_values ) do
for _,value in ipairs( wikidata_values ) do
if value.value == verified_value then
if value.value == local_value then
local_value_in_wikidata = true
local_value_in_wikidata = true
break
end
end
end
end
output[#output].category[#output[#output].category+1] = mw.message.newRawMessage(cmodule:getMessage(contLang:getCode(), (local_value_in_wikidata and 'track-cat-local-wd-equal' or 'track-cat-local-wd-unequal')), props.prop):plain()
output[1].category[1] = mw.message.newRawMessage(cmodule:getMessage(contLangCode, (local_value_in_wikidata and 'track-cat-local-wd-equal' or 'track-cat-local-wd-unequal')), linkTemplate.prop):plain()
end
end
-- Search for a url-formatter
if wikidata_property and wikidata_values and #wikidata_values then
local url = ''
hasdatafromwikidata = true -- signal up the chain this article has a wikidata claim
if linkTemplate.url_f then
end
-- we have a locally defined url-formatter function from the config, use it as first priority
if props.url_f then
url = linkTemplate.url_f(local_value)
-- we have a local defined url-formatter function, use it as first priority
if linkTemplate.track then
url = props.url_f(verified_value)
output[1].category[#output[1].category+1] = mw.message.newRawMessage(cmodule:getMessage(contLangCode, 'track-cat-local-local'), linkTemplate.prop):plain()
if props.track then
output[#output].category[#output[#output].category+1] = mw.message.newRawMessage(cmodule:getMessage(contLang:getCode(), 'track-cat-local-local'), props.prop):plain()
end
end
elseif props.url then
elseif linkTemplate.url then
-- we have a local defined url-formatter string, use it as second priority
-- we have a locally defined url-formatter string from the config, use it as second priority
url = mw.message.newRawMessage(props.url, verified_value):plain()
url = mw.message.newRawMessage(linkTemplate.url, local_value):plain()
if props.track then
if linkTemplate.track then
output[#output].category[#output[#output].category+1] = mw.message.newRawMessage(cmodule:getMessage(contLang:getCode(), 'track-cat-local-local'), props.prop):plain()
output[1].category[#output[1].category+1] = mw.message.newRawMessage(cmodule:getMessage(contLangCode, 'track-cat-local-local'), linkTemplate.prop):plain()
end
end
elseif wikidata_property then
else -- we know wikidata_property exists
-- config has no url formatter; check if Wikidata has one on the property
-- get the formatvalue from the property, if it exists
local formatterUrl = getFormatterUrl(props.prop, verified_value)
local formatterUrl = getFormatterUrl(linkTemplate.prop, local_value)
if formatterUrl ~= '' then
if formatterUrl ~= '' then
url = mw.message.newRawMessage(formatterUrl, verified_value):plain()
url = mw.message.newRawMessage(formatterUrl, local_value):plain()
if props.track then
if linkTemplate.track then
output[#output].category[#output[#output].category+1] = mw.message.newRawMessage(cmodule:getMessage(contLang:getCode(), 'track-cat-wd-local'), props.prop):plain()
output[1].category[#output[1].category+1] = mw.message.newRawMessage(cmodule:getMessage(contLangCode, 'track-cat-wd-local'), linkTemplate.prop):plain()
end
end
end
end
else
-- no other choice, bail out
return {}
end
local this_wiki = mw.getContentLanguage()
local this_wiki_code = this_wiki:getCode()
local langlink = (output[#output].langcode and output[#output].langcode ~= '' and output[#output].langcode ~= this_wiki_code) and mw.message.newRawMessage(conf:g('msg-langcode'), props.langcode, mw.language.fetchLanguageName(props.langcode, this_wiki_code)) or ""
if short_links and props.short then
output[#output].text =
mw.message.newRawMessage(props.short,
getLabel(nil, props.genitive, pagetitle),
url,
langlink,
verified_value,
mw.uri.encode(verified_value, 'PATH'))
:plain()
else
output[#output].text =
mw.message.newRawMessage(props.message,
getLabel(nil, props.genitive, pagetitle),
url,
langlink,
verified_value,
mw.uri.encode(verified_value, 'PATH'))
:plain()
end
end
local langlink = (output[1].langcode and output[1].langcode ~= '' and output[1].langcode ~= contLangCode)
and mw.message.newRawMessage(conf:g('msg-langcode'), linkTemplate.langcode, mw.language.fetchLanguageName(linkTemplate.langcode, contLangCode))
or ""
output[1].text =
mw.message.newRawMessage(short_links and linkTemplate.short or linkTemplate.message,
getLabel(nil, linkTemplate.genitive, pagetitle),
url,
langlink,
local_value,
mw.uri.encode(local_value, 'PATH'))
:plain()
end
end
--mw.log("findMainLinksLocal returning="..dump(output))
--mw.log("findMainLinksLocal returning="..dump(output))
Line 658: Line 380:
end
end


local function findSiteLinksLocal(props, pagetitle, short_links, local_value)
local function findSiteLinksLocal(linkTemplate, pagetitle, short_links, local_value)
local output = {}
local output = {}
-- to avoid deep tests
-- to avoid deep tests
if not local_value or local_value == '' -- bail out if no value is present
if not props.prop then
or (linkTemplate.regex
return nil
and not regexConverterTest(linkTemplate.regex, local_value))
end
then
if not local_value or local_value == '' then
return {}
-- bail out if no value is present
return output
end
-- get the formatvalue from the property
local verified_value = local_value
if props.regex and props.regex ~= '' then
-- let's verify the id
-- maybe we'll have to convert the regex to Lua-style
local regex = regexConverter(props.regex)
local test = string.match( local_value, '^'..regex..'$' )
if test then
-- it matched, this is correct
verified_value = local_value
else
verified_value = nil
end
end
if not verified_value then
return output
end
end
local wikidata_property = string.find(props.prop, "(SL.+)")
local wikidata_property = string.find(linkTemplate.prop, "SL.+")
local wikidata_values = {}
local wikidata_sitelink = nil
if wikidata_property then
if wikidata_property then
-- get any wikidata values to see if they are equal to local values
-- get any wikidata values to see if they are equal to local values
wikidata_sitelink = getSitelinkFromWikidata(linkTemplate)
wikidata_values = getSitelinksFromWikidata(props)
if wikidata_sitelink then
hasdatafromwikidata = true -- signal up the chain this article has a wikidata claim
end
end
end
if wikidata_property or (props.url and props.url ~= '') or (props.url_f) then
if wikidata_property or (linkTemplate.url) or (linkTemplate.url_f) then
output[#output+1] = {}
output[1] = {
output[#output].langcode = string.find(props.langcode, "(SL.+)") and "" or props.langcode
langcode = string.find(linkTemplate.langcode, "SL.+") and "" or linkTemplate.langcode,
category = {}
--mw.log("findSiteLinksLocal - props="..dump(props).." langcode="..output[#output].langcode .." wikidata_values="..dump(wikidata_values))
}
output[#output].category = {}
--mw.log("findSiteLinksLocal - linkTemplate="..dump(linkTemplate).." langcode="..output[#output].langcode .." wikidata_values="..dump(wikidata_values))
if linkTemplate.track and wikidata_sitelink then
local local_value_in_wikidata = (wikidata_sitelink == local_value)
output[1].category[1] = mw.message.newRawMessage(cmodule:getMessage(contLangCode, (local_value_in_wikidata and 'track-cat-local-wd-equal' or 'track-cat-local-wd-unequal')), linkTemplate.prop):plain()
end
-- Search for a url formatter
local url = ''
local url = ''
if linkTemplate.url_f then
if props.track and wikidata_property and wikidata_values and #wikidata_values then
-- we have a locally defined url-formatter function from the config, use it as first priority
local local_value_in_wikidata = false
url = linkTemplate.url_f(local_value)
for _,value in ipairs( wikidata_values ) do
if linkTemplate.track then
if value.value == verified_value then
output[1].category[#output[1].category+1] = mw.message.newRawMessage(cmodule:getMessage(contLangCode, 'track-cat-local-local'), linkTemplate.prop):plain()
local_value_in_wikidata = true
end
end
end
elseif linkTemplate.url then
output[#output].category[#output[#output].category+1] = mw.message.newRawMessage(cmodule:getMessage(contLang:getCode(), (local_value_in_wikidata and 'track-cat-local-wd-equal' or 'track-cat-local-wd-unequal')), props.prop):plain()
-- we have a locally defined url-formatter string from the config, use it as second priority
end
url = mw.message.newRawMessage(linkTemplate.url, local_value):plain()
if wikidata_property and wikidata_values and #wikidata_values then
if linkTemplate.track then
hasdatafromwikidata = true -- signal up the chain this article has a wikidata claim
output[1].category[#output[1].category+1] = mw.message.newRawMessage(cmodule:getMessage(contLangCode, 'track-cat-local-local'), linkTemplate.prop):plain()
end
if props.url_f then
-- we have a local defined url-formatter function, use it as first priority
url = props.url_f(verified_value)
if props.track then
output[#output].category[#output[#output].category+1] = mw.message.newRawMessage(cmodule:getMessage(contLang:getCode(), 'track-cat-local-local'), props.prop):plain()
end
end
else -- we know wikidata_property exists
elseif props.url then
url = local_value:gsub(' ','_')
-- we have a local defined url-formatter string, use it as second priority
if linkTemplate.track then
url = mw.message.newRawMessage(props.url, verified_value):plain()
output[1].category[#output[1].category+1] = mw.message.newRawMessage(cmodule:getMessage(contLangCode, 'track-cat-wd-local'), linkTemplate.prop):plain()
if props.track then
output[#output].category[#output[#output].category+1] = mw.message.newRawMessage(cmodule:getMessage(contLang:getCode(), 'track-cat-local-local'), props.prop):plain()
end
end
elseif wikidata_property then
url = verified_value:gsub(' ','_')
if props.track then
output[#output].category[#output[#output].category+1] = mw.message.newRawMessage(cmodule:getMessage(contLang:getCode(), 'track-cat-wd-local'), props.prop):plain()
end
else
-- no other choice, bail out
return {}
end
local this_wiki = mw.getContentLanguage()
local this_wiki_code = this_wiki:getCode()
local langlink = (output[#output].langcode and output[#output].langcode ~= '' and output[#output].langcode ~= this_wiki_code) and mw.message.newRawMessage(conf:g('msg-langcode'), props.langcode, mw.language.fetchLanguageName(props.langcode, this_wiki_code)) or ""
if short_links and props.short then
output[#output].text =
mw.message.newRawMessage(props.short,
getLabel(nil, props.genitive, pagetitle),
url,
langlink,
verified_value,
mw.uri.encode(verified_value, 'PATH'))
:plain()
else
output[#output].text =
mw.message.newRawMessage(props.message,
getLabel(nil, props.genitive, pagetitle),
url,
langlink,
verified_value,
mw.uri.encode(verified_value, 'PATH'))
:plain()
end
end
local langlink = (output[1].langcode and output[1].langcode ~= '' and output[1].langcode ~= contLangCode)
and mw.message.newRawMessage(conf:g('msg-langcode'), linkTemplate.langcode, mw.language.fetchLanguageName(linkTemplate.langcode, contLangCode))
or ""
output[1].text =
mw.message.newRawMessage(short_links and linkTemplate.short or linkTemplate.message,
getLabel(nil, linkTemplate.genitive, pagetitle),
url,
langlink,
local_value,
mw.uri.encode(local_value, 'PATH'))
:plain()
end
end
--mw.log("findSiteLinksLocal returning="..dump(output))
--mw.log("findSiteLinksLocal returning="..dump(output))
Line 760: Line 446:


local function addLinkback(str, property)
local function addLinkback(str, property)
local id = mw.wikibase.getEntityObject()
local id = mw.wikibase.getEntityIdForCurrentPage()
if not id then
if not id then
return str
return str
end
if type(id) == 'table' then
id = id.id
end
end
Line 802: Line 485:
end
end
end
end
if args[argument] then
return args[argument]
return args[argument]
end
return nil
end
end




local function removeEntry(conf_claims, identifier, property)
local function removeEntry(conf_claims, identifier, property)
for i, props in ipairs(conf_claims) do
for i, linkTemplate in ipairs(conf_claims) do
if props[identifier] == property then
if linkTemplate[identifier] == property then
table.remove(conf_claims, i)
table.remove(conf_claims, i)
end
end
Line 818: Line 498:
end
end


function p.getLinks(frame)
function p.getLinks(frame, customClaims) --customClaims is a backdoor for testcases
local configured_conf = getArgument(frame, conf:a('arg-conf'))
local configured_conf = getArgument(frame, conf:a('arg-conf'))
if configured_conf then
if configured_conf then
Line 825: Line 505:
error(mw.message.newRawMessage(conf:g('missing-conf'), configured_conf):plain())
error(mw.message.newRawMessage(conf:g('missing-conf'), configured_conf):plain())
end
end
local conf_claims = customClaims or cmodule:getConfiguredClaims(contLangCode)
local output = {}
local category = {}
local conf_claims = cmodule:getConfiguredClaims(contLang:getCode())
local limits = cmodule:getLimits()
local limits = cmodule:getLimits()
assert(limits, mw.message.newRawMessage(conf:g('missing-limits'), configured_conf):plain())
assert(limits, mw.message.newRawMessage(conf:g('missing-limits'), configured_conf):plain())
local links_shown = getArgument(frame, conf:a('arg-maxlink'))
local links_shown = tonumber(getArgument(frame, conf:a('arg-maxlink'))) or limits['links-shown'] or 10 -- maximum links to display
local pagetitle = getArgument(frame, conf:a('arg-title'))
local pagetitle = getArgument(frame, conf:a('arg-title'))
-- get a list of tracked properties from the article itself
-- get a list of tracked properties from the article itself
Line 837: Line 517:
-- the properties should be written as P1234, P2345 and other
-- the properties should be written as P1234, P2345 and other
-- version corresponding to the applicable property-identifiers in the config
-- version corresponding to the applicable property-identifiers in the config
for track_prop in string.gmatch(requested_tracking,"([^ ,;:]+)") do
for track_prop in string.gmatch(requested_tracking,"[^ ,;:]+") do
-- get the requested properties and be able to access them
-- get the requested properties and be able to access them
-- like req_prop['P345'] to verify if it was requested
-- like req_prop['P345'] to verify if it was requested
local remove_track = string.match(track_prop, "^\-(.*)")
local remove_track = string.match(track_prop, "^%-(.*)")
for i,claim in ipairs ( conf_claims ) do
for i,claim in ipairs ( conf_claims ) do
if remove_track == claim.prop or remove_track == conf:a('mod-filter-all') then
if remove_track == claim.prop or remove_track == conf:a('mod-filter-all') then
-- if a property starts with "-", then we'll simply remove that
-- if a property starts with "-", then we'll simply remove that
-- property from the conf_claims
-- property from the conf_claims
conf_claims[i]['track'] = false
conf_claims[i].track = false
elseif track_prop == claim.prop or track_prop == conf:a('mod-filter-all') then
elseif track_prop == claim.prop or track_prop == conf:a('mod-filter-all') then
conf_claims[i]['track'] = true
conf_claims[i].track = true
end
end
end
end
Line 861: Line 541:
-- the properties should be written as P1234, P2345 and other
-- the properties should be written as P1234, P2345 and other
-- version corresponding to the applicable property-identifiers in the config
-- version corresponding to the applicable property-identifiers in the config
for i in string.gmatch(requested_properties,"([^ ,;:]+)") do
for i in string.gmatch(requested_properties,"[^ ,;:]+") do
-- get the requested properties and be able to access them
-- get the requested properties and be able to access them
-- like req_prop['P345'] to verify if it was requested
-- like req_prop['P345'] to verify if it was requested
Line 871: Line 551:
no_req_prop = true
no_req_prop = true
end
end
local remove_prop = string.match(i, "^\-(.*)")
local remove_prop = string.match(i, "^%-(.*)")
if remove_prop then
if remove_prop then
-- if a property starts with "-", then we'll simply remove that
-- if a property starts with "-", then we'll simply remove that
Line 877: Line 557:
conf_claims = removeEntry(conf_claims, 'prop', remove_prop)
conf_claims = removeEntry(conf_claims, 'prop', remove_prop)
elseif not no_req_prop then -- only if we are allowing properties to be filtered
elseif not no_req_prop then -- only if we are allowing properties to be filtered
req_prop[i] = 1
req_prop[i] = true
-- cheat to make #req_prop indicate populated table
-- cheat to make #req_prop indicate populated table
req_prop[1] = 1
req_prop[1] = true
end
end
end
end
Line 890: Line 570:
if requested_langs and requested_langs ~= '' then
if requested_langs and requested_langs ~= '' then
-- the languages should be written as langcodes as used in the conf_claims
-- the languages should be written as langcodes as used in the conf_claims
for i in string.gmatch(requested_langs,"([^ ,;:]+)") do
for i in string.gmatch(requested_langs,"[^ ,;:]+") do
-- get the requested languages and be able to access them
-- get the requested languages and be able to access them
if i == conf:a('mod-filter-all') then
if i == conf:a('mod-filter-all') then
Line 900: Line 580:
end
end
-- like req_lang['en'] to verify if it was requested
-- like req_lang['en'] to verify if it was requested
local remove_lang = string.match(i, "^\-(.*)")
local remove_lang = string.match(i, "^%-(.*)")
if remove_lang then
if remove_lang then
-- if a language starts with "-", then we'll simply remove that
-- if a language starts with "-", then we'll simply remove that
Line 906: Line 586:
conf_claims = removeEntry(conf_claims, 'langcode', remove_lang)
conf_claims = removeEntry(conf_claims, 'langcode', remove_lang)
elseif not no_req_lang then -- only if we are allowing languages to be filtered
elseif not no_req_lang then -- only if we are allowing languages to be filtered
req_lang[i] = 1
req_lang[i] = true
-- cheat to make #req_lang indicate populated table
-- cheat to make #req_lang indicate populated table
req_lang[1] = 1
req_lang[1] = true
end
end
end
end
end
end
local short_links = getArgument(frame, conf:a('arg-short'))
local short_links = getArgument(frame, conf:a('arg-short'))
if short_links and short_links ~= '' then
short_links = (short_links and short_links ~= '' or false)
short_links = true
else
short_links = false
end
local showinline = getArgument(frame, conf:a('arg-inline'))
local showinline = getArgument(frame, conf:a('arg-inline'))
if showinline and showinline ~= '' then
showinline = (showinline and showinline ~= '' or false)
showinline = true
else
showinline = false
end
if not links_shown or links_shown == '' then
links_shown = limits['links-shown'] and limits['links-shown'] or 5
else
links_shown = tonumber(links_shown)
end
local somedataonwikidata = not short_links
local somedataonwikidata = not short_links
--mw.log("conf_claims="..dump(conf_claims))
--mw.log("conf_claims="..dump(conf_claims))
Line 934: Line 603:
--mw.log("req_lang="..dump(req_lang))
--mw.log("req_lang="..dump(req_lang))
--mw.log("short_links="..dump(short_links))
--mw.log("short_links="..dump(short_links))
for _, props in ipairs(conf_claims) do
local output = {}
local category = {}
for _, linkTemplate in ipairs(conf_claims) do
-- if we're called with a list of approved properties or languages, check if this one is "approved"
-- if we're called with a list of approved properties or languages, check if this one is "approved"
if (#req_prop==0 or req_prop[props.prop]) and (#req_lang==0 or req_lang[props.langcode] or string.find(props.langcode, "([pP]%d+)")) then
if (#req_prop==0 or req_prop[linkTemplate.prop]) and (#req_lang==0 or req_lang[linkTemplate.langcode] or string.find(linkTemplate.langcode, "[pP]%d+")) then
-- Error if linkTemplate.prop is nonexistent, as it is required
--mw.log("checking claim="..dump(props))
assert(linkTemplate.prop, "malformed linkTemplate from config (no .prop given): " .. dump(linkTemplate))
local links = {}
local links = {}
local checkedonwikidata = false
local checkedonwikidata = false
-- get the any local overriding value from the call
-- get the any local overriding value from the call
local wikivalue = getArgument(frame, props.prop)
local wikivalue = getArgument(frame, linkTemplate.prop)
if (not wikivalue or wikivalue == "") and string.find(linkTemplate.prop, "[pP]%d+") then
--mw.log("wikivalue="..dump(wikivalue))
if (not wikivalue or wikivalue == "") and string.find(props.prop, "([pP]%d+)") then
-- the property is a Pnnn type, and therefore on Wikidata
-- the property is a Pnnn type, and therefore on Wikidata
links = findMainLinksOnWikidata(props, pagetitle, short_links)
links = findMainLinksOnWikidata(linkTemplate, pagetitle, short_links)
if links == nil then
if links == nil then
-- a nil-value indicated no wikidata-link
-- a nil-value indicated no wikidata-link
Line 953: Line 626:
checkedonwikidata = true
checkedonwikidata = true
end
end
elseif (not wikivalue or wikivalue == "") and string.find(props.prop, "(SL%l+)") then
elseif (not wikivalue or wikivalue == "") and string.find(linkTemplate.prop, "SL%l+") then
-- this is a sitelink-type (SLspecieswiki)
-- this is a sitelink-type (SLspecieswiki)
--mw.log("finding sitelinks..")
--mw.log("finding sitelinks..")
links = findSiteLinksOnWikidata(props, pagetitle, short_links)
links = findSiteLinksOnWikidata(linkTemplate, pagetitle, short_links)
if links == nil then
if links == nil then
-- a nil-value indicated no wikidata-link
-- a nil-value indicated no wikidata-link
Line 964: Line 637:
checkedonwikidata = true
checkedonwikidata = true
end
end
elseif (wikivalue and wikivalue ~= "") and string.find(props.prop, "(SL%l+)") then
elseif string.find(linkTemplate.prop, "SL%l+") then -- we know that wikivalue is set if this is true
-- this is a sitelink-type (SLspecieswiki)
-- this is a sitelink-type (SLspecieswiki)
links = findSiteLinksLocal(props, pagetitle, short_links, wikivalue)
links = findSiteLinksLocal(linkTemplate, pagetitle, short_links, wikivalue)
elseif wikivalue and wikivalue ~= '' then
elseif wikivalue and wikivalue ~= '' then
-- the property is of another annotation, and therefore a local construct
-- the property is of another annotation, and therefore a local construct
links = findMainLinksLocal(props, pagetitle, short_links, wikivalue)
links = findMainLinksLocal(linkTemplate, pagetitle, short_links, wikivalue)
end
end
--mw.log("links="..dump(links))
--mw.log("links="..dump(links))
Line 978: Line 651:
-- add a general tracking category for articles with data from wikidata
-- add a general tracking category for articles with data from wikidata
hasdatafromwikidata = true
hasdatafromwikidata = true
category[#category+1] = cmodule:getMessage(contLang:getCode(), 'with-data-cat')
category[#category+1] = cmodule:getMessage(contLangCode, 'with-data-cat')
elseif not checkedonwikidata and not hasdatafromlocal then
elseif not checkedonwikidata and not hasdatafromlocal then -- not checkonwikidata
-- add a general tracking category for articles with data from template-calls in local articles
-- add a general tracking category for articles with data from template-calls in local articles
hasdatafromlocal = true
hasdatafromlocal = true
category[#category+1] = cmodule:getMessage(contLang:getCode(), 'with-local-cat')
category[#category+1] = cmodule:getMessage(contLangCode, 'with-local-cat')
end
end
if short_links and props.short and v.text and v.text ~= '' then
if short_links and linkTemplate.short and v.text and v.text ~= '' then
-- if short links were requested, and a short definition exists for this property, let's use it
-- if short links were requested, and a short definition exists for this property, let's use it
if #output==0 then
if #output==0 then
output[#output+1] = v.text
output[1] = v.text
else
else
output[#output] = output[#output] .. cmodule:getMessage(contLang:getCode(),'short-list-separator') .. v.text
output[#output] = output[#output] .. cmodule:getMessage(contLangCode,'short-list-separator') .. v.text
end
end
somedataonwikidata = true
somedataonwikidata = true
elseif not short_links and not showinline and v.text and v.text ~= '' then
elseif not short_links and not showinline and v.text and v.text ~= '' then
-- only if short links were not requested
-- only if short links were not requested
output[#output+1] = (#output>=1 and conf:g('msg-ul-prepend') or '') -- if this is the first link, we won't output a list-element (msg-ul-prepend)
output[#output+1] = (#output ~= 0 and conf:g('msg-ul-prepend') or '') -- if this is the first link, we won't output a list-element (msg-ul-prepend)
.. (checkedonwikidata and addLinkback(v.text, props.prop) or v.text) -- if the link comes from wikidata, also output a linkback.
.. (checkedonwikidata and addLinkback(v.text, linkTemplate.prop) or v.text) -- if the link comes from wikidata, also output a linkback.
elseif not short_links and showinline and v.text and v.text ~= '' then
elseif not short_links and v.text and v.text ~= '' then -- and showinline
-- only if short links were not requested
-- only if short links were not requested
output[#output+1] = v.text
output[#output+1] = v.text
end
end
if props.track and v.category and #v.category then
if linkTemplate.track then
-- add category if tracking is on for this property and a category exists in the link-result.
-- add category if tracking is on for this property and a category exists in the link-result.
for _,cats in ipairs( v.category ) do
for _,cats in ipairs( v.category ) do
Line 1,006: Line 679:
end
end
end
end
if links_shown>0 then
if links_shown == 0 then -- abort if we've hit the maximum for number of links
links_shown = links_shown - 1
else
break
break
end
end
links_shown = links_shown - 1
end
end
end
end
Line 1,023: Line 695:
--mw.log("somedataonwikidata="..dump(somedataonwikidata).." and output="..dump(output).." and #output="..dump(#output))
--mw.log("somedataonwikidata="..dump(somedataonwikidata).." and output="..dump(output).." and #output="..dump(#output))
outtext = (somedataonwikidata
outtext = (somedataonwikidata
and addLinkback(table.concat(output,cmodule:getMessage(contLang:getCode(),'short-list-separator')), nil)
and addLinkback(table.concat(output,cmodule:getMessage(contLangCode,'short-list-separator')), nil)
or table.concat(output,cmodule:getMessage(contLang:getCode(),'short-list-separator')))
or table.concat(output,cmodule:getMessage(contLangCode,'short-list-separator')))
elseif not short_links and not showinline and #output>0 then
elseif not showinline and #output>0 then -- and not shortlinks
outtext = table.concat(output,"\n")
outtext = table.concat(output,"\n")
elseif not short_links and showinline and #output>0 then
elseif #output>0 then -- and not short_links and showinline
outtext = table.concat(output,conf:g('msg-inline-separator'))
outtext = table.concat(output,conf:g('msg-inline-separator'))
end
end
if not hasdatafromwikidata then
if not hasdatafromwikidata then
category[#category+1] = cmodule:getMessage(contLang:getCode(), 'no-data-cat')
category[#category+1] = cmodule:getMessage(contLangCode, 'no-data-cat')
if not hasdatafromlocal and not short_links then
if not hasdatafromlocal and not short_links then
outtext = cmodule:getMessage(contLang:getCode(), 'no-data-text')
outtext = cmodule:getMessage(contLangCode, 'no-data-text')
end
end
end
end
if not haswikidatalink then
if not haswikidatalink then
category[#category+1] = cmodule:getMessage(contLang:getCode(), 'no-wikilink-cat')
category[#category+1] = cmodule:getMessage(contLangCode, 'no-wikilink-cat')
if not hasdatafromlocal and not short_links then
if not hasdatafromlocal and not short_links then
outtext = cmodule:getMessage(contLang:getCode(), 'no-wikilink')
outtext = cmodule:getMessage(contLangCode, 'no-wikilink')
end
end
end
end
Line 1,051: Line 723:
function p.getLanguageCode(frame)
function p.getLanguageCode(frame)
local prop = getArgument(frame, conf:a('arg-properties'))
local prop = getArgument(frame, conf:a('arg-properties'))
local output = getLanguageData(prop)
return getLanguageData(prop, nil, conf:a(mod-filter-separator))
return table.concat(output, conf:a('mod-filter-separator'))
end
end