Modul:Marker

Aus Wikivoyage
Zur Navigation springen Zur Suche springen
Template-info.png Dokumentation für das Modul Marker[Ansicht] [Bearbeiten] [Versionsgeschichte] [Aktualisieren]

Dieses Modul enthält Funktionen zur Darstellung von Karten-Markern. Die Funktionen des Moduls werden nicht direkt aufgerufen, sondern über die Vorlage {{Marker}}.

Versionsbezeichnung auf WikiData: 2020-07-06

Funktionen

function mk.marker( frame )

Die Funktion prüft die Parameter der Vorlage {{Marker}} und führt die Markerdarstellung aus. Die möglichen Parameter sind in der Vorlage {{Marker}} beschrieben. Im Projektnamensraum befindet sich die technische Dokumentation.

Benötigte weitere Module

Dieses Modul benötigt folgende weitere Module: CountryData • Failsafe • FastWikidata • Marker/Params • MarkerBase/Maki icons • MarkerBase • MarkerBase/i18n • Yesno
Hinweise
-- documentation
local Marker = {
	suite  = 'Marker',
	serial = '2020-07-06',
	item   = 40852170
}

-- module import
local mb = require( 'Module:MarkerBase' )
local mi = require( 'Module:MarkerBase/i18n' )
local mm = require( 'Module:MarkerBase/Maki icons' )
local mp = require( 'Module:Marker/Params' )

local cm = require( 'Module:CountryData' )
local fs = require( 'Module:Failsafe' )
local fw = require( 'Module:FastWikidata' )
local lg = require( 'Module:Languages' )
local yn = require( 'Module:Yesno' )

-- module variable
local mk = {}

local function checkYn( keys, args )
	local s = ''
	for i, key in ipairs( keys ) do
		if not args[ key ] then
			args[ key ] = ''
		end
		s = yn( args[ key ], nil )
		if s ~= nil then -- then args.url is boolean
			args[ key ] = ''
			mp.wdContent[ key ] = s
		elseif args[ key ] ~= '' then
				mp.wdContent[ key ] = false
		end
	end
end

local function initialParameterCheck( templateArgs )
	local entity = nil
	local wrongQualifier = false
	local args = {}
	local show = {}

	-- checking keys and copying values to args
	for key, value in pairs( mp.p ) do
		args[ value ] = ''
	end
	for key, value in pairs( templateArgs ) do
		value, _ = mb.removeCtrls( value, true )

		if mp.p[ key ] then
			args[ mp.p[ key ] ] = value
		else
			mb.addWrongParameter( key )
		end
	end

	-- checking format and show parameters
	if args.show and args.show ~= '' then
		show = mb.getShow( mp.defaultShow, args.show, mp.show )
		if show.noname then
			show.noname = nil
			show.name = nil
		else
			show.name = ''
		end
		if not next( show ) then
			show.name = ''
		end
	else
		if not args.format:match( mp.formats.allowed ) then
			if args.format ~= '' then
				mb.addMaintenance( mi.maintenance.unknownFormat )
			end
			args.format = mp.formats.default
		end
		if args.format == mp.formats.poiMode then
			mb.addMaintenance( mi.maintenance.poiMode )
		end
		for key, value in ipairs( { 'poi', 'name', 'coord' } ) do
			show[ value ] = args.format:match( mp.formats[ value ] )
		end
	end

	-- checking Wikidata entitity
	args.wikidata, entity, wrongQualifier = fw.getEntityId( args.wikidata or '' )
	if wrongQualifier then
		mb.addMaintenance( mi.maintenance.wrongQualifier )
	elseif args.wikidata ~= '' then
		mb.addMaintenance( mi.maintenance.wikidata )
	end

	-- treatment of social media services
	if args.wikidata ~= '' then
		if show.socialmedia then
			for i, value in ipairs( mp.socialMedia ) do
				if not args[ value ] then
					args[ value ] = true
				end
			end
		end
	end
	-- y/n allow/disallow output
	checkYn( mp.ynCheckList, args )
	args.noGpx = yn( args.noGpx, false )

	-- checking coordinates and converting DMS to decimal coordinates if necessary
	args.lat, args.long = mb.checkCoordinates( args.lat, args.long )

	args.zoom = math.floor( tonumber( args.zoom ) or mi.defaultZoomLevel )
	if args.zoom < 0 or args.zoom > mi.maxZoomLevel then
		args.zoom = mi.defaultZoomLevel
	end
	if args.image ~= '' then
		args.image = mb.checkImage( args.image, entity )
	end
	if args.commonscat ~= '' then
		args.commonscat = mb.checkCategory( args.commonscat )
	end
	if args.commonscat ~= '' then
		mb.addMaintenance( mi.maintenance.commonscat )
	end

	return args, entity, show
