Dokumentation für das Modul GetProvince/Test[Ansicht] [Bearbeiten] [Versionsgeschichte] [Aktualisieren]

Verwendung

Das Submodul ist eine Testversion des Moduls GetProvince und nicht für den Produktivbetrieb geeignet. Es dient der Weiterentwicklung des Moduls GetProvince, damit sich Änderungen nicht auf alle Artikel auswirken, die das Modul benutzen.

Das Modul ist eine Spielwiese und nicht zum produktiven Einsatz vorgesehen. Der derzeitige Code ist eine finale Testversion zur Inbetriebnahme. Er enthält für Analysezwecke zusätzliche Wikidata-Abfragen und Ausgaben.

Analyse

Die Tabelle gibt jeweils die nächste administrative Einheit an. Sowohl P31 (istEin) als auch P131 (liegt in der administrativen Einheit) können mehrfach vorkommen, was in der jetzigen Quickbar gar nicht berücksichtigt wird. P10229 wird im jetzigen Entwicklungsstand mit berücksichtigt Die bisherige Suche hätte bei Redcar and Cleveland einen falschen Pfad genommen, obwohl beide bei England landen, was aber nicht immer gesichert ist.

Redcar and Cleveland - Hier ist die P300 vorhanden, obwohl nicht 1. Ordnung, aber P10229 ist vergeben. Sie gibt vor, welche der drei Einheiten im nächsten Level zu verwenden ist (siehe nächstes Objekt) table#1 {

   ["P297"] = "",
   ["P300"] = "GB-RCC",
   ["P31"] = table#2 {
       "Q1136601",
       "Q1006876",
   },
   ["adminTerritory"] = table#3 {
       ["Q23086"] = table#4 {
           ["P10229"] = "Q47983",
           ["P3831"] = "",
           ["P580"] = "",
           ["P582"] = "",
           ["dewikivoyage"] = "North Yorkshire",
           ["label"] = "North Yorkshire",
       },
   },
   ["dewikivoyage"] = "",
   ["label"] = "Redcar and Cleveland",

}


North Yorkshire - Dies ist die nächste Einheit. Die P10229 im vorigen Objekt gibt an, welche ID beim Hochhangeln hier zu verwenden ist. In diesem Falle, geht es über "North East England" weiter. table#1 {

   ["P297"] = "",
   ["P300"] = "",
   ["P31"] = table#2 {
       "Q180673",
   },
   ["adminTerritory"] = table#3 {
       ["Q47983"] = table#4 {
           ["P10229"] = "",
           ["P3831"] = "",
           ["P580"] = "1994-04-01",
           ["P582"] = "",
           ["dewikivoyage"] = "North East England",
           ["label"] = "North East England",
       },
       ["Q48063"] = table#5 {
           ["P10229"] = "",
           ["P3831"] = "",
           ["P580"] = "1994-04-01",
           ["P582"] = "",
           ["dewikivoyage"] = "",
           ["label"] = "Yorkshire and the Humber",
       },
   },
   ["dewikivoyage"] = "North Yorkshire",
   ["label"] = "North Yorkshire",

}


Lelystad (Q166065) - Selbstreferenz (Objekt ist inzwischen bereinigt) und weiterer Qualifikator P3831 (Objekt fungiert als) table#1 {

   ["P297"] = "",
   ["P300"] = "",
   ["P31"] = table#2 {
       "Q515",
       "Q1852859",
       "Q2039348",
   },
   ["adminTerritory"] = table#3 {
       ["Q707"] = table#4 {
           ["P10229"] = "",
           ["P3831"] = "Q134390",
           ["P580"] = "",
           ["P582"] = "",
           ["dewikivoyage"] = "Flevoland",
           ["label"] = "Flevoland",
       },
   },
   ["dewikivoyage"] = "Lelystad",
   ["label"] = "Lelystad",

}


Testaufrufe

