Module:NationAndOccupation: Difference between revisions
From WWII Archives
wc>Jarekt (handle unspecified gender) |
Paul Sidle (talk | contribs) m (1 revision imported) |
(No difference)
|
Latest revision as of 13:21, 30 May 2024
Documentation for this module may be created at Module:NationAndOccupation/doc
--[[ __ __ _ _ _ _ _ _ _ _ ___ _ _ | \/ | ___ __| |_ _| | ___ _| \ | | __ _| |_(_) ___ _ __ / \ _ __ __| |/ _ \ ___ ___ _ _ _ __ __ _| |_(_) ___ _ __ | |\/| |/ _ \ / _` | | | | |/ _ (_) \| |/ _` | __| |/ _ \| '_ \ / _ \ | '_ \ / _` | | | |/ __/ __| | | | '_ \ / _` | __| |/ _ \| '_ \ | | | | (_) | (_| | |_| | | __/_| |\ | (_| | |_| | (_) | | | |/ ___ \| | | | (_| | |_| | (_| (__| |_| | |_) | (_| | |_| | (_) | | | | |_| |_|\___/ \__,_|\__,_|_|\___(_)_| \_|\__,_|\__|_|\___/|_| |_/_/ \_\_| |_|\__,_|\___/ \___\___|\__,_| .__/ \__,_|\__|_|\___/|_| |_| 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