Module:NationAndOccupation



From Wikimedia Commons, the free media repository



Jump to navigation  Jump to search  

Lua

CodeDiscussionEditHistoryLinksLink count Subpages:DocumentationTestsResultsSandboxLive code All modules

Code for {{NationAndOccupation}}.

Code

--[[  
  __  __           _       _        _   _       _   _                _              _  ___                             _   _             
 |  \/  | ___   __| |_   _| | ___ _| \ | | __ _| |_(_) ___  _ __    / \   _ __   __| |/ _ \  ___ ___ _   _ _ __   __ _| |_(_) ___  _ __  
 | |\/| |/ _ \ / _` | | | | |/ _ (_)  \| |/ _` | __| |/ _ \| '_ \  / _ \ | '_ \ / _` | | | |/ __/ __| | | | '_ \ / _` | __| |/ _ \| '_ \ 
 | |  | | (_) | (_| | |_| | |  __/_| |\  | (_| | |_| | (_) | | | |/ ___ \| | | | (_| | |_| | (_| (__| |_| | |_) | (_| | |_| | (_) | | | |
 |_|  |_|\___/ \__,_|\__,_|_|\___(_)_| \_|\__,_|\__|_|\___/|_| |_/_/   \_\_| |_|\__,_|\___/ \___\___|\__,_| .__/ \__,_|\__|_|\___/|_| |_|

 
This module translates a person’s nationality and profession into user’s preferred language. 
The template takes care for the right word order: {{NationAndOccupation|m|FR|painter|poet}} 
gives “French painter and poet”, if the user’s preferred language is set to English, but 
“pintor y poeta francés”, if the language is set to Spanish. This is especially useful with 
the “Description” field of {{Creator}} templates.

]]

-- =======================================
-- === Dependencies ======================
-- =======================================
local core  = require("Module:core")
local conj  = require('Module:Linguistic').conj
local q2iso = require("Module:NationAndOccupation/nationalityLUT")
local n2iso = require("Module:NationAndOccupation/CountryAdjective2iso")

-- ==================================================
-- === Internal functions ===========================
-- ==================================================

-------------------------------------------------------------------------------
local function getBareLabel(id, userLang) 
-- code equivalent to require("Module:Wikidata label")._getLabel with Wikidata=- option
 local label, link
 -- build language fallback list
 local langList = mw.language.getFallbacksFor(userLang)
 table.insert(langList, 1, userLang)
 for _, lang in ipairs(langList) do  -- loop over language fallback list looking for label in the specific language
  label = mw.wikibase.getLabelByLang(id, lang)
  if label then break end                    -- label found and we are done
 end 
 return label or id
end

------------------------------------------------------------------------------
-- straight union of two arrays (tables)
local function union ( a, b )
    local result = {}
    for _,v in pairs ( a or {} ) do
        table.insert( result, v )
    end
    for _,v in pairs ( b or {} ) do
         table.insert( result, v )
    end
    return result
end

------------------------------------------------------------------------------
-- get female forms of occupation using " female form of label (P2521) " property
local function getFemaleLabel(item, lang)
 local label = {}
 for _, statement in pairs( mw.wikibase.getBestStatements( item, 'P2521' )) do
  local v = statement.mainsnak.datavalue.value
  if v then 
   label[v.language] = v.text
  end
 end
 if label then
  label = core.langSwitch(label,lang)
 end
 if not label then
  label = getBareLabel(item, lang)
 end
 return label
end

--[[
Implementation of Template:NationAndOccupation/default
INPUTS:
* nationality - array of string in the form compatible with Template:Nationality
* occupation  - array of already translated strings
* gender      - single gender string "male" or "female"
* lang        - users language
]]
local function assembleNaO(nationality, occupation, gender, lang)

 local styleLUT = { -- language dependent order
  -- Occupation then nationality order
  ca=10 , es=10, eu=10, fa=10, he=10, it=10, pt=10, ro=10, vi=10,
  -- Occupation then nationality order with first nationality in a special form
  fr=11, 
  -- Nationality then Occupation order
  cs=20 , da=20, el=20, en=20, eo=20, et=20, hu=20, mk=20, ml=20, nl=20, 
  -- Nationality then Occupation order, no space
  zh=21,
  -- Nationality then Occupation order with 1st nationality in a special form and 2nd nationality upper case
  nds=22, de=22 , 
  -- Nationality then Occupation order with 1st nationality in a special form and 2nd nationality lower case
  pl=23, ru=23, sl=23, bg=23}
    -- Use LangSwitch to choose the style based on the language. That way language fallback chain is used
 local style = core.langSwitch(styleLUT, lang) 
  
 -- create nationality string
 gender = gender or 'male'
 local frame = mw.getCurrentFrame()
 local nStr=''
 if nationality and #nationality==1 then --Single nationality case
  nStr = frame:expandTemplate{ title='Nationality', args={nationality[1], gender, lang=lang} }
 elseif nationality and #nationality>1 then                 --Double nationality case
  local N2 = frame:expandTemplate{ title='Nationality', args={nationality[2], gender, lang=lang} }
  if style==11 or style==22 or style==23 then -- nationality in a special form
   gender = 's'
  end
  local N1 = frame:expandTemplate{ title='Nationality', args={nationality[1], gender, lang=lang} }
  if style==23 then
   N2 = mw.ustring.lower(N2)
  end
  nStr = N1 .. '-' .. N2
 end
 
 -- Create final string
 if occupation then
  local oStr = conj(occupation, lang, 'and')
  if style<20 then -- Type 1: Occupation then nationality order
   return oStr .. ' ' .. nStr
  elseif style==21 then -- Type 1: Nationality then Occupation order, no space
   return nStr .. oStr
  else             -- Type 2: Nationality then Occupation order
   return nStr .. ' ' .. oStr
  end
 else
  return nStr
 end
end

--[[
Implementation of Template:NationAndOccupation
INPUTS:
* entity - wikidata entity 
* lang   - users language
OUTPUTS:
* data   - data structure with data extracted from Wikidata, including fields:
 * nationality   - array of string in the form compatible with Template:Nationality
 * occupation    - array of already translated occupation strings
 * occupationEN  - array of occupation strings in english
 * gender        - single gender string "male" or "female"
]]
local function harvest_wikidata(entity, lang)
 local occupation, occupationEN, nationality, gender, data = {}, {}, {}, {}, {}
 
 -- if wikidata q-code is provided than look up few properties
 if entity then
  -- harvest  properties from wikidata
  local property = {P21='gender', P27='country', P106='occupation', P172='ethnicity'}
  for prop, field in pairs( property ) do
   if entity.claims and entity.claims[prop] then -- if we have wikidata item and item has the property
    -- capture multiple "best" Wikidata value
    data[field] = core.parseStatements(entity:getBestStatements( prop ), nil)
   end
  end
 end
 
 -- Look up gender
 if data.gender then 
  local LUT = { Q6581097='male', Q2449503='male', Q6581072='female', Q1052281='female' }
  gender = LUT[data.gender[1]]
 end
 if gender~='male' and gender~='female' then
  gender = 'male'
 end
 
 -- Look up occupation
 local occ
 for i, oItem in ipairs(data.occupation or {}) do
  if i>6 then
   break -- only 6 occupations are allowed
  end
  local occEN = mw.wikibase.getLabelByLang(oItem, 'en')
  if gender == 'female' then -- get localized (translated) occupation labels in female form
   occ = getFemaleLabel(oItem, lang) 
  elseif lang=='en' then     -- get English occupation labels in male form
   occ = occEN
  else                       -- get localized (translated) occupation labels in male form
   occ = getBareLabel(oItem, lang)
  end
  table.insert(occupation  , occ) 
  table.insert(occupationEN, occEN)
 end
 
 -- Look up nationality
 if data.country or data.ethnicity then -- from wikidata
  -- process P27/country and P172/ethnicity
  local nTable = {} -- table of unique nationality iso codes stored as keys
  for _, v in ipairs( union(data.country, data.ethnicity) ) do
   for iso in mw.text.gsplit( q2iso[v] or '', '/', true ) do
    nTable[ iso ] = 1
   end
  end
  for nat, _ in pairs(nTable) do
   table.insert(nationality, nat)
  end
 end
 data = {nationality=nationality, occupation=occupation, gender=gender, occupationEN=occupationEN}
 return data
end

-- ==================================================
-- === External functions ===========================
-- ==================================================
local p = {}

-- ===========================================================================
-- === Version of the function to be called from other LUA codes
-- ===========================================================================

--[[
Implementation of Template:NationAndOccupation
INPUTS:
* args.nationality - '/' separated string with substrings in the form compatible 
                     with Template:Nationality
* args.occupation  - '/' separated string with substrings with english names of 
                     occupations compatible with Template:Occupations
* args.gender      - single gender string "male" or "female"
* args.wikidata    - wikidata q-code
* args.lang        - users language
OUTPUTS:
* OutStr - string with transpaced phrase like "english writer"
* args   - data structure with processed inputs
* data   - data structure with data extracted from Wikidata
]]
function p._NationAndOccupation(args0)
 local occupation, nationality, entity, occupationEN
 
 -- if wikidata q-code is provided than look up few properties
 local q = args0.wikidata
 if q and type(q)=='string' and string.sub(q,1,1)=="Q"  then --  
  entity = mw.wikibase.getEntity(q)
 elseif q then
  entity = q
 end
 local data   = harvest_wikidata(entity, args0.lang)
 local gender = args0.gender or data.gender
 
 -- Look up occupation
 if args0.occupation then -- from input arguments
  local frame = mw.getCurrentFrame()
  local occArray = mw.text.split(args0.occupation, '/')
  occupation = {}
  for i = 1,6 do 
   if occArray[i] and occArray[i]~='' then 
    local args={occArray[i], gender, lang=args0.lang}
    table.insert(occupation, frame:expandTemplate{ title='Occupation', args=args })
   end
  end
  if #occupation==0 then
   occupation = nil
  end
 end
 
 -- Look up nationality
 if args0.nationality then -- from input arguments
  nationality = mw.text.split(args0.nationality, '/')
  for i = 1,2 do -- if nationality is a word than see if we can find iso code
   local N = string.lower(nationality[i] or '')
   if #N>2 and n2iso[N] then 
    nationality[i] = n2iso[N]
   end
  end
  if #nationality==0 then
   nationality = nil
  end
 end
 local outStr = assembleNaO(nationality or data.nationality, occupation or data.occupation, gender, args0.lang)
 local args = {nationality=nationality, occupation=occupation, gender=args0.gender, occupationEN=occupationEN}
    --outStr = outStr .. '\n' .. mw.text.jsonEncode(data) .. '\n' .. mw.text.jsonEncode(args)
 return outStr, args, data
end

-- ===========================================================================
-- === Version of the functions to be called from template namespace
-- ===========================================================================

--[[
NationAndOccupation
 
This function is the core part of the NationAndOccupation template. 
 
Usage:
{{#invoke:}}
 
 Parameters:
  *nationality - '/' separated string with substrings in the form compatible 
                     with Template:Nationality
  * occupation  - '/' separated string with substrings with english names of 
                     occupations compatible with Template:Occupations
  * gender      - single gender string "male" or "female"
  * wikidata    - wikidata q-code
  * lang        - users language
 Error Handling:

]]
function p.NationAndOccupation(frame)
 local args0 = core.getArgs(frame)
 local outStr, args, data = p._NationAndOccupation(args0)
 return outStr
end

return p

Retrieved from "https://commons.wikimedia.org/w/index.php?title=Module:NationAndOccupation&oldid=565243508"

Categories: 
Modules for general use
Modules subject to page protection
 


Navigation menu


Personal tools  




English
Not logged in
Talk
Contributions
Create account
Log in
 


Namespaces  




Module
Discussion