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: 2019-09-08

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.

Anmerkungen

Benötigte weitere Module

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

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

local cm = require( 'Module:CountryData' )
local fs = require( 'Module:Failsafe' )
local fw = require( 'Module:FastWikidata' )
local pt = mw.loadData( 'Module:Wikidata2/POITypes' ) -- WD types to vCard/Poi types
local yn = require( 'Module:Yesno' )

-- module variable
local mk = {}

-- main marker function

function mk.marker( frame )
	local catArray = {}
	local noCoords = false
	local wrongQualifier = false
	
	local sisters = {
		wikivoyage = '', -- link to another branch, usually en, as a sister link
		commons    = '', -- link to Commons category
		wikipedia  = ''  -- link to Wikipedia
	}

	local args = {}, key, value, s
	local country -- country data
	local extra = 'type:landmark_globe:earth'
	local mkEntity = nil -- marker entity
	local titleObj = mw.title.getCurrentTitle()
	local ns = titleObj.namespace
	local templateArgs = frame:getParent().args
	local thisWiki = '' -- marker-name link to current Wikivoyage article
	local wikiLang = mw.getContentLanguage():getCode()

	local function addWdClass( key )
		if mp.wdContent[ key ] then
			return ' wikidata-content'
		else
			return ''
		end
	end
	local function checkYn( keys )
		local i, key, s
		for i = 1, #keys, 1 do
			key = keys[ i ]
			s = yn( args[ key ], nil )
			if s ~= nil then -- then args.url is boolean
				args[ key ] = ''
				mp.wdContent[ key ] = s
			else
				if args[ key ] ~= '' then
					mp.wdContent[ key ] = false
				elseif mp.wdContent.auto ~= nil then
					mp.wdContent[ key ] = mp.wdContent.auto
				end
			end
		end
	end

	mb.initMaintenance( 'Marker' )

	-- 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 parameters
	if not args.format:match( mp.formats.allowed ) then
		if args.format ~= '' then
			mb.addMaintenance( ms.maintenance.unknownFormat )
		end
		args.format = mp.formats.default
	end
	if args.format == mp.formats.poiMode then
		mb.addMaintenance( ms.maintenance.poiMode )
	end
	local show = {}
	for key, value in ipairs( { 'marker', 'name', 'onlyCoord', 'withCoord' } ) do
		show[ value ] = args.format:match( mp.formats[ value ] )
	end

	args.zoom = math.floor( tonumber( args.zoom ) or ms.defaultZoomLevel )
	if args.zoom < 0 or args.zoom > ms.maxZoomLevel then
		args.zoom = ms.defaultZoomLevel
	end
	args.symbol = args.symbol:lower()
	args.wikidata, mkEntity, wrongQualifier = fw.getEntity( args.wikidata or '' )
	if wrongQualifier then
		mb.addMaintenance( ms.maintenance.wrongQualifier )
	elseif args.wikidata ~= '' then
		mb.addMaintenance( ms.maintenance.wikidata )
	end
	if args.commonscat ~= '' then
		mb.addMaintenance( ms.maintenance.commonscat )
	end

	-- treatment of args.auto
	if args.wikidata ~= '' then
		mp.wdContent.auto = yn( args.auto, nil )
	else
		mp.wdContent.auto = nil
	end
	-- y/n allow/disallow output
	checkYn( mp.ynCheckList )

	-- checking coordinates given as template parameters
	-- converting DMS to decimal coordinates if necessary
	args.lat, args.long = mb.checkCoordinates( args.lat, args.long )

	-- image check
	if args.image ~= '' then
		args.image, catArray = mb.checkImage( args.image, mkEntity, catArray )
	end

	-- getting data from Wikidata
	if args.wikidata ~= '' then -- mkEntity is available
		if args.name == '' then
			args.name = mkEntity:getLabel() or ms.langs.name ~= ''
				and mkEntity:getLabel( ms.langs.name ) or ''
			mp.wdContent.name = args.name ~= ''
		end
		
		if args.type == '' then
			s, catArray = fw.getValues( mkEntity, mp.wd.type.p, ms.p31Limit, catArray )
			args.type, catArray = fw.typeSearch( s, pt, ms.searchLimit, catArray )
		end

		if args.lat == '' or args.long == '' then
			s, catArray = fw.getValue( mkEntity, mp.wd.coord.p, catArray )
			if s ~= '' then
				args.lat = s.latitude
				args.long = s.longitude
				mp.wdContent.coord = true
			end
		end

		if show.name then
			if mkEntity.sitelinks then
				s = mkEntity.sitelinks[ wikiLang .. 'wikivoyage' ]
				if s then
					if s.title ~= titleObj.text then
						thisWiki = s.title
					end -- no link to the article itself
				end
				sisters.wikipedia = mb.getWikiLink( { wikiLang, ms.langs.name }, 'wiki', mkEntity )
				if thisWiki == '' then
					sisters.wikivoyage = mb.getWikiLink( { ms.langs.name }, 'wikivoyage', mkEntity )
				end
			end
		end

		s = args.commonscat
		args.commonscat = ''
		for key, value in pairs( mp.wdContent ) do
			if value and args[ key ] == '' and mp.wd[ key ]
				and ( show.name or key == 'image' ) then
				args[ key ], catArray = fw.getValue( mkEntity, mp.wd[ key ].p, catArray )
				mp.wdContent[ key ] = args[ key ] ~= ''
			end
		end
		if args.commonscat == '' and mkEntity.sitelinks and mkEntity.sitelinks.commonswiki then
			args.commonscat = mkEntity.sitelinks.commonswiki.title
			if mw.ustring.find( args.commonscat, 'Category:', 1, true ) then
				args.commonscat = mw.ustring.gsub( args.commonscat, 'Category:', '' )
			else
				args.commonscat = ''
			end
			mp.wdContent.commonscat = args.commonscat ~= ''
		end
		if args.commonscat ~= '' and s ~= '' then
			mb.addMaintenance( ms.maintenance.commonscatWD )
		end
		if s ~= '' then
			args.commonscat = s
		end
	end
	if args.commonscat ~= '' then -- if no Wikidata
		args.commonscat = mw.ustring.gsub( args.commonscat, ' ', '_' )
		sisters.commons = tostring( mw.uri.fullUrl( 'c:Category:'
			.. mw.uri.encode( args.commonscat, 'WIKI' ) ) )
	end

	-- coordinates are neccessary

	noCoords = args.lat == '' or args.long == ''
	-- country-specific technical parameters
	-- only for map support
	country, catArray = cm.getCountryData( mkEntity )
	if country.iso_3166 ~= '' then
		extra = extra .. '_region:' .. country.iso_3166
	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 = ms.maintenance.missingName
		mb.addMaintenance( ms.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( ms.maintenance.malformedName )
	end
	local name = mb.getName( args.name, thisWiki )
	local altname = mb.getName( args.alt, thisWiki )
	if not altname.exists then
		altname = name
	end

	-- marker color
	local color = ''
	color, args.group = mb.getColor( args.group )

	-- distinguishing marker symbols, default: number
	local useIcon = false -- true: add pushpin symbol
	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( ms.maintenance.numberUsed )
	elseif args.symbol ~= '' and mi[ args.symbol ] and args.text == '' then
		-- check if MAKI icon is available
		if mi[ args.symbol ].im ~= '' then
			args.text = mi[ args.symbol ].im
		else
			-- fallback if no image is available
			args.text = args.symbol:sub( 1, 1 ):upper()
			useIcon = true
		end
	elseif args.symbol ~= '' and not mi[ args.symbol ] then
		args.symbol = 'cross'
		color, args.group = mb.getColor( 'error' )
		args.text = ms.maintenance.closeX
		mb.addMaintenance( ms.maintenance.unknownIcon )
	end

	-- generating output

	-- adding marker symbol
	local result = '' -- output string, wrapper is added later
	if show.marker and not noCoords then
		result = mb.addingMarkerSymbol( args, altname.all, args.text, args.symbol,
			useIcon, color, frame )
	end

	-- adding name
	-- f0: default: marker and name
	-- f1: marker and name (coordinates)
	-- f4: name (coordinates)
	if show.name then
		if result ~= '' then
			result = result .. ' '
		end
		if name.all ~= '' or args.nameExtra ~= '' then
			s = ''
			if args.styles ~= '' then
				s = ms.nameStyles[ args.styles:lower() ];
				if not s then
					s = args.styles
				end
				s = ' style="' .. s .. '"'
			end
			-- supporting right-to-left wikis
			s = '<bdi id="vCard_' .. mw.uri.anchorEncode( name.name )
				.. '" class="p-name fn org listing-name'
				.. addWdClass( 'name' ) .. '"' .. s .. '>'
			if args.url ~= '' and name.pageTitle == '' then
				s = s .. '[' .. args.url .. ' ' .. mb.replaceBrackets( name.name ) .. ']'
			else
				s = s .. name.all
			end
			if args.nameExtra ~= '' then
				s = s .. ' ' .. args.nameExtra
			end
			result = result .. s .. '</bdi>'
			if args.url ~= '' and name.pageTitle ~= '' then
				-- both article and web links
				result = result .. ' <span class="listing-url">['
					.. args.url .. ' ' .. ms.icons.internet .. ']</span>'
			end
		elseif args.url ~= '' then
			result = result .. '[' .. args.url .. ']'
		end

		-- preparing airport codes
		local airport = ''
		if args.iata ~= '' then
			airport = '<span class="listing-iata' .. addWdClass( 'iata' ) .. '">'
				.. args.iata .. '</span>'
			airport = mw.ustring.format( ms.texts.iata, airport )
		end
		if args.iata == '' and args.icao ~= '' then
			airport = '<span class="listing-icao' .. addWdClass( 'icao' ) .. '">'
				.. args.icao .. '</span>'
			airport = mw.ustring.format( ms.texts.icao, airport )
		end

		-- adding Wikimedia sister project icons if name is shown
		if show.name and ms.options.showSisters ~= false then
			s, _ = mb.addSisterIcons( sisters, altname.name, args.wikidata )
			if s ~= '' then
				result = result .. ' ' .. s
			end
		end

		-- adding airport code
		-- adding coordinate if requested and available
		if show.withCoord and not noCoords then
			result = result .. ' '
			if airport ~= '' then
				result = result .. '<span class="listing-airport">(' .. airport
			end
			result = result .. mb.dmsCoordinates( args.lat, args.long, name.name,
				mp.wdContent.coord, extra, airport == '' , airport ~= '' ) -- (), comma
			if airport ~= '' then
				result = result .. ')</span>'
			end
		elseif airport ~= '' then
			result = result .. ' <span class="listing-airport">(' .. airport .. ')</span>'
		end

	-- adding coordinate
	-- f3: marker and coordinates
	-- f4: only coordinates
	elseif show.onlyCoord and not noCoords then
		if result ~= '' then
			result = result .. ' '
		end
		result = result
			.. mb.dmsCoordinates( args.lat, args.long, name.name, mp.wdContent.coord,
				extra, false )
	end

	-- adding image
	if args.image ~= '' then
		result = result .. '<span class="listing-image" style="display: none">[[File:' .. args.image
			.. '|350x240px|class=noviewer|' .. altname.name .. ']]</span>'
	end

	-- adding wrapper and microformats
	if args.addMf == 'true' or args.addMf == '' then
		if yn( args.noGpx, false ) then
			s = '<span class="h-card vcard-nogpx Marker"'
		else
			s = '<span class="h-card vcard Marker"'
		end
		s = s .. mb.data( 'data-region', country.iso_3166 )
			.. mb.data( 'data-country', country.country )
			.. mb.data( 'data-lang', country.lang )
			.. mb.data( 'data-wikilang', wikiLang )
			.. mb.data( 'data-color', '#' .. color )
			.. mb.data( 'data-type', args.type )
			.. mb.data( 'data-group', args.group )
			.. mb.data( 'data-group-translated', args.groupTranslated )
			.. mb.data( 'data-map-group', args.mapGroup )
			.. mb.data( 'data-name', mb.htmlReplace( altname.name ) )
			.. mb.data( 'data-location', mb.htmlReplace( titleObj.subpageText ) )
			.. mb.data( 'data-symbol', args.symbol )
			.. mb.data( 'data-url', mw.text.nowiki( args.url ) )
			.. mb.data( 'data-wikidata', args.wikidata )
			.. mb.data( 'data-commonscat', args.commonscat )
			.. mb.data( 'data-image', args.image )

		result = s .. '><span class="p-geo geo listing-coordinates" style="display: none">'
			.. '<span class="p-latitude latitude">' .. args.lat .. '</span>'
			.. '<span class="p-longitude longitude">' .. args.long .. '</span></span>'
			.. result
		if not show.name then
			result = result .. '<span class="p-name fn org listing-name" style="display: none">'
				.. name.name .. '</span>'
		end
		result = result .. '</span>'
		-- adding coordinates to Mediawiki database
		-- frame:callParserFunction is expensive
	end
	if not noCoords then
		result = result .. frame:callParserFunction{ name = '#coordinates',
			args = { args.lat, args.long, extra, name = name.name } }
	end

	if ns ~= 10 and ns ~= 828 then
		return result .. mb.getMaintenance()
			.. fw.getCategories( catArray, ms.maintenance.properties )
	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