Modul:External links

Fra Wikisida.no
Sideversjon per 30. mar. 2016 kl. 00:45 av nb>Stigmj (litt forenkling av test. scriptet vil feile uansett hvis conf er feil.)
Hopp til navigering Hopp til søk

Modulen "External links" inneholder følgende metoder som er ment brukt via maler

getLinks
Henter eksterne lenker fra Wikidata i henhold til en konfigurasjonsfil
Funksjonen har noen få felles standard-parametre som kan benyttes
conf
Funksjonen kalles opp slik: {{#invoke:External links|getLinks|conf=...}}
Den vil da returnere en rekke formaterte lenker til eksterne sider i henhold til en konfigurasjon som ligger som undersider av denne modulen.
Følgende konfigurasjoner er tilgjengelige
  • Arter - Artslenker, Kalles opp slik: {{#invoke:External links|getLinks|conf=Arter}}. Se {{Artslenker}} for eksempel på bruk.
  • Astronomi - Astronomi, Kalles opp slik: {{#invoke:External links|getLinks|conf=Astronomi}}. Se {{Astronomilenker}} for eksempel på bruk.
  • Autoritetsdata - Autoritetsdata, Kalles opp slik: {{#invoke:External links|getLinks|conf=Autoritetsdata}}. Se {{Autoritetsdata}} for eksempel på bruk.
  • Bryggeri - Bryggerilenker, Kalles opp slik: {{#invoke:External links|getLinks|conf=Bryggeri}}. Se {{Bryggerilenker}} for eksempel på bruk.
  • Film - Filmlenker, Kalles opp slik: {{#invoke:External links|getLinks|conf=Film}}. Se {{Filmlenker}} for eksempel på bruk.
  • Filmperson - Filmpersonlenker, Kalles opp slik: {{#invoke:External links|getLinks|conf=Filmperson}}. Se {{Filmperson}} for eksempel på bruk.
  • Musikk - Musikklenker, Kalles opp slik: {{#invoke:External links|getLinks|conf=Musikk}}. Se {{Musikklenker}} for eksempel på bruk.
  • Offisielle lenker - Offisielle lenker, Kalles opp slik: {{#invoke:External links|getLinks|conf=Offisielle lenker}}. Se {{Offisielle lenker}} for eksempel på bruk.
  • Politiker - Politiker, Kalles opp slik: {{#invoke:External links|getLinks|conf=Politiker}}. Se {{Politiker}} for eksempel på bruk.
  • Some - Sosiale medie-lenker, Kalles opp slik: {{#invoke:External links|getLinks|conf=Some}}. Se {{Somelenker}} for eksempel på bruk.
  • Spill - Spill-lenker, Kalles opp slik: {{#invoke:External links|getLinks|conf=Spill}}. Se {{Spill-lenker}} for eksempel på bruk.
  • Sport - Sportslenker, Kalles opp slik: {{#invoke:External links|getLinks|conf=Sport}}. Se {{Sportslenker}} for eksempel på bruk.
  • Skip - Skipslenker, Kalles opp slik: {{#invoke:External links|getLinks|conf=Skip}}. Se {{Skipslenker}} for eksempel på bruk.
  • Forsker - Forskerlenker, Kalles opp slik: {{#invoke:External links|getLinks|conf=Forsker}}. Se {{Forskerlenker}} for eksempel på bruk.
  • Test - For testing av nye typer og utvikling, Kalles opp slik: {{#invoke:External links|getLinks|conf=Test}}. Skal ikke benyttes i produksjon.
tittel
Funksjonen kalles opp slik: {{#invoke:External links|getLinks|conf=<konfigurasjon ihht. ovenfor>|tittel=...}}
Denne parameteren kan overstyre artikkelnavnet som benyttes videre i modulen. Hvis dette ikke er satt, vil den som standard bruke sidenavnet til artikkelen.
maxlink
Funksjonen kalles opp slik: {{#invoke:External links|getLinks|conf=<konfigurasjon ihht. ovenfor>|maxlink=...}}
Denne parameteren setter maksimum antall lenker som vises frem. Standardverdien er satt til 10.
prop
Funksjonen kalles opp slik: {{#invoke:External links|getLinks|conf=<konfigurasjon ihht. ovenfor>|prop=<egenskap>,<egenskap2>,...}}
Denne parameteren setter en begrensning på hvilke egenskaper som skal vises frem. De skilles av med et komma, mellomrom, semikolon eller kolon. Dersom egenskapen starter med et minus-tegn (-), f.eks. -P345, så vil alle egenskaper, unntatt den som er angitt forsøkes vist frem. Det er mulig å legge inn flere av disse.
kort
Funksjonen kalles opp slik: {{#invoke:External links|getLinks|conf=<konfigurasjon ihht. ovenfor>|kort=1}}
Denne parameteren bestemmer om kort-versjonen av lenkene skal benyttes.
inline
Funksjonen kalles opp slik: {{#invoke:External links|getLinks|conf=<konfigurasjon ihht. ovenfor>|inline=1}}
Denne parameteren bestemmer om lenkene skal legges på en linje med en separator i mellom seg. Linjen vil ikke prefikses med noen bullet eller lignenden. Se definisjonen av separatoren i Module:External links/conf under ['msg-inline-separator']. Denne funksjonaliteten er ment brukt i tilfeller hvor man ønsker å benytte lenkene i referanser eller lignende.
språk
Funksjonen kalles opp slik: {{#invoke:External links|getLinks|conf=<konfigurasjon ihht. ovenfor>|språk=<langcode1>,<langcode2>...}}
Denne parameteren setter en begrensning på hvilke språk som skal vises frem. De skilles av med et komma, mellomrom, semikolon eller kolon. Dersom språkkoden starter med et minus-tegn (-), f.eks. -fr, så vil alle språkkoder, unntatt den vises frem. Det er mulig å legge inn flere av disse. Spesial-verdien alle overstyrer og tillater alle språk.
track
Funksjonen kalles opp slik: {{#invoke:External links|getLinks|conf=<konfigurasjon ihht. ovenfor>|track=<egenskap1>,<egenskap2>...}}
Denne parameteren styrer individuelle sporingskategorier for hver egenskap. De skilles av med et komma, mellomrom, semikolon eller kolon. Dersom egenskapen starter med et minus-tegn (-), f.eks. -P345, så vil den ikke spores (i tilfelle den er konfigurert til å spores i felleskonfigurasjonen). Det er mulig å legge inn flere av disse, og spesial-koden alle vil slå på sporing på alle.
<egenskapsnavn>
Funksjonen kalles opp slik: {{#invoke:External links|getLinks|conf=<konfigurasjon ihht. ovenfor>|<egenskapsnavn>=<verdi>}}
Dette er en generell måte å sette verdien til en egenskap manuelt fra artikler/maler. Dette er ment brukt for tilfeller hvor man bruker en lokalt definert egenskap og trenger å gi den en verdi fra artikkelen. F.eks. bbfc=46443 vil gi ID-en til Blue Thunder i BBFc sin database, og den manuelle definisjonen av bbfc i Module:External links/conf/Film vil da benyttes sammen med den ID-en for å bygge den eksterne lenken.

Se også


require('Module:No globals')
local genitiv = require('Modul:Genitiv')._genitiv
local contLang = mw.language.getContentLanguage()

local cmodule = {}
local conf = require 'Module:External links/conf'(contLang:getCode())

local p = {}


local function getLabel(entity, use_genitiv)
	if not entity then
		local label = mw.title.getCurrentTitle().text
	else
		local label = mw.wikibase.label(entity.id) or mw.title.getCurrentTitle().text
	return use_genitiv and genitiv(label) or label
	end
end

-- @todo cleanup, this is in production, use the console
local function dump(obj)
	return "<pre>" .. mw.dumpObject(obj) .. "</pre>"
end


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

local qual = {}
qual.P1793 = {
	types = {
		snaktype = 'value',
		datatype = 'string',
	},
}


local qorder = {'P1793'}

-- 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
-- in very few cases)
local function regexConverter( regex )
	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 output
end


local function getFormatterUrl( prop, value )
	local head = ""
	local tail = ""
	local entity = mw.wikibase.getEntity(prop)
	-- to avoid deep tests
	if not entity or not entity.claims then
		return head
	end
	-- get the claims for this entity
	local statements = entity.claims['P1630']
	-- to avoid deep tests
	if not statements then
		return head
	end
	local formatters = {}
	-- let's go through the claims
	for _, claim in ipairs( statements ) do
		-- to avoid deep tests
		if not claim then
			claim = {}
		end
		local valid = claim['type'] == 'statement'
			and claim['rank'] ~= 'deprecated'
		if valid then
			local mainsnak = claim.mainsnak or {}
			--mw.log("mainsnak = " .. dump(mainsnak))
			local preferred = claim['rank'] == 'preferred'
			-- get any qualifiers for this claim (we are interested in P1793 for
			-- indication of which claim is correct) 
			local qualifiers = claim.qualifiers or {}
			-- now go through the qualifiers we are interested in (defined in
			-- the array qorder above this function)
			for _, qualid in ipairs( qorder ) 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 qual[qualid] and qualid == 'P1793' then
							--mw.log("qualsnak = " .. dump(qualsnak))
							-- check if the snak is of the correct snaktype and datatype
							local valid = qualsnak.snaktype == qual[qualid].types.snaktype
								and qualsnak.datatype == qual[qualid].types.datatype
							if valid then
								-- it is, so let's check if it matches the url
								-- (P1793 = regex expression)
								--mw.log("qualsnak.datavalue="..dump(qualsnak.datavalue))
								-- we'll have to convert the regex to Lua-style
								local regex = regexConverter(qualsnak.datavalue.value)
								--mw.log("regex="..dump(regex) .. " and value=" .. dump(value))
								local test = string.match( value, '^'..regex..'$' )
								--mw.log("testing with "..regex.. " and test="..dump(test).." and value="..value)
								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
							--mw.log("mainsnak.datavalue="..dump(mainsnak.datavalue))
							tail = mainsnak.datavalue.value
						end
					end
				end
			end
		end
	end
	--mw.log("head="..head.." and tail="..tail)
	return head ~= '' and head or tail

end


local function findMainLinks(props)
	local output = {}
	-- get the entity we are checking
	local entity = mw.wikibase.getEntityObject()
	-- to avoid deep tests
	if not entity then
		return nil
	end
	if not entity.claims then
		return output
	end
	-- get the claims for this entity
	local statements = entity.claims[props.prop]
	-- to avoid deep tests
	if not statements then
		return output
	end
	-- let's go through the claims
	for _, claim in ipairs( statements ) do
		-- to avoid deep tests
		if not claim then
			claim = {}
		end
		local valid = claim['type'] == 'statement'
			and claim['rank'] ~= 'deprecated'
		if valid then
			local mainsnak = claim.mainsnak or {}
			local preferred = claim['rank'] == 'preferred'
			-- get the content of the claim (the identifier)
			local value = stringFormatter(mainsnak.datavalue)
			--mw.log("value="..dump(value))
			if value then
				-- get the formatvalue from the property
				local formatterUrl = getFormatterUrl(props.prop, value)
				--mw.log("formatterUrl="..dump(formatterUrl))
				if formatterUrl ~= '' then
					output[#output+1] = {}
					output[#output].langcode = props.langcode
					output[#output].text =
						mw.message.newRawMessage(props.message,
							getLabel(entity, props.genitiv),
							mw.message.newRawMessage(formatterUrl, value):plain())
						:plain()
				end
			end
		end
	end
	--mw.log("returning output="..dump(output))
	return output
end

local function addLinkback(str, property)
	local id = mw.wikibase.getEntityObject()
	if not id then
		return str
	end
	if type(id) == 'table' then
		id = id.id
	end
	
	local class = ''
	if property then
		class = 'wd_' .. string.lower(property)
	end
	local title = conf:g('wikidata-linkback-edit')
	local icon = '[%s [[File:Blue pencil.svg|%s|10px|baseline|link=]] ]'
	local url = mw.uri.fullUrl('d:' .. id .. '#' .. property)
	url.fragment = property
	url = tostring(url)
	local v = mw.html.create('span')
		:addClass(class)
		:wikitext(str)
		:tag('span')
			:addClass('noprint plainlinks wikidata-linkback')
			:css('padding-left', '.5em')
			:wikitext(icon:format(url, title))
		:allDone()
	return tostring(v)
end

local function getArgument(frame, argument)
	local args = frame.args
	if args[1] == nil then
		local pFrame = frame:getParent();
		args = pFrame.args;
		for k,v in pairs( frame.args ) do
			args[k] = v;
		end
	end
	if args[argument] then
		return args[argument]
	end
	return nil
end

function p.getLinks(frame)
	local configured_conf = getArgument(frame, 'conf')
	if configured_conf then
		cmodule = require ('Module:External_links/conf/'..configured_conf)
	else
		error(mw.message.newRawMessage(conf:g('missing-conf'), configured_conf):plain())
	end
	local output = {}
	local conf_claims = cmodule:getConfiguredClaims(contLang:getCode())
	local limits = cmodule:getLimits()
	assert(limits, mw.message.newRawMessage(conf:g('missing-limits'), configured_conf):plain())
	local links_shown = limits['links-shown'] and limits['links-shown'] or 10
	--mw.log(dump(conf_claims))
	for _, props in ipairs(conf_claims) do
		local links = findMainLinks(props)
		if links == nil then
			return cmodule:getNoWikilink(contLang:getCode())
		end
		for _,v in ipairs(links) do
			--  calling out to templates are bad style
			output[#output+1] = "* "
				.. (v.langcode and frame:expandTemplate{ title="Språkikon", args = { v.langcode } } .. " " or "")
				.. addLinkback(v.text, props.prop)
			if links_shown>0 then
				links_shown = links_shown - 1
			else
				break
			end
		end
		if links_shown==0 then
			break
		end
	end
	output = table.concat(output,"\n")
	return cmodule:getText(contLang:getCode(), output) .. cmodule:getCategory(contLang:getCode(), output)
end

return p