Die Testaufrufe zeigen (hoffentlich) alle möglichen Szenarien und bilden sie richtig ab. Als mögliche Spielerei kann man sich auch den kompletten Hierarchie-Pfad anzeigen lassen.

  • Dieser Artikel: {{#invoke:GetProvince/Test|getProvince}}
  • Europa: WD vorhanden, aber Suche sollte abbrechen {{#invoke:GetProvince/Test|getProvince|Q46}}
  • Redcar and Cleveland: Abfrage Provinz: {{#invoke:GetProvince/Test|getProvince|Q1434448}}
  • Nochmal Redcar and Cleveland: Test der Ausgabe als Pfad: {{#invoke:GetProvince/Test|getProvince|Q1434448|path}}
  • Nochmal Redcar and Cleveland: Test der Ausgabe als Pfad mit übergebenem Trennzeichen: {{#invoke:GetProvince/Test|getProvince|Q1434448|path|, }}
  • Deutschland: Staaten werden geprüft und es wird keine Ermittlung durchgeführt. In der Testphase eine Meldung, später nichts bzw. Fehlerkategorie: {{#invoke:GetProvince/Test|getProvince|Q183}}
  • Brandenburg: Es wird keine Provinz gefunden und die Suche endet bei einem Staat. In der Testphase eine Meldung, später nichts bzw. Fehlerkategorie: {{#invoke:GetProvince/Test|getProvince|Q1208}}
  • Balzers: Bei kleinen Staaten gibt es kein Provinzlevel und der Staat soll angezeigt werden: {{#invoke:GetProvince/Test|getProvince|Q49663}}
  • Berlin: Einige Orte (z. B. Berlin) sind eigene Verwaltungseinheiten auf Provinzlevel. In den Fällen ist es in Ordnung, wenn man auf der Suche beim Staat landet. Wikidata zu befragen und ist ein (P31) auszuwerten und nach Wikidataobjekten zu suchen, die einem Provinzlevel entsprechen ist aufwändig (wie man am beispiel Berlin sieht, was dort alles erfasst ist.). Daher bis auf weiteres der Ansatz, der Vorlage/Funktion einen Parameter mitzugeben, der den Staat als „Provinz“ gültig macht.: {{#invoke:GetProvince/Test|getProvince|Q64|4=ja}}
  • Lelystad: Selbstreferenzen und Schleifen müssen abgefangen werden (Objekt ist inzwischen bereinigt): {{#invoke:GetProvince/Test|getProvince|Q166065}}

Quickbar Wie auch sonst üblich enthalten die Tags data-, class- und title-Attribute mit zusätzlichen Infos über die Wikidata-Suche bzw den Wikidata-Abglich

Redcar and Cleveland
LandEngland
Spremberg ident. Wert
BundeslandBrandenburg
Guben mit abw. Wert
BundeslandSachsen
Berlin
StaatDeutschland
Balzers
StaatLiechtenstein
Nan
ProvinzNan
Nan (eigenes Label)
eigenes LabelNan
Nan (keine Ausgabe bei NEIN)
Nan (Wikidata bei YES)
ProvinzNan
Dugi otok (hat auch alte Hierarchie)
GespanschaftZadar
Hinweise
--[=[ GetProvince 2024-09-29
* 
* Functions: they are described just before their declaration
*
* local nilIf ( value, equalValue ) > internal use
* local coalesce ( value1, value2, value3 ) > internal use
* local getTableLength ( tbl ) > internal use
* local getAdminTerritory ( id ) > interna, use
* local findProvince( id, output, delimiter ) > internal use
*
* getProvinceAndCode ( id ) > used in other modules (Quickbar Ort)
*
* dumpItem ( id )
* getProvince ( id, output, delimiter )
* getProvinceQuickbar ( id, wikiValue ) 
* 
]=]
local GetProvince = {}

-- loading modules

-- its used to check, whether an object is a country
-- no Wikidata request is needed to test it
local yesno     = require( 'Modul:Yesno' )
local cg        = mw.loadData( 'Module:CountryData/Geography' )
local provinces = mw.loadData( 'Modul:GetProvince/Provinces' )

-- categories for data evaluation
local wikidataCat = {
   -- common wikidata categories
   ["equalData"]   = '[[Kategorie:Artikel mit identischer Provinz auf Wikidata]]',
   ["noEqualData"] = '[[Kategorie:Artikel mit abweichender Provinz auf Wikidata]]',
}

-- returns nil, if both values are equal, otherwise the value
-- similar to the SQL function nullif()
local function nilIf ( value, equalValue )

   if ( value == nil ) then
      return nil
   elseif ( tostring ( value ) == tostring ( equalValue ) ) then
      return nil
   else
      return value
   end

end

-- returns the first value that is not nil
-- similar to the SQL function coalesce()
local function coalesce ( value1, value2, value3 )
   return value1 or value2 or value3
end


-- determines the length of a key-value table
-- the # operator does not work here
local function getTableLength(tbl)
  local getN = 0
  for n in pairs(tbl) do 
    getN = getN + 1 
  end
  return getN
end


--[[ 
- getAdminTerritory() -> just for internal use. 
- it delivers the admin territory of an object including its qualifiers
- it requests two properties
-  - P131: admin territory including qualifiers
-     - P10229: next level in hierarchy
-     - P580: Start date/time
-     - P582: End date/time
-  - P300: is normally set on an item of first hierarchy level within a country
-  - P297: fallback, if P300 is not available
--]]
local getAdminTerritory = function ( id )

   -- local variables
   -- ID of the item
   -- Determined, if not provided   
   -- compatibility to existing modules and templates:
   -- some use the keyword "self" for using the own entity-ID
   local localID = nilIf ( nilIf ( id, 'self' ), '' ) or mw.wikibase.getEntityIdForCurrentPage() or ''

   -- initialising returning table
   local wdValues = {}
   wdValues.label = ''
   wdValues.dewikivoyage = ''
   wdValues.P300 = ''
   wdValues.P297 = ''
   wdValues.P31 = {}
   wdValues.adminTerritory = {}

   -- no Wikidata object
   if localID == '' then
      return wdValues, '', ''
   end
   
   -- maintenance categories
   local maintenanceCategory = ''
   
   -- avoiding multiple category outputs when P10229 and P3831 qualifier are used
   local isP10229Used = false
   local isP3831Used = false

   -- label
   wdValues.label = mw.wikibase.getLabel( localID ) or ''

   -- sitelink
   wdValues.dewikivoyage = mw.wikibase.getSitelink( localID, 'dewikivoyage' ) or ''

   -- getting the values
   -- Property: P31
   local wdStatements = mw.wikibase.getBestStatements( localID, 'P31' )

   -- running through the values
   for i, entry in ipairs ( wdStatements ) do

      -- check for WD-item
      if entry.mainsnak.datatype == 'wikibase-item' then
         if entry.mainsnak.datavalue ~= nil then
            wdValues.P31[i] = entry.mainsnak.datavalue.value.id
         end
      end

   end

   -- setting the category
   if #wdStatements > 0 then
      maintenanceCategory = maintenanceCategory .. '[[Kategorie:Seiten, die die Wikidata-Eigenschaft P31 benutzen]]'
   end

   -- Property: P300 (ISO-3166-2)
   local wdStatements = mw.wikibase.getBestStatements( localID, 'P300' )

   if #wdStatements > 0 then
   	
      if wdStatements[1].mainsnak.datatype == 'external-id' then
         wdValues.P300 = ( wdStatements[1].mainsnak.datavalue and wdStatements[1].mainsnak.datavalue.value ) or ''
         maintenanceCategory = maintenanceCategory .. '[[Kategorie:Seiten, die die Wikidata-Eigenschaft P300 benutzen]]'
      end

      maintenanceCategory = maintenanceCategory .. '[[Kategorie:Test 1]]'
      
   else

      -- maintenanceCategory = maintenanceCategory .. '[[Kategorie:Provinz ohne ISO 3166-2 Code auf Wikidata]]'
      maintenanceCategory = maintenanceCategory .. '[[Kategorie:Test 2]]'
   	
      -- Property: P297 (ISO 3166-1 alpha-2)
      wdStatements = mw.wikibase.getBestStatements( localID, 'P297' )

      if #wdStatements > 0 then
         if wdStatements[1].mainsnak.datatype == 'external-id' then
            wdValues.P297 = ( wdStatements[1].mainsnak.datavalue and wdStatements[1].mainsnak.datavalue.value ) or ''
            maintenanceCategory = maintenanceCategory .. '[[Kategorie:Seiten, die die Wikidata-Eigenschaft P297 benutzen]]'
         end
         maintenanceCategory = maintenanceCategory .. '[[Kategorie:Test 3]]'
      else
         --maintenanceCategory = maintenanceCategory .. '[[Kategorie:Provinz ohne ISO 3166-1 Code auf Wikidata]]'
         maintenanceCategory = maintenanceCategory .. '[[Kategorie:Test 4]]'
      end
      
   end

   -- Property: P131
   local wdStatements = mw.wikibase.getBestStatements( localID, 'P131' )

   -- running through the array and store it in a subtable
   local entryID
   local entryP10229
   local entryP580
   local entryP582
   local entryP3831

   -- running through the values
   for i, entry in ipairs ( wdStatements ) do

      -- check for WD-item
      if entry.mainsnak.datatype == 'wikibase-item' then
         
         -- initialising  the items and qualifiers
         entryID = 'X'
         entryP10229 = ''
         entryP580 = ''
         entryP582 = ''
         entryP3831 = ''

         -- getting the admin territory ID
         entryID = entry.mainsnak.datavalue.value.id

         -- read qualifiers
         if entry.qualifiers ~= nil then

            -- read the P10229-Qualifier (next level in hierarchy)
            if entry.qualifiers.P10229 ~= nil then
               if entry.qualifiers.P10229[1].datatype == 'wikibase-item' then
                  entryP10229 = entry.qualifiers.P10229[1].datavalue.value.id
                  isP10229Used = true
               end
            end

            -- read the P3831-Qualifier (object has role)
            if entry.qualifiers.P3831 ~= nil then
               if entry.qualifiers.P3831[1].datatype == 'wikibase-item' then
                  entryP3831 = entry.qualifiers.P3831[1].datavalue.value.id
                  isP3831Used = true
               end
            end

            -- read P580-Qualifiers (Start date/time)
            if entry.qualifiers.P580 ~= nil then
               if entry.qualifiers.P580[1] ~=nil then
                  if entry.qualifiers.P580[1].datavalue ~=nil then
                     if entry.qualifiers.P580[1].datavalue.value.precision == 9 then
                        entryP580 = entry.qualifiers.P580[1].datavalue.value.time:sub( 2, 11 )
                     end
                     if entry.qualifiers.P580[1].datavalue.value.precision == 10 then
                        entryP580 = entry.qualifiers.P580[1].datavalue.value.time:sub( 2, 11 )
                     end
                     if entry.qualifiers.P580[1].datavalue.value.precision == 11 then
                        entryP580 = entry.qualifiers.P580[1].datavalue.value.time:sub( 2, 11 )
                     end
                  end
               end
            end

            -- read P582-Qualifiers (End date/time)
            if entry.qualifiers.P582 ~= nil then
               if entry.qualifiers.P582[1] ~=nil then
                  if entry.qualifiers.P582[1].datavalue ~=nil then
                     if entry.qualifiers.P582[1].datavalue.value.precision == 9 then
                        entryP582 = entry.qualifiers.P582[1].datavalue.value.time:sub( 2, 11 )
                     end
                     if entry.qualifiers.P582[1].datavalue.value.precision == 10 then
                        entryP582 = entry.qualifiers.P582[1].datavalue.value.time:sub( 2, 11 )
                     end
                     if entry.qualifiers.P582[1].datavalue.value.precision == 11 then
                        entryP582 = entry.qualifiers.P582[1].datavalue.value.time:sub( 2, 11 )
                     end
                  end
               end
            end

         end

         -- as in the other modules as well, a given P582 qualifiers mas the value unvalid
         if entryP582 == '' then

	         -- adding to the list
	         wdValues.adminTerritory[entryID] = { 
	            ['label'] = mw.wikibase.getLabel( entryID ) or '',
	            ['dewikivoyage'] = mw.wikibase.getSitelink( entryID, 'dewikivoyage' ) or '',
	            ['P10229'] = entryP10229, 
	            ['P580'] = entryP580, 
	            ['P582'] = entryP582,
	            ['P3831'] = entryP3831
	         }

      	end

      end -- if entry.mainsnak.datatype == 'wikibase-item'

   end -- for i, entry in ipairs ( wdStatements )

   -- adding category
   if #wdStatements > 0 then
      maintenanceCategory = maintenanceCategory .. '[[Kategorie:Seiten, die die Wikidata-Eigenschaft P131 benutzen]]'
   end

   if isP10229Used then
      maintenanceCategory = maintenanceCategory .. '[[Kategorie:Seiten, die die Wikidata-Eigenschaft P10229 benutzen]]'
   end

   if isP3831Used then
      maintenanceCategory = maintenanceCategory .. '[[Kategorie:Seiten, die die Wikidata-Eigenschaft P3831 benutzen]]'
   end

   return wdValues, localID, maintenanceCategory or ''
 
end


--[[ 

   function: findProvince( id, output, delimiter ) 
      
      provides the province of a given destination
      the province is shown as text or Link, if the article exists

      returns three values:
       - province/path
       - maintaining categories
       - label of the province, the name, how ist the type called in that country

      Parameter:
       - id: Wikidata-ID
       - output: what is shown?
         - province: just the province (standard)
         - path: the hierarchy path up to the province
       - delimiter: delimiter in case of path (standard: " > ")
       - countryIsValid: set to "yes" if a country as parovince is acceptable (in case of province free cities)

]]
local findProvince = function ( id, output, delimiter, countryIsValid )

   -- local variables
   -- ID of the item
   -- Determined, if not provided   
   -- compatibility to existing modules and templates:
   -- some use the keyword "self" for using the own entity-ID
   local localID = nilIf ( nilIf ( id, 'self' ), '' ) or mw.wikibase.getEntityIdForCurrentPage() or ''

   -- returning string
   local provinceString = ''
   local provinceLabel = ''
   local provinceCode = ''
   local categoryList = ''

   -- output
   local paramOutput = nilIf ( output, '' ) or 'province'

   -- check the values, and set to standard, if not valid
   local validOutput = { province=true, path=true }
   if validOutput.paramOutput ~= nil then
      paramOutput = 'province'
   end

   -- no delimiter in front of the first entry
   local stringDelimiter = ''

   -- is the item a country? > nothing to do, just returning an empty string
   if cg.countries[id] ~= nil and yesno ( coalesce ( countryIsValid, 'no' ), false ) then
      return '', localID, '', '', ''
   elseif cg.countries[id] ~= nil and not ( yesno ( coalesce ( countryIsValid, 'no' ), false ) ) then
      return '', localID, '[[Kategorie:Wikidata:Provinzsuche endet bei einem Staat]]', '', ''
   end

   -- WD-Values
   local territoryList = {}
   local wikidataID = ''
   local categories = ''
   territoryList, wikidataID, categories = getAdminTerritory ( id )

   -- no admin territory defined
   if wikidataID == '' then
      return '', localID, '[[Kategorie:Artikel ohne Objekt auf Wikidata]]', '', ''
   end

   -- no admin territory defined
   if getTableLength ( territoryList.adminTerritory ) == 0 then
      return '', localID, '[[Kategorie:Artikel ohne Verwaltungseinheit auf Wikidata]]', '', ''
   end

   -- recursive search for the province
   local stopSearch = false

   -- Territory IDs
   local nextID = ''
   local nextButOneID = ''
   local saveID = ''

   -- array of IDs to detect self referencing hierarchies
   local hierarchyIDList = {}

   -- adding the own ID to the list
   hierarchyIDList[localID] = localID

   -- getting the next ID and 
   -- actually obsolete but needed if its used on a province article itself
   for k, v in pairs ( territoryList.adminTerritory ) do
      nextID = k
      if hierarchyIDList[k] ~= nil then
         return '', localID, '[[Kategorie:Wikidata:Provinzsuche bildet eine Schleife]]', '', ''
      end
   end

   repeat 

      -- no admin territory defined
      if getTableLength ( territoryList.adminTerritory ) == 0 then
         provinceString = ''
         categoryList = categoryList .. '[[Kategorie:Wikidata:Provinz konnte nicht ermittelt werden]]'
         break
      end

      -- self referencing hierarchy? then stop
      if hierarchyIDList[nextID] ~= nil then
         categoryList = categoryList .. '[[Kategorie:Wikidata:Provinzsuche bildet eine Schleife]]'
         nextID = ''
         break
      end

      -- is the item a country? Then break
      if cg.countries[nextID] ~= nil then

         if provinces.countriesWithNoProvince[nextID] ~= nil then

            -- small country that does not need a province level
            provinceString = '[[' .. cg.countries[nextID].country .. ']]'
            provinceLabel = 'Staat'

         elseif yesno ( coalesce ( nilIf ( countryIsValid, '' ), 'no' ), false ) then

            -- it's ok to find the country, like in Berlin
            provinceString = '[[' .. cg.countries[nextID].country .. ']]'
            provinceLabel = 'Staat'

         else

            -- search ended at the country level.
            -- maybe you should add an item to Modul:GetProvince/Provinces
            categoryList = categoryList .. '[[Kategorie:Wikidata:Provinzsuche endet bei einem Staat]]'
            provinceString = ''

         end
         
         nextID = ''
         break
      end

      -- show the province, if the path is requestes
      if paramOutput == 'path' then

         if territoryList.dewikivoyage ~= '' then
            provinceString = provinceString .. stringDelimiter .. '[[' .. territoryList.dewikivoyage .. ']]'
         else
            provinceString = provinceString .. stringDelimiter .. territoryList.label
         end

         stringDelimiter = nilIf ( delimiter, '' ) or ' > '

      end

      -- got province? then stop searching
      for i, entry in ipairs ( territoryList.P31 ) do
         if provinces.provinces[entry] ~= nil then
            provinceLabel = provinces.provinces[entry]
            stopSearch = true
         end
      end
 
      -- getting the next ID and 
      -- maybe it was given on last step by providing P10229 Qualifier...
      if nextButOneID ~= '' then

         saveID = nextButOneID

         -- checking, whether here is a new P10229 qualifier
         if territoryList.adminTerritory[nextButOneID].P10229 ~= '' then 
            nextButOneID = territoryList.adminTerritory[nextButOneID].P10229
         else
            nextButOneID = ''
         end

         nextID = saveID

      -- ...or it was not given
      else
         for k, v in pairs ( territoryList.adminTerritory ) do
            nextID = k
            if territoryList.adminTerritory[k].P10229 ~= '' then
               nextButOneID = territoryList.adminTerritory[k].P10229
               break
            end
         end
      end

      -- next round, if necessary
      if not stopSearch then
         territoryList, wikidataID, categories = getAdminTerritory ( nextID )
      end

   until stopSearch

   categoryList = categoryList .. categories

   if ( nextID ~= '' ) and ( paramOutput == 'province' ) then
      if territoryList.dewikivoyage ~= '' then
         provinceString = stringDelimiter .. provinceString .. '[[' .. territoryList.dewikivoyage .. '|' .. mw.ustring.gsub( territoryList.dewikivoyage, '%s%(.*%)', '' ) .. ']]'
      else
         provinceString = stringDelimiter .. provinceString .. territoryList.label
      end
      provinceCode = nilIf ( territoryList.P300, '' ) or nilIf ( territoryList.P297, '' ) or ''
   end

   return provinceString, localID, categoryList, provinceLabel, provinceCode

end

-- Provides the province and its ISO3166-Code of a destination
-- only used in other modules, not in templates
GetProvince.getProvinceAndCode = function( id ) 

   local province = ''
   local wikidataID = ''
   local categories = ''
   local label = ''
   local code = ''

   province, wikidataID, categories, label, code = findProvince( id )

   return province, code

end

--[[ 

   function: dumpItem( id, output, delimiter ) 
      
      just dumps the object, returned by the function getAdminTerritory ( id )

]]
GetProvince.dumpItem = function ( id )

   -- returning string
   local provinceString = ''

   -- WD-Values
   local territoryList = {}
   local wikidataID = ''
   local categories = ''
   territoryList, wikidataID, categories = getAdminTerritory ( id )

   -- debugging info during the development
   provinceString = mw.dumpObject( territoryList ) .. '<br />'

   -- no admin territory defined
   if getTableLength ( territoryList.adminTerritory ) == 0 then
      return provinceString
   end

   return provinceString

end

-- Provides the province or the hierarchy path of a destination
GetProvince.getProvince = function( id, output, delimiter, countryIsValid ) 

   local province = ''
   local wikidataID = ''
   local categories = ''

   province, wikidataID, categories = findProvince( id, output, delimiter, countryIsValid )

   return province .. categories

end

-- Gets the province as wiki markup for quickbars (infoboxes)
GetProvince.getProvinceQuickbar = function( id, wikiValue, wikiLabel, countryIsValid ) 

   
   -- getting the link with the base function above
   local wikidataString
   local wikidataID
   local wikidataCategories
   local wikidataLabel
   local wikidataCode
   wikidataString, wikidataID, wikidataCategories, wikidataLabel, wikidataCode = findProvince ( id, property, nil, countryIsValid )

   -- text to be shown
   local provinceValue = wikidataString
   
   -- removing brackets and alias for later comparison with wikivalue and showing in data attribute
   wikidataString = mw.ustring.gsub ( mw.ustring.gsub ( wikidataString, '[%[%]]', '' ), '|.*', '' )
   
   -- if it is taken from wikidata, this variable provides an additional class for: MediaWiki:Gadget-Wikidata-Content.css
   -- space is needed becaus its simply added to the existing class string
   local wikidataClass = ' voy-wikidata-content'

   -- comparing a possibly given value with Wikidata
   local category = ''
   
   -- is a wiki value defined?
   if ( nilIf ( wikiValue, '' ) ~= nil ) then
      
      -- wikivalues, that can be interpreted as "TRUE" are removed and Wikidata is used
      -- it's used to switch entries on and off in Quickbars
      if yesno ( coalesce ( wikiValue, 'no' ), false ) then
         wikiValue = ''
      else
         provinceValue = wikiValue
         wikidataClass = ''
      end
     
      -- wikivalues, that can be interpreted as "FALSE" suppress the whole row
      if not yesno ( coalesce ( wikiValue, 'yes' ), true ) then
         return wikidataCategories
      end

      wikiValue = mw.ustring.gsub ( wikiValue, '[%[%]]', '' )

      if ( wikidataString ~= '' ) then

         -- are the values equal?
         if wikidataString == wikiValue then
            category = wikidataCat.equalData
         else
            category = wikidataCat.noEqualData
         end

      end

   end

   if provinceValue == '' then
      return category .. wikidataCategories, ''
   end

   -- creating the table row 
   local tr = mw.html.create ( 'tr' )
   
   -- first table cell (heading)
   local trLabel = coalesce ( nilIf ( wikiLabel, '' ), nilIf ( wikidataLabel, '' ), 'Provinz' )
   tr:addClass('voy-qb-item voy-qb-item-province' )
      :tag('th')
      :addClass('voy-qb-item-key')
      :wikitext(trLabel)
   
   -- second table cell (province)
   if category == wikidataCat.equalData then
      tr:tag('td')
            :addClass( 'voy-qb-item-value1 voy-qb-item-value-wikidata-equal' .. wikidataClass )
            :attr('data-wikidata-id',wikidataID)
            :attr('data-wikidata-value',wikidataString)
            :attr('title','Daten identisch - Provinz auf Wikidata: ' .. wikidataString)
            :wikitext( provinceValue )
   elseif category == wikidataCat.noEqualData then
      tr:tag('td')
            :addClass( 'voy-qb-item-value1 voy-qb-item-value-wikidata-noequal' .. wikidataClass )
            :attr('data-wikidata-id',wikidataID)
            :attr('data-wikidata-value',wikidataString)
            :attr('title','Daten unterschiedlich - Provinz auf Wikidata: ' .. wikidataString)
            :wikitext( provinceValue )
   else
      tr:tag('td')
            :addClass( 'voy-qb-item-value1' .. wikidataClass )
            :attr('data-wikidata-id',wikidataID)
            :attr('data-wikidata-value',wikidataString)
            :wikitext( provinceValue )
   end

   -- returning the row
   return tostring ( tr ) .. category .. wikidataCategories, wikidataCode
   
end

-- Providing template access
local p = {}

function p.dumpItem( frame )
   return GetProvince.dumpItem( frame.args[ 1 ] ) or ""
end

function p.getProvince( frame )
   return GetProvince.getProvince( frame.args[ 1 ], frame.args[ 2 ], frame.args[ 3 ], frame.args[ 4 ] ) or ""
end

function p.getProvinceQuickbar( frame )
   return GetProvince.getProvinceQuickbar( frame.args[ 1 ], frame.args[ 2 ], frame.args[ 3 ], frame.args[ 4 ] ) or ""
end


-- for usage in other modules
-- using it the following way:
--
-- local getImage = require( 'Module:GetProvince' )
-- foo = getImage.GetProvince().xxx( id )
function p.GetProvince()
   return GetProvince
end

return p