end

-- getting data from Wikidata
local function getDataFromWikidata( args, show, country, entity )
	if args.wikidata == '' then
		return
	end

	local s, t
	if args.name == '' then
		args.name = fw.getLabel( entity )
			or mi.langs.name ~= '' and fw.getLabel( entity, mi.langs.name )
			or ''
		mp.wdContent.name = args.name ~= ''
		if args.name ~= '' then
			mb.addMaintenance( mi.maintenance.nameFromWD )
		end
	end
	if args.nameLocal == '' then
		args.nameLocal = fw.getLabel( entity, country.lang ) or ''
	end
	if args.name == '' and args.nameLocal ~= '' then
		args.name = args.nameLocal
		args.nameLocal = ''
		mb.addMaintenance( mi.maintenance.nameFromWD )
	end
		
	if args.type == '' then
		s = fw.getValues( entity, mp.wd.type.p, mi.p31Limit )
		args.type = mb.typeSearch( s )
		if args.type ~= '' then
			mb.addMaintenance( mi.maintenance.typeFromWD )
		end
	end

	if args.lat == '' or args.long == '' then
		s = mb.getCoordinatesFromWikidata( entity )
		if s ~= '' then
			args.lat = s.latitude
			args.long = s.longitude
			mp.wdContent.coord = true
		end
	end

	if show.name then
		s = fw.getSitelink( entity, args.wikiLang .. 'wikivoyage' )
		if s and s ~= args.titleObj.text then -- no link to the article itself
			args.thisWiki = s
		end
	end

	-- saving manually added commons category
	s = args.commonscat
	args.commonscat = ''

	-- getting commonscat from commonswiki sitelink before P373
	-- because sitelink is checked by Wikidata
	if args.commonscat == '' then
		t = fw.getSitelink( entity, 'commonswiki' ) or ''
		if mw.ustring.find( t, 'Category:', 1, true ) then
			args.commonscat = mw.ustring.gsub( t, 'Category:', '' )
		end
	end

	-- getting more values from Wikidata
	for key, value in pairs( mp.wdContent ) do
		if not args[ key ] or args[ key ] == '' then
			if key == 'image' or key == 'rss' then
				args[ key ] = fw.getValue( entity, mp.wd[ key ].p )
			elseif value and mp.wd[ key ] and show.name then
				args[ key ] = fw.getValue( entity, mp.wd[ key ].p )
				if args[ key ] ~= '' and mp.wd[ key ].f then
					args[ key ] = mw.ustring.gsub( mp.wd[ key ].f, '($1)', args[ key ] )
				end
			end
			mp.wdContent[ key ] = args[ key ] ~= ''
		end
	end

	if args.commonscat ~= '' and s ~= '' then
		mb.addMaintenance( mi.maintenance.commonscatWD )
	end
	if s ~= '' then -- replace with manually added commons category
		args.commonscat = s
	end
end

