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}}.

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

Hinweise
-- module import
local mb = require( 'Module:MarkerBase' )
local mi = mw.loadData( 'Module:Marker/Maki icons' )
local mp = require( 'Module:Marker/Params' )
local ms = require( 'Module:MarkerBase/i18n' )
local pt = mw.loadData( 'Module:Wikidata2/POITypes' ) -- WD types to vCard/Poi types
local yn = require( 'Module:Yesno' )
local fw = require( 'Module:FastWikidata' )
local cm = require( 'Module:CountryData' )

-- module variable
local mk = {}

-- main marker function

function mk.marker( frame )
	local wrongQualifier = false
	local noCoords = false
	local mkEntity = nil -- marker entity
	local key, value, s, t, u

	local args = {}
	local templateArgs= frame:getParent().args
	local errorMsgs = ''
	local cntrl = false
	local catArray = {}
	local ns = mw.title.getCurrentTitle().namespace
	
	-- checking keys and copying values to args
	t = 0
	s = ''
	for key, value in pairs( mp ) do
		args[ value ] = ''
	end
	for key, value in pairs( templateArgs ) do
		-- vaule check
		u = mw.ustring.gsub( value, '</br>', ' ' )
		u = mw.ustring.gsub( u, '<br%s*/*>', ' ' )
		u = mw.ustring.gsub( u, '<p>', ' ' )
		if not mw.ustring.find( u, '<span' ) then
			u = mw.ustring.gsub( u, '[%z\000-\031]', ' ' )
		end
		if u ~= value then
			cntrl = true
			value = u
		end

		if mp[ key ] then
			args[ mp[ key ] ] = value
		else
			if s ~= '' then s = s .. ', ' end
			s = s .. "''" .. key .. "''"
			t = t + 1
		end
	end
	if t == 1 then
		s = ms.errorMsg.unknownParam .. s
	elseif t > 1 then
		s = ms.errorMsg.unknownParams .. s
	end
	if s ~= '' then
		errorMsgs = '<span class="error">' .. s .. ms.errorMsg.wrongParam .. '</span>'
	end
	if cntrl then
		errorMsgs = errorMsgs .. '<span class="listing-error">'
			.. ms.errorMsg.illegalCtrls .. '</span>'
	end

	if args.addMf == '' then args.addMf = 'true' end
	if args.format == '' then args.format = 'f0' 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 = string.lower( args.symbol )
	args.wikidata, mkEntity, wrongQualifier = fw.getEntity( args.wikidata or '' )

	local thisWiki   = '' -- marker-name link to current Wikivoyage article
	local commonsCat = '' -- name of Commons category
	local sisters = {
		wikivoyage = '', -- link to another branch, usually en, as a sister link
		commons    = '', -- link to Commons category
		wikipedia  = ''  -- link to Wikipedia
	}
	local showSisters = false -- sisters were fetched from Wikidata
	local wikiLang    = mw.getContentLanguage():getCode()

	-- url = y/n allow/disallow url output
	local noURL = false
	if args.url ~= '' then
		t = yn( args.url, nil )
		if t ~= nil then -- then a is boolean
			args.url = ''
			noURL = not t
		end
	end

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

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

	if args.commonscat ~= '' then
		errorMsgs = errorMsgs .. ms.errorMsg.commonscat
	end

	-- getting data from Wikidata
	local coordFromWD = false
	local nameFromWD = false
	showSisters = ( args.format ~= 'f2' ) and ( args.format ~= 'f3' )

	if args.wikidata ~= '' then -- mkEntity is available
		if args.name == '' then
			args.name = mkEntity:getLabel() or mkEntity:getLabel( 'en' ) or ''
			if args.name ~= '' then nameFromWD = true end
		end
		
		if args.image == '' then
			args.image, catArray = fw.getValue( mkEntity, 'P18', catArray )
		end

		if args.type == '' then
			t, catArray = fw.getValues( mkEntity, 'P31', ms.p31Limit, catArray )
			args.type, catArray = fw.typeSearch( t, pt, ms.searchLimit, catArray )
		end

		if (args.lat == '') or (args.long == '') then
			t, catArray = fw.getValue( mkEntity, 'P625', catArray )
			if t ~= '' then
				args.lat = t.latitude
				args.long = t.longitude
				coordFromWD = true
			end
		end

		if showSisters then
			if mkEntity.sitelinks then
				t = mkEntity.sitelinks[wikiLang .. 'wikivoyage']
				if t then
					if t.title ~= mw.title.getCurrentTitle().text then
						thisWiki = t.title
					end -- no link to the article itself
				end
				sisters.wikipedia = mb.getWikiLink( {wikiLang, 'en'}, 'wiki', mkEntity )
				if thisWiki == '' then
					sisters.wikivoyage = mb.getWikiLink( {'en'}, 'wikivoyage', mkEntity )
				end
			end
			commonsCat = args.commonscat
			t, catArray = fw.getValue( mkEntity, 'P373', catArray )
			if ( commonsCat ~= '' ) and ( t~='' ) then
				errorMsgs = errorMsgs .. ms.errorMsg.commonscatWD
			end
			if commonsCat == '' then
				commonsCat = t
			end
			if commonsCat ~= '' then
				commonsCat = mw.ustring.gsub( commonsCat, ' ', '_' )
				sisters.commons = tostring( mw.uri.fullUrl( 'c:Category:'
					.. mw.uri.encode( commonsCat, 'WIKI' ) ) )
			end

			if (args.url == '') and (not noURL) then
				args.url, catArray = fw.getValue( mkEntity, 'P856', catArray ) -- official website
			end
		end
	elseif ( args.commonscat ~= '' ) and showSisters then
		commonsCat = mw.ustring.gsub( args.commonscat, ' ', '_' )
		sisters.commons = tostring( mw.uri.fullUrl( 'c:Category:'
			.. mw.uri.encode( commonsCat, 'WIKI' ) ) )
	end

	-- coordinates are neccessary
	if (args.lat == '') or (args.long == '') then
		noCoords = true
		errorMsgs = errorMsgs .. ms.errorMsg.missingCoord
	end

	if dms then errorMsgs = errorMsgs .. ms.errorMsg.dmsCoordinate end

	local country = cm.getCountryData( mkEntity )

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

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

	-- checking name existence, splitting name and link from [[link|name]]
	if args.name == '' then
		args.name = ms.errorMsg.missingName
		errorMsgs = errorMsgs .. ' ' .. ms.errorMsg.missingNameMsg
	end
	if args.name:find( '<' ) or args.name:find( '{{' ) or 
		args.alt:find( '<' ) or args.alt:find( '{{' ) then
		errorMsgs = errorMsgs .. ms.errorMsg.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()
		errorMsgs = errorMsgs .. ms.errorMsg.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 (mi[args.symbol] == nil) then
		args.symbol = 'cross'
		color, args.group = mb.getColor( 'error' )
		args.text = ms.errorMsg.closeX
		errorMsgs = errorMsgs .. ' ' .. ms.errorMsg.unknownIcon
	end

	-- generating output

	-- adding marker symbol
	local result -- output string, wrapper is added later
	if noCoords or ( args.format == 'f4' ) or ( args.format == 'f5' ) then
		result = ''
	else
		result = mb.addingMarkerSymbol( args, altname.all, args.text, args.symbol,
			useIcon, color, frame )
	end

	if args.format == 'f2' then
		-- marker only

	-- f3: marker and coordinates
	-- f4: only coordinates
	elseif ( args.format == 'f3' ) or ( args.format == 'f5' ) and not noCoords then
		if args.format == 'f3' then result = result .. ' ' end
		result = result
			.. mb.dmsCoordinates( args.lat, args.long, name.name, coordFromWD,
				'type:landmark_globe:earth', false )

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

		-- adding Wikimedia sister project icons

		if showSisters and ms.options.showSisters then -- only for f0 and f1 formats
			s = ''
			local key, value
			for key, value in pairs( sisters ) do
				if value ~= '' then
					s = s .. ' <span class="listing-sister-icon listing-sister-' .. key .. '">['
						.. value .. ' ' .. string.format( ms.icons[key], altname.name )
						.. ']</span>'
				end
			end
			if args.wikidata ~= '' then
				s = s .. '<span class="listing-sister-icon listing-sister-wikidata">['
					.. tostring( mw.uri.fullUrl( 'd:' .. args.wikidata ) )
					.. ' ' .. string.format( ms.icons.wikidata, altname.name, args.wikidata )
					.. ']</span>'
			end
			result = result .. s
		end

		if ( args.format == 'f1' ) or ( args.format == 'f4' ) and not noCoords then
			result = result 
				.. ' ' .. mb.dmsCoordinates( args.lat, args.long, name.name,
					coordFromWD, 'type:landmark_globe:earth', true )
		end
	else
		result = result .. ' ' .. ms.errorMsg.unknownFormat .. ' '
	end
	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' 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-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( mw.title.getCurrentTitle().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', 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 (args.format == 'f2') or (args.format == 'f3') 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
		if not noCoords then
			result = result .. frame:callParserFunction{ name = '#coordinates',
				args = { args.lat, args.long, 'type:landmark_globe:earth', name = name.name } }
		end
	end

	if wrongQualifier then
		result = result .. ms.errorMsg.wrongQualifier
	end
	if ns == 0 then
		result = result .. fw.getCategories( catArray, ms.errorMsg.properties )
	end
	if args.demo == 'true' then
		return result
	else
		return result .. errorMsgs
	end
end

return mk