Modul:Marker utilities

![]() | Dieses Modul wird auf vielen Seiten benutzt, und Änderungen werden projektweit sofort wahrgenommen. Bitte teste Änderungen vorher im /Sandkasten oder in deinem Benutzernamensraum. Die getestete Änderung sollte dann in einem einzigen Edit auf dieser Seite eingefügt werden. Bitte diskutiere Änderungen zuerst auf der Diskussionsseite bevor du sie implementierst. |
![]() | Dieses Modul ist getestet und für den projektweiten Gebrauch geeignet. Es kann in Vorlagen benutzt und auf Hilfeseiten erläutert werden. Entwicklungen an dem Modul sollten auf Marker utilities/Test und die Anwendung auf der Spielwiese getestet werden, da wiederholte Trial-and-Error-Edits die Resourcen stark belasten können. |
![]() | Dieses Modul benutzt eine oder mehrere Wikidata-Eigenschaften. |
Anwendung
Das Modul stellt gemeinsame Funktionen für das Modul:Marker und das Modul:vCard zur Verfügung.
Versionsbezeichnung auf Wikidata: 2023-05-17
Benötigte weitere Module
Dieses Modul benötigt folgende weitere Module: Coordinates • Marker utilities/Groups • Marker utilities/i18n • Marker utilities/Maki icons • Marker utilities/Types • UrlCheck • Wikidata utilities
Verwendung in anderen Modulen
Dieses Modul ist notwendig für die Ausführung folgender Module. Bei Anpassungen sollte die Funktionstüchtigkeit der folgenden Module geprüft werden. Benutze dazu auch diese Tracking-Kategorie um Fehler zu finden, die sich dann auf Artikel auswirken:
- Marker • vCard • VCard/Params
- Modul benötigt das Modul Marker utilities – Wartungskategorie, in der nochmals alle Module gelistet sind, die von diesem Modul abhängig sind.
Wartungsfunktionen
function mu.initMaintenance( name )
Die Funktion initialisiert die Zeichenkettenverwaltung für die Ausgabe von Fehlermeldungen. name
ist der zugehörige Modulname ohne die Namensraumbezeichnung. Diese Funktion setzt auch die Tabellen fehlerhafter Paramter und der Fehlermeldungen/Hinweise zurück.
function mu.addMaintenance( s )
Diese Funktion fügt die Fehlermeldung s
in die Tabelle der Fehlermeldungen und Hinweise ein. Ein Teil der oben genannten Funktionen befüllt ebenfalls diese Tabelle.
function mu.getMaintenance()
Dises Funktion liefert eine Zeichenkette mit allen Fehlermeldungen und Hinweisen zurück.
function mu.getCategories( formatStr )
- Liefert eine Zeichenkette mit den Kategorie-Links aller verwendeten Wikidata-Eigenschaften zurück.
Funktionen
Im Projektnamensraum befindet sich die technische Dokumentation.
function mu.isSet( arg )
liefert true
oder false
, je nachdem, ob das Argument arg
gesetzt ist oder nicht. arg
muss existieren und einen Wert ungleich ''
enthalten.
function mu.tableInsert( tab, value )
fügt den Wert value
zur Tabelle tab
hinzu, wenn er existiert und nicht leer ist.
function mu.yesno( val )
gibt y
oder n
zurück, wenn val
einen entsprechenden Wert besitzt, anderenfalls nil
.
function mu.textSplit( s, sep )
trennt die Zeichenkette s
an Trennzeichen sep
auf und legt sie in einer Tabelle ab. sep
muss genau die Länge von einem Zeichen (ein Byte) haben und darf kein magisches Pattern-Zeichen sein. Die Funktion ist deutlich schneller als mw.text.split()
.
function mu.getAliases( tab, key )
erstellt aus der Tabelle tab
eine Alias-Tabelle, die in tab
unter dem Schlüssel key
notiert sind.
function mu.checkArguments( templateArgs, validKeys )
prüft, ob im Vorlagenaufruf unbekannte oder durch Aliase entstandene doppelte Parameternamen verwendet werden. Diese unbekannten bzw. doppelten Parameter werden in die Tabelle fehlerhafter bzw. doppelter Parameter eingefügt. templateArgs
ist die Tabelle der Vorlagenparamter, validKeys
die Tabelle der erlaubten Parameter (siehe z. B. Modul:VCard/i18n). Die Funktion liefert eine Tabelle der gültigen Argumente zurück.
function mu.addWdClass( isFromWikidata )
liefert den Klassenbezeichner wikidata-content
, wenn isFromWikidata
auf true
gesetzt ist, ansonsten eine leere Zeichenkette.
function mu.dmsCoordinates( lat, long, name, fromWD, extraParams, withBracket )
liefert die Zeichenkette r
, die eine zu den Kartenwerkzeugen verlinkte Dezimalkoordinate enthält, die wahlweise in Klammern gesetzt oder mit einem Komma eingeleitet werden kann. name
ist der Name der Einrichtung, fromWD = true
besagt, dass die Koordinate aus Wikidata stammt und extraParams
enthält zusätzliche Parameter wird Maßstab und Region, die in den kartenwerkzeugen ausgewertet werden.
function mu.removeCtrls( s, onlyInline )
Die Funktion entfernt Steuerzeichen und die HTML-Tags für den Zeilenumbruch und Zeilenwechsel aus der Zeichenkette s
. Wenn onlyInline = false
, dann bleiben Zeilenumbruch und Zeilenwechsel erhalten. Deren Vorkommen wird in der Variablen descrDiv
mitgeteilt. Die Funktion liefert zwei Werte zurück:
s
bereinigte Zeichenkette.descrDiv
Der Container für die Beschreibung muss ein<div>
-Tag sein.
function mu.addLinkIcon( classes, link, title, text )
erstellt den HTML-Code für die Anzeige eines verlinkten Symbolbildes. Die Darstellung erfolgt im Zusammenspiel mit Stilvorlagen. Gefordert werden zu listing-icon
hinzuzufügende CSS-Klassen classes
, ein Link link
(entweder Internet- oder Artikellink), ein Tooltip-Text title
und der meist nicht sichtbare Linktext text
.
function mu.makeSisterIcons( icons, args, country, entity )
liefert die verlinkten Schwesterprojekt-Symbole in der Tabelle icons
zurück. Die Angaben stammen meist aus den Sitelinks der Wikidata-Entity entity
. args
ist die Tabelle der übergebenen Vorlagenparameter. Die Tabelle country
enthält länderspezifische Daten wie die Sprachangabe.
function mu.removeStars( name )
entfernt aus der Zeichenkette name
die Sternchen *
und liefert die modifizierte Zeichenkette zurück.
function mu.getName( name, pageTitle )
liefert die Tabelle array
, die den Namen einer Einrichtung name
in verschiedenen Formen enthält. Hauptaufgabe ist es, den eigentlichen Namen aus einem möglichen Link in Wikiyntax herauszulösen. pageTitle
ist der mögliche Titel des zugehörigen Artikels. Enthält der Name neben einem möglichen Link in Wikisyntax weitere Textteile, so werden diese verworfen. Folgende vier Tabellenelemente werden zurückgeliefert:
exists
:boolean
, Name liegt vor.name
:string
, nur der Name.all
:string
, verlinkter Name oder nur der Name, falls kein Link vorliegt.pageTitle
:string
, Artikel, auf den verlinkt wird. Der Titel kann vonname
verschieden sein.
function mu.checkCoordinates( lat, long )
liefert die überprüften Koordinaten lat, long
. Im Fehlerfall sind lat
und long
leere Zeichenketten. Die Fehlermeldungstabelle enthält zusätzlich einen entsprechenden Eintrag (siehe unten).
function mu.typeExists( aType )
liefert den Typ aType
oder nil
zurück, je nachdem, ob der Typ in der Typentabelle enthalten ist. Aliase werden in den zugehörigen Typ umgewandelt.
function mu.getTypeParams( aType )
liefert den Parametersatz aus Module:Marker utilities/Types für den Typ aType
oder nil
zurück.
function mu.idToType( id )
liefert zur Wikidata-Id den zugehörigen Typ oder nil
zurück.
function mu.groupWithEvents( group )
prüft, ob in der angegebenen Gruppe group
Ereignisse als Typen vorgesehen sind.
function mu.checkTypeAndGroup( args )
liefert die überprüften Werte für den Typ und die Gruppen in args
zurück. Im Fehlerfall enthält die Fehlermeldungstabelle zusätzlich einen entsprechenden Eintrag (siehe unten).
function mu.checkStatus( args )
prüft die übergebenen Werte im Parameter status
und legt die gültigen Werte in args.statusTable
ab. Im Fehlerfall enthält die Fehlermeldungstabelle zusätzlich einen entsprechenden Eintrag (siehe unten).
function mu.makeStatusIcons( args )
liefert eine Zeichenkette mit der Bildersyntax gemäß der Tabelle args.statusTable
zurück.
function mu.checkImage( image, entity )
liefert den überprüften Wert für das image
oder eine leere Zeichenkette zurück. Im Fehlerfall enthält die Fehlermeldungstabelle zusätzlich einen entsprechenden Eintrag (siehe unten). Die Variable mi.options.imageCheck
legt fest, ob überhaupt einen rechenzeitintensive Prüfung vorgenommen wird.
function mu.checkUrl( args )
liefert die überprüfte Internetaddresse url
in der Argumenttabelle args
zurück. Im Fehlerfall enthält die Fehlermeldungstabelle zusätzlich einen entsprechenden Eintrag (siehe unten).
function mu.setCopyMarker( args, show )
prüft bei gesetztem show.copy
-Parameter, dass args.wikidata
gesetzt und args.copyMarker
nicht gesetzt sind. Ansonsten werden show.copy
auf false
gesetzt und eine Fehlerausschrift ausgegeben.
function mu.makeMarkerSymbol( args, title, frame, show )
liefert r
: HTML-Quellcode des Marker-Symbols.
function mu.getColor( args )
fügt color
und inverse
zu den Argumenten args
aus der Gruppe group
hinzu. color
ist die zur Gruppe gehörende Farbe und wird aus der Tabelle Modul:Marker utilities/Groups bezogen.
function mu.replaceBrackets( s )
liefert eine Zeichenkette, in der eckige Klammern durch XML-Zeichenreferenz ersetzt wurden. Wird benötigt, wenn die Zeichenkette in einem Link verwendet werden soll.
function mu.convertForSort( s )
Wandelt die Zeichenkette s
so um, dass eine korrekte Sortierung ermöglicht wird. Die auszutauschenden Buchstaben sind in der sprachabhängigen Tabelle substitutes
im Modul Marker utilities/i18n enthalten.
function mu.data( s )
liefert die Zeichenkette s
mit aufgelösten XML- und SGML-Enitäten, wenn sie existiert und nicht leer ist, ansonsten nil
.
function mu.makeWrapper( result, args, country, show, list, aClass, frame )
umgibt zum Inhalt eines Markers oder einer vCard mit einem umschließenden Tag (span, div).
function mu.languageSpan( s, titleHint, args, country, addClass )
fügt den Text in ein span-Tag, in dem die Sprache und Textrichtung des des Texts s
angegeben ist. titleHint
ist das title-Attribut des span-Tags, args
die Vorlagenparamtetertabelle und country
eine Tabelle mit landesspezifischen Angaben. addClass
stellt einen zusätzlichen Klassenbezeichner dar.
function mu.split( s, convert, toValue )
liefert eine Tabelle kommaseparierter Werte der Zeichenkette s
. Bei convert = true
wird die Zeichenkette in Kleinbuchstaben umgewandelt, und Leerräume werden durch den Unterstrich ersetzt. Bei toValue = false
, werden die Werte als Schlüssel einer assoziierten Tabelle übergeben.
function mu.getShow( default, value, validValues )
liefert eine assoziierte Tabelle mit den übergebenen kommaseparierten show
-Attributen, wobei der überschreibbare Standardwert default
berücksichtigt wird. Die show
-Attribute werden auf Gültigkeit hin überprüft.
function mu.getCoordinatesFromWikidata( entity )
liefert die im Wikidata-Datensatz mit der Einität entity
enthaltene Koordinate zurück. Zuerst wird versucht, die Zentrumskoordinate aus der Eigenbschaft P5140
zu erhalten, danach die Koordinate aus der Eigenschaft P625
.
function mu.makeSocial( icons, args, fromWikidata, name )
liefert die verlinkten Symbole von Social-Media-Diensten in der Tabelle icons
zurück. args
ist die Tabelle der Vorlagenparameter, fromWikidata
die Tabelle der Parameter, die aus Wikidata bezogen wurden, und name
die Bezeichnung der Einrichtung.
function mu.makeAirport( args, fromWikidata )
liefert den formatierten Flughafencode nach IATA oder, falls dieser fehlt, den nach ICAO. args
ist die Tabelle der Vorlagenparameter und fromWikidata
die Tabelle der Parameter, die aus Wikidata bezogen
function mu.typeSearch( p31 )
- Sucht in mehreren P31-P279-Ketten nach Q-ids, deren Werte in der Tabelle Module:Marker utilities/Types enthalten sein könnten. Die Tabelle
p31
enthält die vorgefunden P31-Werte. Der erste Treffer wird als Zeichenkette zurückgegeben, im Fehlerfall die Zeichenkette error. Die Maximalanzahl höherer Ebenen für die Suche ist mitmi.searchLimit
vorgegeben, dies sind üblicherweise 4. Es wird nur jeweils die erste P279-Id ausgewertet, also nicht die gesamte Baumstruktur.
function mu.getMaki( key )
Die Funktion liefert eine Tabelle für den angegebenen key
aus der Tabelle Module:Marker utilities/Maki icons zurück.
function mu.getMakiIconId( aType )
Die Funktion liefert den Namen eines MAKI-Symbols zum Type aType
oder nil
zurück, wenn es keinen gibt oder eine Abbildung für den Fließtext fehlt.
function mu.checkCommonsCategory( args )
Die Funktion löscht eine evtl. vorhandene Namensraumangabe in der Commons-Kategorie args.commonscat
und fügt eine Wartungskategorie hinzu, wenn die Commons-Kategorie gesetzt wurde.
function mu.getCommonsCategory( args, entity )
Die Funktion versucht, eine Commons-Kategorie aus Wikidata über die Wikidata-Entität entity
zu beziehen. Zuerst wird der Commons-Site-Link analysiert, dann die Eigenschft P373 und zuletzt die Eigenschaft P910.
function mu.getNamesFromWikidata( args, fromWikidata, country, entity )
Die Funktion befüllt die Tabelle args
mit dem Namen der Einrichtung in der Wiki-Sprache und in der Landessprache mit den Angaben aus Wikidata. Die Tabelle fromWikidata
enthält die Information (fromWikidata.name
, fromWikidata.nameLocal
), ob der Name aus Wikidata stammt.
function mu.getArticleLink( args, entity )
Die Funktion übergibt den Sitelink zum zugehörigen Arikel an args.thisWiki
, außer der Vorlagenaufruf wurde in diesem Arikel vorgenommen.
function mu.formatNumber( num )
Die Funktion ersetzt in der als Zeichenkette vorliegenden Zahl das Dezimalzeichen und fügt Tausendertrennzeichen ein.
function mu.getTypeLabel( id )
liefert das erste Label aus der Typenliste zum id
. id
kann ein Marker- oder vCard-Typ bzw. eine Wikidata-Id sein. Im Fehlerfall wird eine leere Zeichenkette oder der id
selbst zurückgegeben.
function mu.getPageData()
- Die obige Dokumentation wurde aus der Seite Modul:Marker utilities/Doku eingefügt. (bearbeiten | Versionsgeschichte) Die Kategorien für dieses Modul sollten in der Dokumentation eingetragen werden. Die Interwiki-Links sollten auf Wikidata eingepflegt werden.
- Liste der Unterseiten
--[[
Functions library for Marker and vCard modules
In non-Wikivoyage projects, sister-project links functions have to be adapted.
]]--
-- module variable and administration
local mu = {
moduleInterface = {
suite = 'Marker utilities',
serial = '2023-05-17',
item = 58187612
}
}
-- require( 'strict' )
local cd = require( 'Module:Coordinates' )
local mg = require( 'Module:Marker utilities/Groups' )
local mi = require( 'Module:Marker utilities/i18n' )
local mm -- MAKI icons
local mt = require( 'Module:Marker utilities/Types' ) -- types to groups like drink, eat, go, see, sleep, ...
local uc -- URL check
local wu = require( 'Module:Wikidata utilities' )
function mu.isSet( arg )
return arg and arg ~= ''
end
function mu.tableInsert( tab, value )
if mu.isSet( value ) then
table.insert( tab, value )
end
end
function mu.yesno( val )
return mi.yesno[ mw.ustring.lower( val ) ]
end
-- sep is a single character separator but no magic character
function mu.textSplit( s, sep )
local result = {}
for str in s:gmatch( '([^' .. sep .. ']+)' ) do
mu.tableInsert( result, mw.text.trim( str ) )
end
return result
end
function mu.getAliases( tab, key )
local result = {}
if not tab then
return result
end
local v
for k, tb in pairs( tab ) do
v = tb[ key ]
if v then
if type( v ) == 'table' then
for i = 1, #v do
result[ v[ i ] ] = k
end
else
result[ v ] = k
end
end
end
return result
end
-- maintenance tools
function mu.initMaintenance( name )
mu.name = name -- module name
mu.invalidParams = {} -- table of unknown parameters
mu.duplicateAliases = {} -- table of duplicate parameter aliases
mu.maintenance = {} -- table of error strings
mu.typeAliases = nil -- table for type aliases. Create on demand
mu.groupAliases = nil -- table for group aliases
end
function mu.addMaintenance( s )
local function contains( new )
for i = 1, #mu.maintenance do
if mu.maintenance[ i ] == new then
return true
end
end
return false
end
if not contains( s ) then
table.insert( mu.maintenance, s )
end
end
function mu.getMaintenance()
local s = ''
if #mu.invalidParams > 0 then
if #mu.invalidParams == 1 then
s = mw.ustring.format( mi.maintenance.unknownParam, mu.invalidParams[ 1 ] )
else
s = mw.ustring.format( mi.maintenance.unknownParams,
table.concat( mu.invalidParams, ', ' ) )
end
s = s .. mw.ustring.format( mi.maintenance.wrongParam, mu.name )
end
if #mu.duplicateAliases > 0 then
s = s .. mw.ustring.format( mi.maintenance.duplicateAliases,
table.concat( mu.duplicateAliases, ', ' ) )
end
return s .. table.concat( mu.maintenance, ' ' )
end
function mu.getCategories( formatStr )
return wu.getCategories( formatStr )
end
-- args: template arguments consisting of argument name as key and a value
-- validKeys: table with argument name as key used by the script and
-- a string or a table of strings for argument names used by the local wiki
function mu.checkArguments( templateArgs, validKeys )
local args = {}
if not templateArgs or not validKeys or not next( validKeys ) then
return args
end
local keys = {} -- list of wiki-dependent parameter names
for key, params in pairs( validKeys ) do
if type( params ) == 'string' then
keys[ params ] = key
else
for i = 1, #params do
keys[ params[ i ] ] = key
end
end
end
local targetKey
for key, arg in pairs( templateArgs ) do
targetKey = keys[ key ]
if targetKey then
if args[ targetKey ] then -- prevents duplicates
table.insert( mu.duplicateAliases, "''" .. key .. "''" )
else
args[ targetKey ] = arg
end
else
table.insert( mu.invalidParams, "''" .. key .. "''" )
end
end
return args
end
function mu.addWdClass( isFromWikidata )
return isFromWikidata and ' voy-wikidata-content' or ''
end
-- getting DMS coordinates
function mu.dmsCoordinates( lat, long, name, fromWD, extraParams, withBrackets )
local dec
local latDMS, dec, latMs = cd.getDMSString( lat, 4, 'lat', '', '', mi.defaultDmsFormat )
local longDMS, dec, longMs = cd.getDMSString( long, 4, 'long', '', '', mi.defaultDmsFormat )
local r = '[' .. mi.coordURL .. latMs .. '_' .. longMs .. '_'
.. mw.uri.encode( extraParams ) .. '&locname=' .. mw.uri.encode( name )
.. ' ' .. tostring( mw.html.create( 'span' )
:addClass( 'coordStyle' )
:attr( 'title', mi.texts.latitude )
:wikitext( latDMS )
)
.. ' ' .. tostring( mw.html.create( 'span' )
:addClass( 'coordStyle' )
:attr( 'title', mi.texts.longitude )
:wikitext( longDMS )
)
.. ']'
if withBrackets then
r = '(' .. r .. ')'
end
return tostring( mw.html.create( 'span' )
:attr( 'class', 'listing-dms-coordinates printNoLink plainlinks'
.. mu.addWdClass( fromWD ) )
:wikitext( r ) )
end
local function replaceWithSpace( s, pattern )
s = s:find( pattern ) and s:gsub( pattern, ' ' ) or s
return s
end
-- removing line breaks and controls from parameter strings
function mu.removeCtrls( s, onlyInline )
local descrDiv = false -- div tag instead of span tag for description needed?
-- remove controls from tags before test
s = s:gsub( '(<[^>]+>)', function( t )
return replaceWithSpace( t, '[%z\1-\31]' )
end )
local t = replaceWithSpace( s, '</br%s*>' )
if onlyInline then
t = replaceWithSpace( t, '<br[^/>]*/*>' )
t = replaceWithSpace( t, '</*p[^/>]*/*>' )
t = replaceWithSpace( t, '[%z\1-\31]' )
-- not %c because \127 is used for Mediawiki tags (strip markers `UNIQ)
else
t = replaceWithSpace( t, '[%z\1-\9\11\12\14-\31]' )
descrDiv = t:find( '[\10\13]' ) or t:find( '<br[^/>]*/*>' ) or
t:find( '<p[^/>]*>' )
end
if t ~= s then
mu.addMaintenance( mi.maintenance.illegalCtrls )
end
-- remove LTR and RTL marks
t = mw.ustring.gsub( t, '[]+', '' )
if descrDiv then
mu.addMaintenance( mi.maintenance.descrDiv )
-- unify line breaks to Linux mode
t = t:gsub( '\13\10', '\10' ):gsub( '\13', '\10' )
-- replace line breaks by <br> in block mode
t = t:gsub( '([^>%]\10])\10+([^<%[\10])', '%1<br class="listing-next-paragraph" />%2' )
end
return replaceWithSpace( t, '%s%s+' ), descrDiv
end
local colorAdjust = { ['-webkit-print-color-adjust'] = 'exact', ['color-adjust'] = 'exact',
['print-color-adjust'] = 'exact' }
function mu.addLinkIcon( classes, link, title, text )
local span = tostring( mw.html.create( 'span' )
:attr( 'title', title )
:css( colorAdjust )
:wikitext( ' ' .. text )
)
local lFormat = ( link:find( '^https?://' ) or link:find( '^//' ) )
and '[%s %s]' or '[[%s|%s]]'
return tostring( mw.html.create( 'span' )
:attr( 'class', 'listing-icon ' .. classes )
:wikitext( mw.ustring.format( lFormat, link, span ) )
)
end
-- adding linked sister icons
local function addSisterIcons( icons, sisters, name, id )
local link, span
for i, key in ipairs( { 'wikivoyage', 'wikipedia', 'commons', 'wikidata' } ) do
if mu.isSet( sisters[ key ] ) then
span = mu.addLinkIcon( 'listing-sister-icon listing-sister-' .. key, sisters[ key ],
mw.ustring.format( mi.iconTitles[ key ], name, id ), key )
table.insert( icons, span )
end
end
-- return true if only Wikidata icon
return mu.isSet( sisters.wikidata ) and #icons == 1
end
-- getting sister project links
local function getWikiLink( langArray, wiki, entity, wikilang )
local prefix = wiki == 'wiki' and 'w:' or 'voy:'
local link
for i, lang in ipairs( langArray ) do
if lang ~= '' then
link = wu.getSitelink( entity, lang .. wiki )
if link then
prefix = prefix .. ( lang ~= wikilang and ( lang .. ':' ) or '' )
return prefix .. link
end
end
end
return ''
end
function mu.getLangTable( wikiLang, localLang )
local langs = { wikiLang }
for i, lang in ipairs( mi.langs ) do
table.insert( langs, lang )
end
if mu.isSet( localLang ) and localLang ~= wikiLang then
table.insert( langs, localLang )
end
return langs
end
-- adding Wikimedia sister project icons
function mu.makeSisterIcons( icons, args, page, country, entity )
local sisters = {
commons = '', -- link to Commons category
wikidata = '', -- link to Wikidata
wikipedia = '', -- link to Wikipedia
wikivoyage = '' -- link to another branch, usually en, as a sister link
}
if mu.isSet( args.wikipedia ) then
sisters.wikipedia = 'w:' .. args.wikipedia
end
if mu.isSet( args.wikidata ) then
local langs = mu.getLangTable( page.lang, country.lang )
if sisters.wikipedia == '' then
sisters.wikipedia = getWikiLink( langs, 'wiki', entity, page.lang )
end
if args.wikiPage == '' then
table.remove( langs, 1 ) -- exclude page.lang
sisters.wikivoyage = getWikiLink( langs, page.globalProject, entity, page.lang )
if sisters.wikivoyage ~= '' then
mu.addMaintenance( mi.maintenance.linkToOtherWV )
end
end
sisters.wikidata = 'd:' .. args.wikidata
end
if args.commonscat ~= '' then
sisters.commons = 'c:Category:' .. args.commonscat
end
return addSisterIcons( icons, sisters, args.givenName.name, args.wikidata )
end
function mu.removeStars( args, params )
for i, param in ipairs( params ) do
if args[ param ]:find( '*', 1, true ) then
args[ param ] = args[ param ]:gsub( '%*+', '' )
args[ param ] = mw.text.trim( args[ param ] )
mu.addMaintenance( mi.maintenance.nameWithStar )
end
end
end
-- getting name table with linked and unlinked names
function mu.getName( name, pageTitle )
local r = {
exists = false,
all = '', -- name or linked name
name = '', -- only name
pageTitle = '', -- if pageTitle ~= '' name is already linked
}
if type( name ) ~= 'string' or name == '' then
return r
end
r.exists = true
local s
local t, c = mw.ustring.gsub( name, '^(.*)%[%[(.*)%]%](.*)$', '%2' )
if c > 0 then -- is / contains [[...]]
t = mw.text.trim( t )
r.all = '[[' .. t .. ']]'
s, c = mw.ustring.gsub( t, '^(.*)|(.*)$', '%2' )
if c > 0 then -- is [[...|...]]
r.name = mw.text.trim( s )
r.pageTitle = mw.ustring.gsub( t, '^(.*)|(.*)$', '%1' )
r.pageTitle = mw.text.trim( r.pageTitle )
else
r.name = t
r.pageTitle = t
end
else
r.name = name
r.all = name
if pageTitle ~= '' then
r.pageTitle = pageTitle
r.all = '[[' .. pageTitle .. '|' .. name .. ']]'
end
end
mu.removeStars( r, { 'name', 'all' } )
return r
end
-- checking coordinates
function mu.checkCoordinates( args )
local function clearCoordinates()
args.lat = ''
args.long = ''
end
local t
if type( args.lat ) == 'boolean' or type( args.long ) == 'boolean' then
clearCoordinates()
end
if args.lat == '' and args.long == '' then
return
elseif args.lat ~= '' and args.long == '' then
t = args.lat:find( ',', 1, true )
if t then
args.long = mw.text.trim( args.lat:sub( t + 1, #args.lat ) )
args.lat = mw.text.trim( args.lat:sub( 1, t - 1 ) )
end
end
if args.lat == '' or args.long == '' then
clearCoordinates()
mu.addMaintenance( mi.maintenance.wrongCoord )
return
end
local dms = false
t = tonumber( args.lat )
if t then
args.lat = math.abs( t ) <= 90 and t or ''
else
t = cd.toDec( args.lat, 'lat', 6 )
args.lat = t.error == 0 and t.dec or ''
dms = args.lat ~= ''
end
if args.lat ~= '' then
t = tonumber( args.long )
if t then
args.long = ( t > -180 and t <= 180 ) and t or ''
else
t = cd.toDec( args.long, 'long', 6 )
args.long = t.error == 0 and t.dec or ''
dms = dms or args.long ~= ''
end
end
if args.lat == '' or args.long == '' then
clearCoordinates()
mu.addMaintenance( mi.maintenance.wrongCoord )
elseif dms then
mu.addMaintenance( mi.maintenance.dmsCoordinate )
end
end
-- getting a set of parameters for a given type
function mu.getTypeParams( aType )
return mt.types[ aType ]
end
local function encodeSpaces( s )
if s:find( '[_%s]+' ) then
s = s:gsub( '[_%s]+', '_' )
end
return s
end
local function getTypeFromTypeAliases( aType )
if not mu.typeAliases then
mu.typeAliases = mu.getAliases( mt.types, 'alias' )
end
return next( mu.typeAliases ) and mu.typeAliases[ aType ]
end
function mu.typeExists( aType )
return mt.types[ aType ] and aType or getTypeFromTypeAliases( aType )
end
-- groups translation for map legend into Wiki language
local function translateGroup( group )
if not mu.isSet( group ) then
group = mt.types.error.group
end
local t = mg.groups[ group ]
if t then
t = t.map or t.label or t.alias or group
if type( t ) == 'table' then
t = t[ 1 ]
end
return t
end
return group
end
local function getGroupFromGroupAliases( group )
if not mu.groupAliases then
mu.groupAliases = mu.getAliases( mg.groups, 'alias' )
end
return next( mu.groupAliases ) and mu.groupAliases[ group ]
end
-- check if the specified group can have events
function mu.groupWithEvents( group )
return mg.groups[ group ] and mg.groups[ group ].withEvents
end
-- getting marker type and group
function mu.checkTypeAndGroup( args )
local s, t
args.typeTable = {}
args.subtypeTable = {}
if mu.isSet( args.group ) then
mu.addMaintenance( mi.maintenance.groupUsed )
s = mg.groups[ args.group ]
if not s then
s = getGroupFromGroupAliases( args.group )
s = s and mg.groups[ s ]
end
if not s then
mu.addMaintenance( mi.maintenance.unknownGroup )
args.group = ''
elseif s.is and s.is == 'color' then
mu.addMaintenance( mi.maintenance.groupIsColor )
if mi.options.useTypeCateg then
mu.addMaintenance( mw.ustring.format( mi.maintenance.type, args.group ) )
end
end
end
if not mu.isSet( args.type ) then
args.type = mt.types.error.group
if args.group == '' then
args.group = mt.types.error.group
end
mu.addMaintenance( mi.maintenance.missingType )
elseif args.type == mt.types.error.group then
if args.group == '' then
args.group = mt.types.error.group
end
mu.addMaintenance( mi.maintenance.unknownType )
else
-- split seperate types and analyse them
for i, t in ipairs( mu.textSplit( args.type, ',' ) ) do
-- try to find the type t in types or groups
t = encodeSpaces( t:lower() )
if not mt.types[ t ] then
s = getTypeFromTypeAliases( t )
if not s then
s = getGroupFromGroupAliases( t )
end
t = s or t
end
s = mg.groups[ t ]
if s then -- type is a group itself
if s.is and s.is == 'color' then
mu.addMaintenance( mi.maintenance.typeIsColor )
elseif not mi.options.noTypeMsgs then
mu.addMaintenance( mi.maintenance.typeIsGroup )
end
if args.group == '' then
args.group = t
end
else
s = mt.types[ t ]
if s then
if args.group == '' then
args.group = s.group
end
if mu.isSet( s.subtype ) then
table.insert( args.subtypeTable, t )
end
else
mu.addMaintenance( mi.maintenance.unknownType )
args.group = mt.types.error.group
end
end
table.insert( args.typeTable, t )
end
args.type = table.concat( args.typeTable, ',' )
end
args.groupTranslated = translateGroup( args.group )
end
function mu.checkStatus( args )
args.statusTable = {}
local hash = {}
if mu.isSet( args.status ) then
local statusAliases = mu.getAliases( mi.statuses, 'alias' )
if not next( statusAliases ) then
statusAliases = nil
end
for i, t in ipairs( mu.textSplit( args.status, ',' ) ) do
t = encodeSpaces( t:lower() )
if statusAliases then
t = statusAliases[ t ] or t
end
if mi.statuses[ t ] then
if not hash[ t ] then
table.insert( args.statusTable, t )
hash[ t ] = 'x'
end
else
mu.addMaintenance( mi.maintenance.unknownStatus )
end
end
end
end
function mu.makeStatusIcons( args )
local result = ''
if args.statusTable and #args.statusTable > 0 then
for k, v in pairs( args.statusTable ) do
result = result .. tostring( mw.html.create( 'span' )
:addClass( 'listing-status listing-status-' .. v )
:attr( 'title', mi.statuses[ v ].label )
:css( colorAdjust )
:wikitext( v )
)
end
end
return result
end
local function removeNS( s, nsTable )
s = s or ''
if not s:find( ':', 1, true ) then
return s
end
local t = s
for i = 1, #nsTable do
t = mw.ustring.gsub( t, '^' .. nsTable[ i ] .. ':', '' )
if s ~= t then
break
end
end
return t
end
-- image check
function mu.checkImage( args, entity )
if type( args.image ) == 'boolean' or args.image == '' then
return
end
-- formal checks
if args.image:find( '^https?:' ) then
args.image = ''
else
-- remove namespace
args.image = removeNS( args.image, mi.texts.FileNS )
local extensionExists = false
local im = args.image:lower()
for i = 1, #mi.fileExtensions do
if im:find( '%.' .. mi.fileExtensions[ i ] .. '$' ) then
extensionExists = true
break
end
end
if not extensionExists then
args.image = ''
end
end
if args.image == '' then
mu.addMaintenance( mi.maintenance.wrongImgName )
return
end
local alreadyChecked = false
if mi.options.mediaCheck and args.image ~= '' then
if not mi.options.WDmediaCheck and entity then
-- check if image is stored in Wikidata
local imgs = wu.getValues( entity, mi.properties.image, nil )
for i = 1, #imgs do
if imgs[ i ] == args.image then
alreadyChecked = true
break
end
end
end
if not alreadyChecked then
-- expensive function call
local title = mw.title.new( 'Media:' .. args.image )
if not title or not title.exists then
mu.addMaintenance( mw.ustring.format( mi.maintenance.missingImg, args.image ) )
args.image = ''
end
end
end
end
local function isUrl( url )
uc = uc or require( 'Module:UrlCheck' )
return uc.isUrl( url, mi.options.skipPathCheck )
end
-- url check in args
function mu.checkUrl( args )
if mu.isSet( args.url ) then
local c = isUrl( args.url ) -- getting result code
if c > 2 then
mu.addMaintenance( mi.maintenance.wrongUrl )
args.url = ''
elseif c == 2 then -- URL contains IP address
mu.addMaintenance( mi.maintenance.urlWithIP )
else
for i = 1, #mi.services do
if args.url:find( mi.services[ i ].key .. '.com', 1, true ) then
mu.addMaintenance( mi.maintenance.urlIsSocialMedia )
args.url = ''
end
end
end
end
end
function mu.setCopyMarker( args, show )
if show.copy and ( mu.isSet( args.copyMarker ) or not mu.isSet( args.wikidata ) ) then
show.copy = false
mu.addMaintenance( mi.maintenance.deleteShowCopy )
end
if show.copy then
args.copyMarker = args.wikidata
end
end
-- making marker symbol
function mu.makeMarkerSymbol( args, title, frame )
local inverseClass = args.inverse and ' listing-map-inverse' or ''
local copyClass = 'listing-map plainlinks printNoLink voy-copy-marker'
.. inverseClass
if mu.isSet( args.copyMarker ) then
return tostring( mw.html.create( 'span' )
:addClass( copyClass )
:attr( 'title', mi.texts.tooltip )
:css( colorAdjust )
-- display will be replaced by [[MediaWiki:Gadget-GeneralChanges.js]] script
:css( { display = 'none' } )
:attr( 'data-copy-marker-attribute', args.copyMarker:match( 'Q%d+' )
and 'data-wikidata' or 'data-name' )
:attr( 'data-copy-marker-content', args.copyMarker )
)
end
local lon = tonumber( args.long )
local lat = tonumber( args.lat )
local tagArgs = {
zoom = tonumber( args.zoom ),
latitude = lat,
longitude = lon,
show = mg.showAll,
}
if mu.isSet( args.text ) then
tagArgs.text = args.text
if not args.useIcon then
tagArgs.class = 'no-icon'
end
end
if mu.isSet( args.mapGroup ) then
tagArgs.group = args.mapGroup
tagArgs.show = args.mapGroup
else
tagArgs.group = args.groupTranslated
end
if mu.isSet( args.image ) then
tagArgs.description = '[[File:' .. args.image .. '|100x100px|' .. title .. ']]'
end
local geoJson = {
type = 'Feature',
geometry = {
type = 'Point',
coordinates = { lon, lat }
},
properties = {
title = title,
description = tagArgs.description,
['marker-symbol'] = args.symbol,
['marker-color'] = args.color,
['marker-size'] = 'medium',
}
}
return tostring( mw.html.create( 'span' )
:addClass( 'listing-map plainlinks printNoLink' .. inverseClass )
:attr( 'title', mi.texts.tooltip )
:css( colorAdjust )
:css( 'background-color', args.color )
-- frame:extensionTag is expensive
:wikitext( frame:extensionTag( 'maplink', mw.text.jsonEncode( geoJson ), tagArgs ) )
)
end
-- getting color from group in args
function mu.getColor( args )
local c = mg.groups[ args.group ] or mg.groups[ 'error' ]
args.color = c.color
args.inverse = c.inverse
end
-- replace brackets in names
function mu.replaceBrackets( s )
local count
s, count = s:gsub( '%[', '[' )
:gsub( '%]', ']' )
return s
end
function mu.convertForSort( s )
s = mw.ustring.lower( s )
for i, obj in ipairs( mi.substitutes ) do
s = mw.ustring.gsub( s, obj.l, obj.as )
end
return s
end
-- prepare value s for data attribute and replace all entities by characters
function mu.data( s )
return mu.isSet( s ) and mw.text.decode( s, true ) or nil
end
-- adding wrapper and microformats
function mu.makeWrapper( result, args, page, country, show, list, aClass, frame )
if type( result ) == 'table' then
result = table.concat( result, ' ' )
end
local wrapper = mw.html.create( show.inline and 'span' or 'div' )
:attr( 'class', 'vcard h-card ' .. aClass )
if args.noGpx then
wrapper:addClass( 'listing-no-gpx' )
end
if show.outdent and not show.inline then
wrapper:addClass( 'listing-outdent' )
end
if show.inlineSelected then
wrapper:addClass( 'listing-inline' )
end
if mu.isSet( args.copyMarker ) or not show.poi then
wrapper:addClass( 'voy-without-marker' )
end
if args.givenName.name ~= mi.maintenance.missingName then
wrapper:attr( 'data-name', mu.data( args.givenName.name ) )
end
if args.statusTable and #args.statusTable > 0 then
wrapper:addClass( 'listing-with-status' )
end
if mu.isSet( args.wikidata ) then
wrapper:attr( 'id', 'vCard_' .. args.wikidata )
end
wrapper:attr( 'data-location', mu.data( page.subpageText ) )
:attr( 'data-location-qid', page.entityId )
:attr( 'data-wikilang', page.lang )
:attr( 'data-country', mu.data( country.iso_3166 ) )
:attr( 'data-country-name', mu.data( country.country ) )
:attr( 'data-lang', mu.data( country.lang ) )
:attr( 'data-lang-name', mu.data( country.langName ) )
:attr( 'data-country-calling-code', mu.data( country.cc ) )
:attr( 'data-trunk-prefix', mu.data( country.trunkPrefix ) )
:attr( 'data-dir', mu.data( country.isRTL and 'rtl' or 'ltr' ) )
:attr( 'data-wiki-dir', mu.data( page.isRTL and 'rtl' or 'ltr' ) )
:attr( 'data-currency', mu.data( country.addCurrency ) )
local arg
for key, value in pairs( list ) do
arg = args[ key ]:gsub( '<[^<>]*>', '' ) -- remove html tags
wrapper:attr( value, mu.data( arg ) )
end
if not show.noCoord then
wrapper:node( mw.html.create( 'span' )
:attr( 'class', 'p-geo geo listing-coordinates' )
:css( 'display', 'none' )
:node( mw.html.create( 'span' )
:attr( 'class', 'p-latitude latitude' )
:wikitext( args.lat )
)
:node( mw.html.create( 'span' )
:attr( 'class', 'p-longitude longitude' )
:wikitext( args.long )
)
)
end
if not show.name then
wrapper:node( mw.html.create( 'span' )
:attr( 'class', 'p-name fn org listing-name' )
:css( 'display', 'none' )
:wikitext( args.givenName.name )
)
end
wrapper = tostring( wrapper:wikitext( result ) )
-- adding coordinates to Mediawiki database
-- frame:callParserFunction is expensive
if not show.noCoord and mi.options.secondaryCoords then
wrapper = wrapper .. frame:callParserFunction{ name = '#coordinates',
args = { args.lat, args.long, country.extra, name = args.givenName.name } }
end
return wrapper
end
-- bdi and bdo tags are not working properly on all browsers. Adding marks
-- (lrm, rlm) is maybe the only way for a correct output
function mu.languageSpan( s, titleHint, page, country, addClass )
if not mu.isSet( s ) then
return ''
end
local bdi = mw.html.create( 'bdi' )
:addClass( addClass )
:wikitext( s )
local c = country.lang
if c == '' or c == page.lang then
return tostring( bdi )
end
local dir
local fStr = '%s'
if country.isRTL and not page.isRTL then
dir = 'rtl'
fStr = '‏%s‎'
elseif not country.isRTL and page.isRTL then
dir = 'ltr'
fStr = '‎%s‏'
end
return fStr:format( tostring( bdi
:addClass( 'voy-lang voy-lang-' .. c )
:attr( 'lang', c )
:attr( 'dir', dir )
:attr( 'title', mw.ustring.format( titleHint , country.langName ) )
) )
end
-- Splitting comma separated lists to an array
-- convert = true: conversion to lowercase characters, spaces to low lines
-- toValue = true: list items handled as array values
-- toValue = false: list items handled as array keys
function mu.split( s, convert, toValue )
local arr = {}
if not mu.isSet( s ) then
return arr
end
for i, str in ipairs( mu.textSplit( s, ',' ) ) do
if convert then
str = encodeSpaces( str:lower() )
end
if toValue then
table.insert( arr, str )
else
arr[ str ] = ''
end
end
return arr
end
-- Splitting comma separated lists to a table of key items
-- checking items with allowed key values of validValues table
local function splitAndCheck( s, validValues )
local values = {}
if not mu.isSet( s ) or not validValues then
return values, ''
end
local errors = {}
for item, v in pairs( mu.split( s, true ) ) do
-- value check
if validValues[ item ] then
values[ item ] = ''
else
table.insert( errors, item )
end
end
return values, table.concat( errors, ', ' )
end
function mu.getShow( default, value, validValues )
local show = mu.split( default, true )
local add, err = splitAndCheck( value, validValues )
if err ~= '' then
mu.addMaintenance( mw.ustring.format( mi.maintenance.unknownShow, err ) )
end
if add.none or add.coord or add.poi or add.all then
show.all = nil -- overwriting defaults
show.coord = nil
show.poi = nil
end
for key, value in pairs( add ) do
show[ key ] = value
end
if show.none then
show.none = nil
show.all = nil
show.coord = nil
show.poi = nil
end
if show.all then
show.all = nil
show.coord = ''
show.poi = ''
end
return show
end
function mu.getCoordinatesFromWikidata( args, fromWikidata, entity )
if not entity or ( args.lat ~= '' and args.long ~= '' ) then
return
end
-- center coordinates from Wikidata
local c = wu.getValue( entity, mi.properties.centerCoordinates )
if c == '' then
-- coordinates from Wikidata
c = wu.getValue( entity, mi.properties.coordinates )
end
if c ~= '' then
args.lat = c.latitude
args.long = c.longitude
fromWikidata.lat = true
end
end
-- create social media icons including value check
function mu.makeSocial( icons, args, fromWikidata, name )
local domain, span, t
for i, service in ipairs( mi.services ) do
-- check values first
t = args[ service.key ] or ''
domain = service.url:gsub( 'com/.*', 'com/' )
if t ~= '' then
if t:match( '^http' ) then
if not t:find( 'https', 1, true ) then
t = t:gsub( '^http', 'https' )
mu.addMaintenance( mw.ustring.format(
mi.maintenance.wrongSocialUrl, service.key ) )
end
if isUrl( t ) > 1 or
not t:match( '^' .. domain .. '.+$' ) then
t = ''
mu.addMaintenance( mw.ustring.format(
mi.maintenance.wrongSocialUrl, service.key ) )
end
if t ~= '' and not fromWikidata[ service.key ] then
mu.addMaintenance( mw.ustring.format(
mi.maintenance.socialUrlUsed, service.key ) )
end
else
local match = false
local sp = service.pattern
if type( sp ) == 'string' then
sp = { sp }
end
for i = 1, #sp do
if mw.ustring.match( t, sp[ i ] ) then
match = true
break
end
end
if not match then
t = ''
mu.addMaintenance( mw.ustring.format(
mi.maintenance.wrongSocialId, service.key ) )
end
end
end
args[ service.key ] = t
-- create symbol link
if t ~= '' then
if not t:find( domain, 1, true ) then
t = mw.ustring.format( service.url, t )
end
span = mu.addLinkIcon( 'listing-social-media listing-social-media-' ..
service.key .. mu.addWdClass( fromWikidata[ service.key ] ), t,
mw.ustring.format( mi.iconTitles[ service.key ], name ), service.key )
table.insert( icons, span )
end
end
end
local function _makeAirport( code, args, fromWikidata )
local span = mw.html.create( 'span' )
:attr( 'class', 'listing-' .. code .. '-code'
.. mu.addWdClass( fromWikidata[ code ] ) )
:wikitext( args[ code ] )
return tostring( mw.html.create( 'span' )
:attr( 'class', 'listing-airport listing-' .. code )
:wikitext( mw.ustring.format( mi.texts[ code ], tostring( span ) ) )
)
end
function mu.makeAirport( args, show, fromWikidata )
if show.noairport then
return ''
else
local t = args.type:gsub( ',.*$', '' ) -- only first type
if mt.types[ t ] and not mt.types[ t ].useIATA then
return ''
end
end
if mu.isSet( args.iata ) then
return _makeAirport( 'iata', args, fromWikidata )
elseif mu.isSet( args.icao ) then
return _makeAirport( 'icao', args, fromWikidata )
else
return ''
end
end
function mu.idToType( id )
if not mu.types then
mu.types = mu.getAliases( mt.types, 'wd' ) -- Q id to type table
end
return mu.types[ id ]
end
local function _typeSearch( p31 )
-- p31: array of Wikidata values
if not p31 or #p31 == 0 then
return ''
end
local firstStep = true
local function compareLabels( ar )
if not ar then
return nil
elseif type( ar ) == 'string' then
ar = { ar }
end
for i, value in ipairs( ar ) do
if mu.isSet( value ) then
value = mw.ustring.lower( encodeSpaces( value ) )
if mt.types[ value ] then
return value
end
end
end
return nil
end
local function compareIds( ar )
local id, t
for i = 1, #ar do
id = ar[ i ].id
-- md: indexed array of q id - types relations
t = mu.idToType( id )
if t then
return t
end
-- checking English label and aliases
t = compareLabels( mw.wikibase.getLabelByLang( id, 'en' ) )
or compareLabels( wu.getAliases( id, 'en' ) )
if t then
if firstStep and not mi.options.noTypeMsgs then
firstStep = false
mu.addMaintenance( mi.maintenance.typeFromWDchain )
end
return t
end
end
return nil
end
local aType = compareIds( p31 ) -- check p31 ids first, maybe step 2 is not nessary
if aType then
if not mi.options.noTypeMsgs then
mu.addMaintenance( mi.maintenance.typeFromWD )
end
return aType
end
-- now functions becomes expensive because of multiple wu.getValues calls
local id, ids
firstStep = false
for i = 1, #p31 do -- step 2: analyse P279 chains of first ids
id = p31[ i ].id -- start id
local j = 0
repeat
ids = wu.getValues( id, mi.properties.subclassOf, nil )
if #ids > 0 then
aType = compareIds( ids )
if aType then
if not mi.options.noTypeMsgs then
mu.addMaintenance( mi.maintenance.typeFromWD )
mu.addMaintenance( mi.maintenance.typeFromWDchain )
end
return aType
end
id = ids[ 1 ].id
end
j = j + 1
-- limit: maximum levels to analyse
until j >= mi.searchLimit or #ids == 0
end
return ''
end
function mu.typeSearch( p31, entity )
if p31 and #p31 == 0 then
p31 = wu.getValues( entity, mi.properties.subclassOf, mi.p31Limit )
end
return _typeSearch( p31 )
end
-- returns a single data set from Module:Marker utilities/Maki icons
function mu.getMaki( key )
mm = mm or require( 'Module:Marker utilities/Maki icons' )
return mm.icons[ key ]
end
function mu.getMakiIconId( aType )
aType = mu.getMaki( aType ) and aType or
( mt.types[ aType ] and mt.types[ aType ].icon )
if aType and mu.getMaki( aType ) and mu.isSet( mu.getMaki( aType ).im ) then
return aType
else
return nil
end
end
function mu.checkCommonsCategory( args )
-- remove namespace from category
if type( args.commonscat ) == 'string' and args.commonscat ~= '' then
args.commonscat = removeNS( args.commonscat, mi.texts.CategoryNS )
if args.commonscat ~= '' then
mu.addMaintenance( mi.maintenance.commonscat )
end
end
end
function mu.getCommonsCategory( args, entity )
-- getting commonscat from commonswiki sitelink before P373
-- because sitelink is checked by Wikidata
if type( args.commonscat ) == 'boolean' then
args.commonscat = ''
end
local t = wu.getSitelink( entity, 'commonswiki' ) or ''
if t:match( '^Category:.+$' ) then
t = t:gsub( '^Category:', '' )
else
t = wu.getValue( entity, mi.properties.commonsCategory )
if t == '' then
local id = wu.getId( entity, mi.properties.mainCategory )
if id ~= '' then
t = wu.getSitelink( id, 'commonswiki' ) or ''
t = t:gsub( '^Category:', '' )
end
end
end
if t ~= '' and args.commonscat ~= '' then
mu.addMaintenance( mi.maintenance.commonscatWD )
end
if args.commonscat == '' then
args.commonscat = t
end
end
-- getting names from Wikidata
function mu.getNamesFromWikidata( args, fromWikidata, page, country, entity )
-- getting official names
local officialNames =
wu.getMonolingualValues( entity, mi.properties.officialName )
if type( args.name ) == 'boolean' or args.name == '' then
args.name = ''
local langs = mu.getLangTable( page.lang )
for i, lang in ipairs( langs ) do
args.name = officialNames[ lang ]
if args.name then
break
end
end
-- if failed then get labels
if not mu.isSet( args.name ) then
for i, lang in ipairs( langs ) do
args.name = wu.getLabel( entity, lang, true )
if args.name then
break
end
end
args.name = args.name or ''
end
if args.name ~= '' then
mu.addMaintenance( mi.maintenance.nameFromWD )
fromWikidata.name = true
end
end
-- get local name if no name is available
if args.name == '' and
not ( type( args.nameLocal ) == 'string' and args.nameLocal ~= '' ) then
args.nameLocal = true
-- no local name if country and wiki language are identical
elseif args.nameLocal == true and page.lang == country.lang then
args.nameLocal = ''
end
if args.nameLocal == true then
args.nameLocal = officialNames[ country.lang ] or ''
if args.nameLocal == '' then
args.nameLocal = wu.getLabel( entity, country.lang, true ) or ''
end
if args.name == '' and args.nameLocal ~= '' then
args.name = args.nameLocal
args.nameLocal = ''
mu.addMaintenance( mi.maintenance.nameFromWD )
fromWikidata.name = true
end
if args.name:lower() == args.nameLocal:lower() then
args.nameLocal = ''
end
fromWikidata.nameLocal = args.nameLocal ~= ''
if fromWikidata.nameLocal then
mu.addMaintenance( mi.maintenance.localNameFromWD )
end
end
end
-- getting link to Wikivoyage
function mu.getArticleLink( args, entity, page )
local t = wu.getSitelinkTable( entity, page.lang .. page.globalProject )
if t and t.title ~= page.text then -- no link to the article itself
local isLink = false
for i, badge in ipairs( t.badges ) do
if badge == mi.qualifiers.intentionalSitelink or
badge == mi.qualifiers.redirectSitelink then
isLink = true
break
end
end
if not isLink then
args.wikiPage = t.title
end
end
end
-- replacing decimal separator and inserting group separators
function mu.formatNumber( num )
if mu.isSet( mi.formatnum.decimalPoint ) and mi.formatnum.decimalPoint ~= '.' then
num = num:gsub( '%.', mi.formatnum.decimalPoint )
end
if mu.isSet( mi.formatnum.groupSeparator ) then
local count
repeat
num, count = num:gsub( '^([-+]?%d+)(%d%d%d)',
'%1%' .. mi.formatnum.groupSeparator .. '%2' )
until count == 0
end
return num
end
function mu.getTypeLabel( id )
if not mu.isSet( id ) then
return ''
end
if id:match( '^Q%d+$' ) then
id = mu.idToType( id )
if not id then
return ''
end
end
local at, t
id = id:gsub( '[_%s]+', '_' )
t = mt.types[ id ]
if not t then
t = getTypeFromTypeAliases( id )
t = t and mt.types[ t ]
end
if t then
t = t.label or id
at = t:find( ',' )
if at then
t = t:sub( 1, at - 1 )
end
else
t = id:gsub( '_', ' ' )
end
return t
end
function mu.getPageData()
local page = mw.title.getCurrentTitle()
page.langObj = mw.getContentLanguage()
page.lang = page.langObj:getCode()
page.langName = mw.language.fetchLanguageName( page.lang, page.lang )
page.isRTL = page.langObj:isRTL()
page.entityId = mw.wikibase.getEntityIdForCurrentPage() -- can be nil
page.siteName = mw.site.siteName
page.globalProject = page.siteName:lower()
if page.globalProject == 'wikipedia' then
page.globalProject = 'wiki'
end
return page
end
return mu