local function finalParameterCheck( args, show, country )
	-- coordinates are neccessary
	show.noCoord = args.lat == '' or args.long == ''
	if show.noCoord then
		show.name  = ''
		show.poi   = false
		show.coord = false
	end

	-- getting Marker type and group
	args.type, args.group =	mb.checkTypeAndGroup( args.type, args.group )
	args.groupTranslated = mb.translateGroup( args.group )

	-- url check
	args.url = mb.checkUrl( args.url )

	-- checking name existence, splitting name and link from [[link|name]]
	if args.name == '' then
		args.name = mi.maintenance.missingName
		mb.addMaintenance( mi.maintenance.missingNameMsg )
	end
	if args.name:find( '<', 1, true ) or args.name:find( '{{', 1, true ) or
		args.alt:find( '<', 1, true ) or args.alt:find( '{{', 1, true ) then
		mb.addMaintenance( mi.maintenance.malformedName )
	end
	args.givenName = mb.getName( args.alt, args.thisWiki )
	args.displayName = mb.getName( args.name, args.thisWiki )
	if not args.givenName.exists then
		args.givenName = args.displayName
	end
	if args.nameLocal ~= '' and args.givenName.name == args.nameLocal then
		args.nameLocal = ''
	end
	if args.symbol == '' and show.poi and show.icon then
		args.symbol = mb.getMakiIconName( args.type ) or ''
	end
end

-- distinguishing marker symbols, default: number
local function makeMarkerProperties( args )
	args.useIcon = false -- true: add pushpin symbol
	args.color = ''
	args.color, args.group = mb.getColor( args.group )
	args.symbol = args.symbol:lower()

	if args.symbol == 'letter' then
		args.symbol = '-letter-' .. args.group
	elseif args.symbol == '' or args.symbol == 'number' then
		args.symbol = '-number-' .. args.group
	elseif args.symbol:len() == 1 and args.symbol:match( '%w' ) then
		args.text = args.symbol:upper()
		mb.addMaintenance( mi.maintenance.numberUsed )
	elseif args.symbol ~= '' and mm[ args.symbol ] and args.text == '' then
		-- check if MAKI icon is available
		if mm[ args.symbol ].im ~= '' then
			args.text = mw.ustring.format( '[[File:%s|x14px|link=|class=noviewer]]',
				mm[ args.symbol ].im )
		else
			-- fallback if no image is available
			args.text = args.symbol:sub( 1, 1 ):upper()
			args.useIcon = true
		end
	elseif args.symbol ~= '' and not mm[ args.symbol ] then
		args.symbol = 'cross'
		args.color, args.group = mb.getColor( 'error' )
		args.text = mi.maintenance.closeX
		mb.addMaintenance( mi.maintenance.unknownIcon )
	end
end

local function makeName( result, args )
	local tag

	if args.displayName.all ~= '' or args.nameExtra ~= '' then
		local style
		if args.styles ~= '' then
			style = mi.nameStyles[ args.styles:lower() ];
			if not style then
				style = args.styles
			end
		end

		local s
		if args.url ~= '' and args.displayName.pageTitle == '' then
			s = '[' .. args.url .. ' '
				.. mb.replaceBrackets( args.displayName.name ) .. ']'
		else
			s = args.displayName.all
		end
		if args.nameExtra ~= '' then
			s = s .. ' ' .. args.nameExtra
		end

		-- supporting right-to-left wikis
		tag = mw.html.create( 'bdi' )
			:attr( 'id', 'vCard_' .. mw.uri.anchorEncode( args.givenName.name ) )
			:attr( 'class', 'p-name fn org listing-name'
				.. mb.addWdClass( mp.wdContent.name ) )
			:cssText( style )
			:wikitext( s )
		table.insert( result, tostring( tag ) )

		if args.url ~= '' and args.displayName.pageTitle ~= '' then
			-- both article and web links
			tag = mw.html.create( 'span' )
				:addClass( 'listing-url' )
				:wikitext( '['.. args.url .. ' ' .. mi.icons.internet .. ']' )
			table.insert( result, tostring( tag ) )
		end
	elseif args.url ~= '' then
		tag = mw.html.create( 'span' )
			:addClass( 'listing-url' )
			:wikitext( '[' .. args.url .. ']' )
		table.insert( result, tostring( tag ) )
	end
