require('Modül:No globals')
local conf = require( "Modül:Taksonçubuğu/konf" ) -- configuration module
local TaxonItalics = require("Modül:Taksonİtalik") -- use a function from Module:TaxonItalics to italicize a taxon name
local function getIdsFromWikidata( item, property )
local ids = {}
if not item.claims[property] then
return ids
end
for _, statement in pairs( item.claims[property] ) do
if statement.mainsnak.datavalue then
table.insert( ids, statement.mainsnak.datavalue.value )
end
end
return ids
end
local function getLink( property, val )
local link, returnVal = "", {}
returnVal.isError = false
if mw.ustring.find( val, '//' ) then
link = val
else
if type(property) == 'number' and property > 0 then
local entityObject = mw.wikibase.getEntity('P'..property)
local dataType
if entityObject then dataType = entityObject.datatype
else returnVal.isError = true end
if dataType == "external-id" then
local formatterURL = entityObject:getBestStatements('P1630')[1]
if formatterURL then link = formatterURL.mainsnak.datavalue.value end
elseif dataType == "url" then
local subjectItem = entityObject:getBestStatements('P1629')[1]
if subjectItem then
local officialWebsite = mw.wikibase.getEntity(subjectItem.mainsnak.datavalue.value.id):getBestStatements('P856')[1]
if officialWebsite then link = officialWebsite.mainsnak.datavalue.value end
end
elseif dataType == "string" then
local formatterURL = entityObject:getBestStatements('P1630')[1]
if formatterURL then
link = formatterURL.mainsnak.datavalue.value
else
local subjectItem = entityObject:getBestStatements('P1629')[1]
if subjectItem then
local officialWebsite = mw.wikibase.getEntity(subjectItem.mainsnak.datavalue.value.id):getBestStatements('P856')[1]
if officialWebsite then link = officialWebsite.mainsnak.datavalue.value end
end
end
else
returnVal.isError = true
end
elseif type(property) == 'string' then
link = property
end
local valurl = val
if mw.ustring.find( link, 'antweb.org' ) then valurl = mw.ustring.gsub(valurl, " ", "%%20") end
valurl = mw.ustring.gsub(valurl,"%%","%%%%")
link = mw.ustring.gsub(link, '$1', valurl)
end
link = mw.ustring.gsub(link, '^[Hh][Tt][Tt][Pp]([Ss]?)://', 'http%1://') -- fix wikidata URL
val = mw.ustring.match(val, '([^=/]*)/?$') -- get display name from end of URL
if mw.ustring.find( link, '//' ) then
returnVal.text = '['..link..' '..mw.text.encode(mw.uri.decode(val, "PATH"),'%[%]')..']'
elseif link == "" then
returnVal.text = val
else
returnVal.text = '<span class="external">[['..link..'|'..val..']]</span>'
end
return returnVal
end
local function createRow( id, label, rawValue, link, withUid )
if link then
local outStr = '*<span style="white-space:nowrap;">' .. label .. ' <span'
if withUid then outStr = outStr..' class="uid"' end
return outStr..'>' .. link .. '</span></span>\n'
else
return '* ' .. mw.text.tag('span', {class='error'}, 'The identifier ' .. id .. ' ' .. rawValue .. ' is not valid.') .. '\n'
end
end
local function copyTable(inTable)
if type(inTable) ~= 'table' then return inTable end
local outTable = setmetatable({}, getmetatable(inTable))
for key, value in pairs (inTable) do outTable[copyTable(key)] = copyTable(value) end
return outTable
end
local p = {}
function p.authorityControlTaxon( frame )
local resolve = require( "Modül:GirdiIdsiniÇöz" )
local parentArgs = copyTable(frame:getParent().args)
local currentTitle = mw.title.getCurrentTitle()
local currentEntityId = mw.wikibase.getEntityIdForCurrentPage()
local stringArgs = false
local fromTitleCount, firstRow, rowCount = 1, 0, 0
local outString, errors = "", ""
local tfroms = {} --non-sequential table of unique froms
local ifroms = 0 --integer size of tfroms, b/c Lua
local categories = {
'[[Kategori:Parametre girilmemiş taksonçubukları]]',
"[[Kategori:Vikiveri'den kaldırılmış taksonçubukları]]",
'', -- [3] placeholder for [[Category:Taxonbars using multiple manual Wikidata items]]
'', -- [4] placeholder for [[Category:Taxonbars with invalid from parameters]]
'', -- [5] placeholder for [[Category:Taxonbars using manual taxon IDs]]
'', -- [6] placeholder for [[Category:Taxonbar pages requiring a Wikidata item]]
'', -- [7] placeholder for [[Category:Taxonbar pages without Wikidata taxon IDs]]
'', -- [8] placeholder for [[Category:Taxonbars with duplicate from parameters]]
'', -- [9] placeholder for [[Category:Taxonbars with manual taxon IDs differing from Wikidata]]
'', --[10] placeholder for [[Category:Taxonbars with manual taxon IDs identical to Wikidata]]
'', --[11] placeholder for [[Category:Taxonbars on possible non-taxon pages]]
'', --[12] placeholder for [[Category:Taxonbars with 20+ taxon IDs]]
'', --[13] placeholder for [[Category:Taxonbars with 25+ taxon IDs]]
'', --[14] placeholder for [[Category:Taxonbars with automatically added basionyms]]
'', --[15] placeholder for [[Category:Taxonbars with automatically added monotypic genera]]
'', --[16] placeholder for [[Category:Taxonbars of monotypic species missing genera]]
}
--Assess the page's relationship with Wikidata
local currentItem = nil
if currentTitle.namespace == 10 then --i.e. Module:Taxonbar/sandbox, Template:Taxonbar/doc, etc.
if resolve._entityid(frame, parentArgs['from']) then
currentItem = mw.wikibase.getEntity(parentArgs['from'])
end
if currentItem == nil then
if resolve._entityid(frame, parentArgs['from1']) then
currentItem = mw.wikibase.getEntity(parentArgs['from1'])
end
end
elseif resolve._entityid(frame, currentEntityId) then
currentItem = mw.wikibase.getEntity(currentEntityId)
else --currentEntityId == nil
categories[6] = '[[Kategori:Vikiveri nesnesine ihtiyaç duyan taksonçubukları]]'
end
if currentItem then
local acceptable = {
['Q16521'] = 'taxon',
['Q310890'] = 'monotypic taxon',
['Q2568288'] = 'ichnotaxon',
['Q23038290'] = 'fossil taxon',
['Q47487597'] = 'monotypic fossil taxon',
['Q42621'] = 'hybrid',
['Q235536'] = 'incertae sedis',
['Q713623'] = 'clade',
['Q848328'] = 'serotype',
['Q17487588'] = 'unavailable combination',
}
categories[11] = '[[Kategori:Takson sayfasında olmadığı tahmin edilen taksonçubukları]]' --unset if acceptable found
for _, instanceOfState in pairs ( currentItem:getBestStatements('P31') ) do --instance of
local instanceOf = instanceOfState.mainsnak.datavalue.value.id
if acceptable[instanceOf] then
categories[11] = ''
break
end
end
end
--Cleanup args
for k, v in pairs( frame:getParent().args ) do
if type(k) == 'string' then
--make args case insensitive
local lowerk = mw.ustring.lower(k)
if not parentArgs[lowerk] or parentArgs[lowerk] == '' then
parentArgs[k] = nil
parentArgs[lowerk] = v
end
--remap abc to abc1
if not mw.ustring.find(lowerk,"%d$") then --if no number at end of param
if not parentArgs[lowerk..'1'] or parentArgs[lowerk..'1'] == '' then
parentArgs[lowerk] = nil
lowerk = lowerk..'1'
parentArgs[lowerk] = v
end
end
if v and v ~= '' then
--remap "for" to "title"
if mw.ustring.sub(lowerk,1,3) == "for" then
local forTitle = mw.ustring.gsub(lowerk,"^for","title",1)
if parentArgs[forTitle] == '' or not parentArgs[forTitle] then
parentArgs[lowerk] = nil
lowerk = forTitle
parentArgs[lowerk] = v
end
end
--find highest from or title param
if mw.ustring.sub(lowerk,1,4) == "from" then
local fromNumber = tonumber(mw.ustring.sub(lowerk,5,-1))
if fromNumber and fromNumber >= fromTitleCount then fromTitleCount = fromNumber end
--look for duplicate froms while we're here
if mw.ustring.find(v, "^Q%d") then
if tfroms[v] then
categories[8] = '[[Kategori:Parametresi tekrar eden taksonçubukları]]'
tfroms[v] = tfroms[v] + 1
else
tfroms[v] = 1
ifroms = ifroms + 1
end
if ifroms > 1 then
categories[3] = '[[Kategori:Birden fazla elle eklenmiş Vikiveri nesneli taksonçubukları]]'
end
end
elseif mw.ustring.sub(lowerk,1,5) == "title" then
local titleNumber = tonumber(mw.ustring.sub(lowerk,4,-1))
if titleNumber and titleNumber >= fromTitleCount then fromTitleCount = titleNumber end
elseif mw.ustring.lower(v) ~= 'no' then
stringArgs = true
categories[5] = '[[Kategori:Elle eklenmiş ID kullanan taksonçubukları]]'
end
end
end
end
--Append basionym to arg list, if not already provided
if currentItem then
local currentBasState = currentItem:getBestStatements('P566')[1] --basionym
if currentBasState then
local basionymId = currentBasState.mainsnak.datavalue.value.id
if basionymId and resolve._entityid(frame, basionymId) and tfroms[basionymId] == nil then
--check that basionym is a strict instance of taxon
local basionymItem = mw.wikibase.getEntity(basionymId)
if basionymItem then
local acceptable = {
['Q16521'] = 'takson',
['Q310890'] = 'monotypic taxon',
['Q2568288'] = 'ichnotaxon',
['Q23038290'] = 'fosil takson',
['Q47487597'] = 'monotypic fosil takson',
}
for _, instanceOfState in pairs ( basionymItem:getBestStatements('P31') ) do --instance of
local instanceOf = instanceOfState.mainsnak.datavalue.value.id
if acceptable[instanceOf] then
--housekeeping
tfroms[basionymId] = 1
ifroms = ifroms + 1
fromTitleCount = fromTitleCount + 1
--append basionym & track
parentArgs['from'..fromTitleCount] = basionymId
categories[14] = '[[Kategori:Bilimsel adıyla çalışan otomatik taksonçubukları]]'
break
end end end end end end
--Append monotypic genus/species to arg list of monotypic species/genus, if not already provided
if currentItem then
for _, instanceOfState in pairs ( currentItem:getBestStatements('P31') ) do --instance of
local taxonRank = nil
local parentItem = nil
local parentTaxon = nil
local parentTaxonRank = nil
local parentMonoGenus = nil --holy grail/tbd
local instanceOf = instanceOfState.mainsnak.datavalue.value.id
if instanceOf and (instanceOf == 'Q310890' or instanceOf == 'Q47487597') then --monotypic/fossil taxon
local taxonRankState = currentItem:getBestStatements('P105')[1] --taxon rank
if taxonRankState then taxonRank = taxonRankState.mainsnak.datavalue.value.id end
if taxonRank and taxonRank == 'Q7432' then --species
--is monotypic species; add genus
local parentTaxonState = currentItem:getBestStatements('P171')[1] --parent taxon
if parentTaxonState then parentTaxon = parentTaxonState.mainsnak.datavalue.value.id end
--confirm parent taxon rank == genus & monotypic (too careful/expensive? remove/mod this first if hitting any request limits)
if parentTaxon and resolve._entityid(frame, parentTaxon) then
parentItem = mw.wikibase.getEntity(parentTaxon)
if parentItem then
local parentTaxonRankState = parentItem:getBestStatements('P105')[1] --taxon rank
if parentTaxonRankState then parentTaxonRank = parentTaxonRankState.mainsnak.datavalue.value.id end
if parentTaxonRank and parentTaxonRank == 'Q34740' then -- genus
for _, parentInstanceOfState in pairs ( parentItem:getBestStatements('P31') ) do --instance of
local parentInstanceOf = parentInstanceOfState.mainsnak.datavalue.value.id
if parentInstanceOf and
(parentInstanceOf == 'Q310890' or parentInstanceOf == 'Q47487597') then --monotypic/fossil taxon
parentMonoGenus = parentTaxon --confirmed
break
end
end
if parentMonoGenus and tfroms[parentMonoGenus] == nil then
--housekeeping
tfroms[parentMonoGenus] = 1
ifroms = ifroms + 1
fromTitleCount = fromTitleCount + 1
--append monotypic genus & track
parentArgs['from'..fromTitleCount] = parentMonoGenus
categories[15] = '[[Kategori:Monotipik cinsiyle otomatik çalışan taksonçubukları]]'
break
end
end
end
end
if parentMonoGenus == nil or tfroms[parentMonoGenus] == nil then
categories[16] = '[[Kategori:Cinsi eksik olan monotipik tür taksonçubukları]]'
break
end
elseif taxonRank and taxonRank == 'Q34740' then --genus
--is monotypic genus; add species
--...
end
end
end
end
--Setup navbox
local navboxParams = {
ad = 'Taksonçubuğu',
['gövdesınıfı'] = 'hlist',
['listesınıfı'] = '',
['grupbiçimi'] = 'text-align: left;',
}
for f = 1,fromTitleCount,1
do
local elements, title = {}, nil
--cleanup parameters
if parentArgs['from'..f] == '' then parentArgs['from'..f] = nil end
if parentArgs['title'..f] == '' then parentArgs['title'..f] = nil end
--remap aliases
for _, a in pairs( conf.aliases ) do
local alias, name = mw.ustring.lower(a[1]), mw.ustring.lower(a[2])
if parentArgs[alias..f] and not parentArgs[name..f] then
parentArgs[name..f] = parentArgs[alias..f]
parentArgs[alias..f] = nil
end
end
--Fetch Wikidata item
local from = resolve._entityid(frame, parentArgs['from'..f])
local item = mw.wikibase.getEntity(from)
local label = nil
if type(item) == 'table' then
local statements = item:getBestStatements('P225')[1] --taxon name
if statements then
local datavalue = statements.mainsnak.datavalue
if datavalue then
label = datavalue.value
end
end
label = label or item:getLabel()
else
if parentArgs['from'..f] then
categories[1] = ''
categories[4] = '[[Kategori:Parametresi geçersiz taksonçubukları]]'
errors = errors .. mw.text.tag('strong', {class='error'}, 'Error: "' ..
parentArgs['from'..f] .. '" is not a valid Wikidata entity ID.<br />')
end
end
if label and label ~= '' then
title = mw.title.new(label)
end
if not title and parentArgs['title'..f] then
title = mw.title.new(parentArgs['title'..f])
end
if not title and f == 1 then
title = currentTitle
end
if title then
if (not parentArgs['wikidata'..f] or parentArgs['wikidata'..f] == '') and
(title.namespace == 0) then
if parentArgs['from'..f] then
parentArgs['wikidata'..f] = parentArgs['from'..f]
elseif item then
parentArgs['wikidata'..f] = item.id
end
end
if title.namespace == 0 or stringArgs then --Only in the main namespace or if there are manual overrides
local sourcesFound = false
local sourceCount = 0
for _, params in pairs( conf.databases ) do
params[1] = mw.ustring.lower(params[1])
local propId = params[3]
--Wikidata fallback if requested
if (item ~= nil and item.claims ~= nil) and
(type(propId) == 'string' or (type(propId) == 'number' and propId > 0)) then
local wikidataIds = getIdsFromWikidata( item, 'P' .. propId )
local v = parentArgs[params[1]..f]
if wikidataIds[1] then
if (not v or v == '') then
parentArgs[params[1]..f] = wikidataIds[1]
else
if v and v ~= 'no' and v ~= wikidataIds[1] then
categories[9] = "[[Kategori:Elle eklenmiş ID'si Vikiveri'dekinden farklı olan taksonçubukları]]"
elseif v and v == wikidataIds[1] then
categories[10] = "[[Kategori:Elle eklenmiş ID'si Vikiveri'deki ile aynı olan taksonçubukları]]"
end
end
end
end
local val = parentArgs[params[1]..f]
if val and val ~= '' and mw.ustring.lower(val) ~= 'no' then
if type(propId) == 'number' then
if propId < 0 then propId = -propId end --allow link
if propId > 0 then --link
table.insert( elements, createRow( params[1], params[2]..':', val, getLink( propId, val ).text, true ) )
else --propId == 0; no link
table.insert( elements, createRow( params[1], params[2]..':', val, val, true ) )
end
else
table.insert( elements, createRow( params[1], params[2]..':', val, getLink( propId, val ).text, true ) )
end
if params[1] ~= 'wikidata' then
sourcesFound = true
sourceCount = sourceCount + 1
end
end
end
if sourceCount >= 20 then categories[12] = "[[Kategori:20'den fazla ID'ye sahip taksonçubukları]]" end
if sourceCount >= 25 then categories[13] = "[[Kategori:25'den fazla ID'ye sahip taksonçubukları]]" end
--Generate navbox title
if sourcesFound then
rowCount = rowCount + 1
if firstRow == 0 then firstRow = f end
--set title from wikidata if it doesn't exist
if parentArgs['title'..f] == '' or not parentArgs['title'..f] then
parentArgs['noTitle'..f] = true
parentArgs['title'..f] = title.text
end
--if it exists now, set row heading to title
if parentArgs['title'..f] and parentArgs['title'..f] ~= '' then
navboxParams['grup'..f] = TaxonItalics.italicizeTaxonName(parentArgs['title'..f], false)
else
navboxParams['grup'..f] = ""
end
navboxParams['liste'..f] = table.concat( elements )
elseif currentEntityId then
categories[7] = "[[Kategori:Vikiveri takson ID'si olmayan taksonçubukları]]"
end
--Categorize
if parentArgs['from'..f] and parentArgs['from'..f] ~= '' then
--blank "missing from" if 'from' exists
categories[1] = ''
--blank "desynced" if 'from' matches current page
if parentArgs['from'..f] == currentEntityId then categories[2] = '' end
end
--cannot be "desynced" if no 'from' params
if categories[1] ~= '' then categories[2] = '' end
end
end
end
if rowCount > 0 then
local Navbox = require('Modül:Dolaşım')
if rowCount > 1 then
--remove duplicates and move page title to top
local rowIDs = {}
for f = 1,fromTitleCount,1
do
if parentArgs['title'..f] and parentArgs['title'..f] ~= '' then
if rowIDs[parentArgs['wikidata'..f]] then --remove duplicate
navboxParams['grup'..f] = nil
navboxParams['liste'..f] = nil
else
rowIDs[parentArgs['wikidata'..f]] = true
if f > firstRow and (parentArgs['title'..f] == currentTitle.text or
parentArgs['wikidata'..f] == currentEntityId) then --move item linked to page to top
if navboxParams['grup'..f] and
navboxParams['grup'..f] ~= '' and
navboxParams['liste'..f] and
navboxParams['liste'..f] ~= '' then
local tempGroup, tempList = navboxParams['grup'..f], navboxParams['liste'..f]
navboxParams['grup'..f], navboxParams['liste'..f] = navboxParams['grup'..firstRow], navboxParams['liste'..firstRow]
navboxParams['grup'..firstRow], navboxParams['liste'..firstRow] = tempGroup, tempList
end
end
end
end
end
--adjust navbox for number of rows
navboxParams['başlık'] = "[[Yardım:Takson belirleyicileri|Takson belirleyicileri]]"
if rowCount > 2 then
navboxParams['dolçub'] = 'plain'
else
navboxParams['durum'] = 'off'
navboxParams['dolçub'] = 'off'
end
elseif parentArgs['noTitle'..firstRow] then
navboxParams['grup'..firstRow] = '[[Yardım:Takson belirleyicileri|Takson belirleyicileri]]'
else
navboxParams['grup'..firstRow] = '[[Yardım:Takson belirleyicileri|Takson belirleyicileri]]<br />' .. navboxParams['grup'..firstRow]
end
--return navbox
outString = Navbox._navbox(navboxParams)
end
--add categories
if string.sub(currentTitle.subpageText,1,9) == 'testcases' then parentArgs['demo'] = true end
if parentArgs['demo'] and parentArgs['demo'] ~= '' then
outString = outString .. mw.text.nowiki(table.concat(categories)) .. '<br />'
elseif currentTitle.namespace == 0 then
outString = outString .. table.concat(categories)
end
return outString .. errors
end
return p