<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en-GB">
	<id>https://safernicotine.wiki/mediawiki/index.php?action=history&amp;feed=atom&amp;title=Module%3ANationAndOccupation</id>
	<title>Module:NationAndOccupation - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://safernicotine.wiki/mediawiki/index.php?action=history&amp;feed=atom&amp;title=Module%3ANationAndOccupation"/>
	<link rel="alternate" type="text/html" href="https://safernicotine.wiki/mediawiki/index.php?title=Module:NationAndOccupation&amp;action=history"/>
	<updated>2026-04-09T21:30:01Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.44.0</generator>
	<entry>
		<id>https://safernicotine.wiki/mediawiki/index.php?title=Module:NationAndOccupation&amp;diff=12052&amp;oldid=prev</id>
		<title>Richardpruen: 1 revision imported</title>
		<link rel="alternate" type="text/html" href="https://safernicotine.wiki/mediawiki/index.php?title=Module:NationAndOccupation&amp;diff=12052&amp;oldid=prev"/>
		<updated>2021-11-23T12:11:21Z</updated>

		<summary type="html">&lt;p&gt;1 revision imported&lt;/p&gt;
&lt;table style=&quot;background-color: #fff; color: #202122;&quot; data-mw=&quot;interface&quot;&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;en-GB&quot;&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;← Older revision&lt;/td&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;Revision as of 13:11, 23 November 2021&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;4&quot; class=&quot;diff-notice&quot; lang=&quot;en-GB&quot;&gt;&lt;div class=&quot;mw-diff-empty&quot;&gt;(No difference)&lt;/div&gt;
&lt;/td&gt;&lt;/tr&gt;
&lt;!-- diff cache key uk_vapewiki:diff:1.41:old-12051:rev-12052 --&gt;
&lt;/table&gt;</summary>
		<author><name>Richardpruen</name></author>
	</entry>
	<entry>
		<id>https://safernicotine.wiki/mediawiki/index.php?title=Module:NationAndOccupation&amp;diff=12051&amp;oldid=prev</id>
		<title>Wikimedia+Commons&gt;Jarekt: handle unspecified gender</title>
		<link rel="alternate" type="text/html" href="https://safernicotine.wiki/mediawiki/index.php?title=Module:NationAndOccupation&amp;diff=12051&amp;oldid=prev"/>
		<updated>2021-05-27T12:59:42Z</updated>

		<summary type="html">&lt;p&gt;handle unspecified gender&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;--[[  &lt;br /&gt;
  __  __           _       _        _   _       _   _                _              _  ___                             _   _             &lt;br /&gt;
 |  \/  | ___   __| |_   _| | ___ _| \ | | __ _| |_(_) ___  _ __    / \   _ __   __| |/ _ \  ___ ___ _   _ _ __   __ _| |_(_) ___  _ __  &lt;br /&gt;
 | |\/| |/ _ \ / _` | | | | |/ _ (_)  \| |/ _` | __| |/ _ \| &amp;#039;_ \  / _ \ | &amp;#039;_ \ / _` | | | |/ __/ __| | | | &amp;#039;_ \ / _` | __| |/ _ \| &amp;#039;_ \ &lt;br /&gt;
 | |  | | (_) | (_| | |_| | |  __/_| |\  | (_| | |_| | (_) | | | |/ ___ \| | | | (_| | |_| | (_| (__| |_| | |_) | (_| | |_| | (_) | | | |&lt;br /&gt;
 |_|  |_|\___/ \__,_|\__,_|_|\___(_)_| \_|\__,_|\__|_|\___/|_| |_/_/   \_\_| |_|\__,_|\___/ \___\___|\__,_| .__/ \__,_|\__|_|\___/|_| |_|&lt;br /&gt;
&lt;br /&gt;
 &lt;br /&gt;
This module translates a person’s nationality and profession into user’s preferred language. &lt;br /&gt;
The template takes care for the right word order: {{NationAndOccupation|m|FR|painter|poet}} &lt;br /&gt;
gives “French painter and poet”, if the user’s preferred language is set to English, but &lt;br /&gt;
“pintor y poeta francés”, if the language is set to Spanish. This is especially useful with &lt;br /&gt;
the “Description” field of {{Creator}} templates.&lt;br /&gt;
&lt;br /&gt;
]]&lt;br /&gt;
&lt;br /&gt;
-- =======================================&lt;br /&gt;
-- === Dependencies ======================&lt;br /&gt;
-- =======================================&lt;br /&gt;
local core  = require(&amp;quot;Module:core&amp;quot;)&lt;br /&gt;
local conj  = require(&amp;#039;Module:Linguistic&amp;#039;).conj&lt;br /&gt;
local q2iso = require(&amp;quot;Module:NationAndOccupation/nationalityLUT&amp;quot;)&lt;br /&gt;
local n2iso = require(&amp;quot;Module:NationAndOccupation/CountryAdjective2iso&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
-- ==================================================&lt;br /&gt;
-- === Internal functions ===========================&lt;br /&gt;
-- ==================================================&lt;br /&gt;
&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
local function getBareLabel(id, userLang) &lt;br /&gt;
-- code equivalent to require(&amp;quot;Module:Wikidata label&amp;quot;)._getLabel with Wikidata=- option&lt;br /&gt;
	local label, link&lt;br /&gt;
	-- build language fallback list&lt;br /&gt;
	local langList = mw.language.getFallbacksFor(userLang)&lt;br /&gt;
	table.insert(langList, 1, userLang)&lt;br /&gt;
	for _, lang in ipairs(langList) do  -- loop over language fallback list looking for label in the specific language&lt;br /&gt;
		label = mw.wikibase.getLabelByLang(id, lang)&lt;br /&gt;
		if label then break end                    -- label found and we are done&lt;br /&gt;
	end	&lt;br /&gt;
	return label or id&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
------------------------------------------------------------------------------&lt;br /&gt;
-- straight union of two arrays (tables)&lt;br /&gt;
local function union ( a, b )&lt;br /&gt;
    local result = {}&lt;br /&gt;
    for _,v in pairs ( a or {} ) do&lt;br /&gt;
        table.insert( result, v )&lt;br /&gt;
    end&lt;br /&gt;
    for _,v in pairs ( b or {} ) do&lt;br /&gt;
         table.insert( result, v )&lt;br /&gt;
    end&lt;br /&gt;
    return result&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
------------------------------------------------------------------------------&lt;br /&gt;
-- get female forms of occupation using &amp;quot; female form of label (P2521) &amp;quot; property&lt;br /&gt;
local function getFemaleLabel(item, lang)&lt;br /&gt;
	local label = {}&lt;br /&gt;
	for _, statement in pairs( mw.wikibase.getBestStatements( item, &amp;#039;P2521&amp;#039; )) do&lt;br /&gt;
		local v = statement.mainsnak.datavalue.value&lt;br /&gt;
		if v then &lt;br /&gt;
			label[v.language] = v.text&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	if label then&lt;br /&gt;
		label = core.langSwitch(label,lang)&lt;br /&gt;
	end&lt;br /&gt;
	if not label then&lt;br /&gt;
		label = getBareLabel(item, lang)&lt;br /&gt;
	end&lt;br /&gt;
	return label&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[&lt;br /&gt;
Implementation of Template:NationAndOccupation/default&lt;br /&gt;
INPUTS:&lt;br /&gt;
* nationality - array of string in the form compatible with Template:Nationality&lt;br /&gt;
* occupation  - array of already translated strings&lt;br /&gt;
* gender      - single gender string &amp;quot;male&amp;quot; or &amp;quot;female&amp;quot;&lt;br /&gt;
* lang        - users language&lt;br /&gt;
]]&lt;br /&gt;
local function assembleNaO(nationality, occupation, gender, lang)&lt;br /&gt;
&lt;br /&gt;
	local styleLUT = { -- language dependent order&lt;br /&gt;
		-- Occupation then nationality order&lt;br /&gt;
		ca=10 , es=10, eu=10, fa=10, he=10, it=10, pt=10, ro=10, vi=10,&lt;br /&gt;
		-- Occupation then nationality order with first nationality in a special form&lt;br /&gt;
		fr=11, &lt;br /&gt;
		-- Nationality then Occupation order&lt;br /&gt;
		cs=20 , da=20, el=20, en=20, eo=20, et=20, hu=20, mk=20, ml=20, nl=20, &lt;br /&gt;
		-- Nationality then Occupation order, no space&lt;br /&gt;
		zh=21,&lt;br /&gt;
		-- Nationality then Occupation order with 1st nationality in a special form and 2nd nationality upper case&lt;br /&gt;
		nds=22, de=22 , &lt;br /&gt;
		-- Nationality then Occupation order with 1st nationality in a special form and 2nd nationality lower case&lt;br /&gt;
		pl=23, ru=23, sl=23, bg=23}&lt;br /&gt;
    -- Use LangSwitch to choose the style based on the language. That way language fallback chain is used&lt;br /&gt;
	local style = core.langSwitch(styleLUT, lang) &lt;br /&gt;
	 &lt;br /&gt;
	-- create nationality string&lt;br /&gt;
	gender = gender or &amp;#039;male&amp;#039;&lt;br /&gt;
	local frame = mw.getCurrentFrame()&lt;br /&gt;
	local nStr=&amp;#039;&amp;#039;&lt;br /&gt;
	if nationality and #nationality==1 then --Single nationality case&lt;br /&gt;
		nStr = frame:expandTemplate{ title=&amp;#039;Nationality&amp;#039;, args={nationality[1], gender, lang=lang} }&lt;br /&gt;
	elseif nationality and #nationality&amp;gt;1 then                 --Double nationality case&lt;br /&gt;
		local N2 = frame:expandTemplate{ title=&amp;#039;Nationality&amp;#039;, args={nationality[2], gender, lang=lang} }&lt;br /&gt;
		if style==11 or style==22 or style==23 then -- nationality in a special form&lt;br /&gt;
			gender = &amp;#039;s&amp;#039;&lt;br /&gt;
		end&lt;br /&gt;
		local N1 = frame:expandTemplate{ title=&amp;#039;Nationality&amp;#039;, args={nationality[1], gender, lang=lang} }&lt;br /&gt;
		if style==23 then&lt;br /&gt;
			N2 = mw.ustring.lower(N2)&lt;br /&gt;
		end&lt;br /&gt;
		nStr = N1 .. &amp;#039;-&amp;#039; .. N2&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	-- Create final string&lt;br /&gt;
	if occupation then&lt;br /&gt;
		local oStr = conj(occupation, lang, &amp;#039;and&amp;#039;)&lt;br /&gt;
		if style&amp;lt;20 then -- Type 1: Occupation then nationality order&lt;br /&gt;
			return oStr .. &amp;#039; &amp;#039; .. nStr&lt;br /&gt;
		elseif style==21 then -- Type 1: Nationality then Occupation order, no space&lt;br /&gt;
			return nStr .. oStr&lt;br /&gt;
		else             -- Type 2: Nationality then Occupation order&lt;br /&gt;
			return nStr .. &amp;#039; &amp;#039; .. oStr&lt;br /&gt;
		end&lt;br /&gt;
	else&lt;br /&gt;
		return nStr&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[&lt;br /&gt;
Implementation of Template:NationAndOccupation&lt;br /&gt;
INPUTS:&lt;br /&gt;
* entity - wikidata entity &lt;br /&gt;
* lang   - users language&lt;br /&gt;
OUTPUTS:&lt;br /&gt;
* data   - data structure with data extracted from Wikidata, including fields:&lt;br /&gt;
	* nationality   - array of string in the form compatible with Template:Nationality&lt;br /&gt;
	* occupation    - array of already translated occupation strings&lt;br /&gt;
	* occupationEN  - array of occupation strings in english&lt;br /&gt;
	* gender        - single gender string &amp;quot;male&amp;quot; or &amp;quot;female&amp;quot;&lt;br /&gt;
]]&lt;br /&gt;
local function harvest_wikidata(entity, lang)&lt;br /&gt;
	local occupation, occupationEN, nationality, gender, data = {}, {}, {}, {}, {}&lt;br /&gt;
	&lt;br /&gt;
	-- if wikidata q-code is provided than look up few properties&lt;br /&gt;
	if entity then&lt;br /&gt;
		-- harvest  properties from wikidata&lt;br /&gt;
		local property = {P21=&amp;#039;gender&amp;#039;, P27=&amp;#039;country&amp;#039;, P106=&amp;#039;occupation&amp;#039;, P172=&amp;#039;ethnicity&amp;#039;}&lt;br /&gt;
		for prop, field in pairs( property ) do&lt;br /&gt;
			if entity.claims and entity.claims[prop] then -- if we have wikidata item and item has the property&lt;br /&gt;
				-- capture multiple &amp;quot;best&amp;quot; Wikidata value&lt;br /&gt;
				data[field] = core.parseStatements(entity:getBestStatements( prop ), nil)&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	-- Look up gender&lt;br /&gt;
	if data.gender then	&lt;br /&gt;
		local LUT = { Q6581097=&amp;#039;male&amp;#039;, Q2449503=&amp;#039;male&amp;#039;, Q6581072=&amp;#039;female&amp;#039;, Q1052281=&amp;#039;female&amp;#039; }&lt;br /&gt;
		gender = LUT[data.gender[1]]&lt;br /&gt;
	end&lt;br /&gt;
	if gender~=&amp;#039;male&amp;#039; and gender~=&amp;#039;female&amp;#039; then&lt;br /&gt;
		gender = &amp;#039;male&amp;#039;&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	-- Look up occupation&lt;br /&gt;
	local occ&lt;br /&gt;
	for i, oItem in ipairs(data.occupation or {}) do&lt;br /&gt;
		if i&amp;gt;6 then&lt;br /&gt;
			break -- only 6 occupations are allowed&lt;br /&gt;
		end&lt;br /&gt;
		local occEN = mw.wikibase.getLabelByLang(oItem, &amp;#039;en&amp;#039;)&lt;br /&gt;
		if gender == &amp;#039;female&amp;#039; then -- get localized (translated) occupation labels in female form&lt;br /&gt;
			occ = getFemaleLabel(oItem, lang) &lt;br /&gt;
		elseif lang==&amp;#039;en&amp;#039; then     -- get English occupation labels in male form&lt;br /&gt;
			occ = occEN&lt;br /&gt;
		else                       -- get localized (translated) occupation labels in male form&lt;br /&gt;
			occ = getBareLabel(oItem, lang)&lt;br /&gt;
		end&lt;br /&gt;
		table.insert(occupation  , occ) &lt;br /&gt;
		table.insert(occupationEN, occEN)&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	-- Look up nationality&lt;br /&gt;
	if data.country or data.ethnicity then -- from wikidata&lt;br /&gt;
		-- process P27/country and P172/ethnicity&lt;br /&gt;
		local nTable = {} -- table of unique nationality iso codes stored as keys&lt;br /&gt;
		for _, v in ipairs( union(data.country, data.ethnicity) ) do&lt;br /&gt;
			for iso in mw.text.gsplit( q2iso[v] or &amp;#039;&amp;#039;, &amp;#039;/&amp;#039;, true ) do&lt;br /&gt;
				nTable[ iso ] = 1&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
		for nat, _ in pairs(nTable) do&lt;br /&gt;
			table.insert(nationality, nat)&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	data = {nationality=nationality, occupation=occupation, gender=gender, occupationEN=occupationEN}&lt;br /&gt;
	return data&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- ==================================================&lt;br /&gt;
-- === External functions ===========================&lt;br /&gt;
-- ==================================================&lt;br /&gt;
local p = {}&lt;br /&gt;
&lt;br /&gt;
-- ===========================================================================&lt;br /&gt;
-- === Version of the function to be called from other LUA codes&lt;br /&gt;
-- ===========================================================================&lt;br /&gt;
&lt;br /&gt;
--[[&lt;br /&gt;
Implementation of Template:NationAndOccupation&lt;br /&gt;
INPUTS:&lt;br /&gt;
* args.nationality - &amp;#039;/&amp;#039; separated string with substrings in the form compatible &lt;br /&gt;
                     with Template:Nationality&lt;br /&gt;
* args.occupation  - &amp;#039;/&amp;#039; separated string with substrings with english names of &lt;br /&gt;
                     occupations compatible with Template:Occupations&lt;br /&gt;
* args.gender      - single gender string &amp;quot;male&amp;quot; or &amp;quot;female&amp;quot;&lt;br /&gt;
* args.wikidata    - wikidata q-code&lt;br /&gt;
* args.lang        - users language&lt;br /&gt;
OUTPUTS:&lt;br /&gt;
* OutStr - string with transpaced phrase like &amp;quot;english writer&amp;quot;&lt;br /&gt;
* args   - data structure with processed inputs&lt;br /&gt;
* data   - data structure with data extracted from Wikidata&lt;br /&gt;
]]&lt;br /&gt;
function p._NationAndOccupation(args0)&lt;br /&gt;
	local occupation, nationality, entity, occupationEN&lt;br /&gt;
	&lt;br /&gt;
	-- if wikidata q-code is provided than look up few properties&lt;br /&gt;
	local q = args0.wikidata&lt;br /&gt;
	if q and type(q)==&amp;#039;string&amp;#039; and string.sub(q,1,1)==&amp;quot;Q&amp;quot;  then --  &lt;br /&gt;
		entity = mw.wikibase.getEntity(q)&lt;br /&gt;
	elseif q then&lt;br /&gt;
		entity = q&lt;br /&gt;
	end&lt;br /&gt;
	local data   = harvest_wikidata(entity, args0.lang)&lt;br /&gt;
	local gender = args0.gender or data.gender&lt;br /&gt;
	&lt;br /&gt;
	-- Look up occupation&lt;br /&gt;
	if args0.occupation then -- from input arguments&lt;br /&gt;
		local frame = mw.getCurrentFrame()&lt;br /&gt;
		local occArray = mw.text.split(args0.occupation, &amp;#039;/&amp;#039;)&lt;br /&gt;
		occupation = {}&lt;br /&gt;
		for i = 1,6 do &lt;br /&gt;
			if occArray[i] and occArray[i]~=&amp;#039;&amp;#039; then &lt;br /&gt;
				local args={occArray[i], gender, lang=args0.lang}&lt;br /&gt;
				table.insert(occupation, frame:expandTemplate{ title=&amp;#039;Occupation&amp;#039;, args=args })&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
		if #occupation==0 then&lt;br /&gt;
			occupation = nil&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	-- Look up nationality&lt;br /&gt;
	if args0.nationality then -- from input arguments&lt;br /&gt;
		nationality = mw.text.split(args0.nationality, &amp;#039;/&amp;#039;)&lt;br /&gt;
		for i = 1,2 do -- if nationality is a word than see if we can find iso code&lt;br /&gt;
			local N = string.lower(nationality[i] or &amp;#039;&amp;#039;)&lt;br /&gt;
			if #N&amp;gt;2 and n2iso[N] then &lt;br /&gt;
				nationality[i] = n2iso[N]&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
		if #nationality==0 then&lt;br /&gt;
			nationality = nil&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	local outStr = assembleNaO(nationality or data.nationality, occupation or data.occupation, gender, args0.lang)&lt;br /&gt;
	local args = {nationality=nationality, occupation=occupation, gender=args0.gender, occupationEN=occupationEN}&lt;br /&gt;
    --outStr = outStr .. &amp;#039;\n&amp;#039; .. mw.text.jsonEncode(data) .. &amp;#039;\n&amp;#039; .. mw.text.jsonEncode(args)&lt;br /&gt;
	return outStr, args, data&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- ===========================================================================&lt;br /&gt;
-- === Version of the functions to be called from template namespace&lt;br /&gt;
-- ===========================================================================&lt;br /&gt;
&lt;br /&gt;
--[[&lt;br /&gt;
NationAndOccupation&lt;br /&gt;
 &lt;br /&gt;
This function is the core part of the NationAndOccupation template. &lt;br /&gt;
 &lt;br /&gt;
Usage:&lt;br /&gt;
{{#invoke:}}&lt;br /&gt;
 &lt;br /&gt;
 Parameters:&lt;br /&gt;
  *nationality - &amp;#039;/&amp;#039; separated string with substrings in the form compatible &lt;br /&gt;
                     with Template:Nationality&lt;br /&gt;
  * occupation  - &amp;#039;/&amp;#039; separated string with substrings with english names of &lt;br /&gt;
                     occupations compatible with Template:Occupations&lt;br /&gt;
  * gender      - single gender string &amp;quot;male&amp;quot; or &amp;quot;female&amp;quot;&lt;br /&gt;
  * wikidata    - wikidata q-code&lt;br /&gt;
  * lang        - users language&lt;br /&gt;
 Error Handling:&lt;br /&gt;
&lt;br /&gt;
]]&lt;br /&gt;
function p.NationAndOccupation(frame)&lt;br /&gt;
	local args0 = core.getArgs(frame)&lt;br /&gt;
	local outStr, args, data = p._NationAndOccupation(args0)&lt;br /&gt;
	return outStr&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
return p&lt;/div&gt;</summary>
		<author><name>Wikimedia+Commons&gt;Jarekt</name></author>
	</entry>
</feed>