end

local function makeNameAndAdditions( result, args, show, country, entity )
	local s = ''

	-- adding name, airport code and sister-project icons
	if show.name then
		makeName( result, args )

		if mi.options.showSisters then
			s, _ = mb.makeSisterIcons( args, country, entity )
		end
		s = s .. mb.makeSocial( args, mp.wdContent, args.givenName.name )
		mb.tableInsert( result, s )

		-- adding airport code and coordinate if requested and available
		s = {}
		if not show.noairport and args.type == mi.airportType then
			mb.tableInsert( s, mb.makeAirport( args, mp.wdContent ) )
		end
		if show.coord then
			table.insert( s, mb.dmsCoordinates( args.lat, args.long,
				args.givenName.name, mp.wdContent.coord, country.extra ) )
		end
		if #s > 0 then
			s = '<span class="listing-parenthesis">(</span>'
				.. table.concat( s, '<span class="listing-delimiter">, &#8203;</span>' )
				.. '<span class="listing-parenthesis">)</span>'
			table.insert( result, s )
		end

	-- adding coordinate only
	elseif show.coord then
		table.insert( result, mb.dmsCoordinates( args.lat, args.long,
			args.givenName.name, mp.wdContent.coord, country.extra ) )
	end
end

-- main marker function

function mk.marker( frame )
	mb.initMaintenance( 'Marker' )

	-- copying frame:getParent().args to template arguments, args, parameter check
	-- returning Wikidata entity and display options
	local args, mkEntity, show = initialParameterCheck( frame:getParent().args )
	show.inline = true

	-- get country-specific technical parameters
	local country = cm.getCountryData( mkEntity )
	if country.lang ~= '' then
		country.langName = lg.getProperty( country.lang, 'n' )
		country.R2L = lg.isR2L( country.lang )
	end
	-- for map support
	country.extra = mi.defaultSiteType
	if country.iso_3166 and country.iso_3166 ~= '' then
		country.extra = country.extra .. '_region:' .. country.iso_3166
	end

	-- add additional parameters
	args.thisWiki  = '' -- marker-name link to current Wikivoyage article
	args.wikiLang  = mw.getContentLanguage():getCode()
	args.titleObj  = mw.title.getCurrentTitle()
	args.nameLocal = '' -- possible future feature

	getDataFromWikidata( args, show, country, mkEntity )
	if args.commonscat ~= '' then
		args.commonscat = mw.ustring.gsub( args.commonscat, ' ', '_' )
	end
	args.wikiR2L = lg.isR2L( args.wikiLang )

	-- parameter check after data import from Wikidata
	finalParameterCheck( args, show, country )

	-- generating output
	local result = {} -- output string table, wrapper is added later

	-- adding marker symbol
	makeMarkerProperties( args )
	if show.poi then
		table.insert( result, mb.makeMarkerSymbol( args, args.givenName.all, frame ) )
	end

	makeNameAndAdditions( result, args, show, country, mkEntity )
	result = mb.makeWrapper( result, args, country, show, mp.markerData, 'Marker', frame )

	local ns = args.titleObj.namespace
	if ns ~= 4 and ns ~= 10 and ns ~= 828 then
		local m = mi.maintenance.properties
		return result .. mb.getMaintenance() .. fw.getCategories( m )
			.. mb.getCategories( m ) .. cm.getCategories( m )
	else
		return result
	end
end

-- module administration
function mk.Marker()
	return Marker
end

function mk.failsafe( version )
	return fs._failsafe( version, Marker ) or ''
end

return mk