Module:NationAndOccupation

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

This module translates a person’s nationality and profession into user’s preferred language. The template takes care for the right word order: 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 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: local function assembleNaO(nationality, occupation, gender, lang)
 * 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 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: OUTPUTS:	* 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
 * entity - wikidata entity
 * lang  - users language
 * data  - data structure with data extracted from Wikidata, including fields:

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

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

-- Implementation of Template:NationAndOccupation INPUTS:                    with Template:Nationality                     occupations compatible with Template:Occupations OUTPUTS: 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
 * args.nationality - '/' separated string with substrings in the form compatible
 * args.occupation - '/' separated string with substrings with english names of
 * args.gender     - single gender string "male" or "female"
 * args.wikidata   - wikidata q-code
 * args.lang       - users language
 * OutStr - string with transpaced phrase like "english writer"
 * args  - data structure with processed inputs
 * data  - data structure with data extracted from Wikidata

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

--[[ NationAndOccupation This function is the core part of the NationAndOccupation template. Usage:

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