Wikisource dawikisource https://da.wikisource.org/wiki/Forside MediaWiki 1.47.0-wmf.23 first-letter Media Speciel Diskussion Bruger Brugerdiskussion Wikisource Wikisource diskussion Fil Fildiskussion MediaWiki MediaWiki diskussion Skabelon Skabelondiskussion Hjælp Hjælp diskussion Kategori Kategoridiskussion Forfatter Forfatterdiskussion Side Sidediskussion Indeks Indeksdiskussion TimedText TimedText talk Modul Moduldiskussion Event Event talk Skabelon:Forfatter 10 2322 482569 481741 2026-10-11T13:58:14Z Johshh 9757 Erstatter sidens indhold med "{{#invoke:Author|author}}<noinclude>{{documentation}}</noinclude>" 482569 wikitext text/x-wiki {{#invoke:Author|author}}<noinclude>{{documentation}}</noinclude> dwwmzoe0l1pypbqpgzqnd892jcf6j9g Side:Danske digtere 1904.djvu/150 104 31696 482582 71943 2026-10-11T16:36:48Z MGA73 457 /* Validated */ 482582 proofread-page text/x-wiki <noinclude><pagequality level="4" user="MGA73" />{{c|JOHANNES JØRGENSEN.}} {{streg}}</noinclude>indlæg, hvor han ofte skriger råere op i selvgod nyomvendthed. Det er en anselig virksomhed, nykatolicismens litterære apostel i Danmark i et decennium har udfoldet; han har skjænket sit i kjætteri og hedendom vildfarende land en lang række skrifter af mere eller mindre agitatorisk art: „Rejsebogen“ (1895), „Beuron“ (1897), „Den yderste dag“ (1897), „Lignelser“ (1898), „Helvedfiender“ (1898), „Omvendelse“ (1899), „Livsløgn og livssandhed“ (1899), „Vor frue af Danmark“ (1900), „En apostel“ (1900), „Romerske helgenbilleder“ (1902), „Den hellige ild“ (1902), „Pilgrimsbogen“ (1903). Samlede virker disse arbeider yderst monotont; man kjender i virkeligheden dem alle, naar man kjender etpar. „Reisebogen“ hører til de mere interessante. Her ligger både Johannes Jørgensens spinkle styrke og hans store svagheder åbent i dagen. Han taler om middelalderens kunst og den moderne: „Et selskab turister kom op paa Køllner doms tårne for at bese arbeiderne, der da endnu var i gang. Helt op steg de, højere end turister pleier. Og dér, helt oppe på spiret, traf de en gammel skægget arbeider, som sad og hamrede og meislede på det sirligste. Smaa blomster og snørkler huggede han, og dækkede stenens hele flade med skønne ornamenter. En af herrerne spurgte forundret den gamle: — Men hvorfor sidder De dog og gør Dem al den umage? Der er jo ingen, som kan se det og beundre det nede fra. Den gamle så op fra sin meisel og sagde kort: „Ich thu’s für den lieben Gott. ''Der'' sieht’s.“ — Denne mand — han være apokryf eller<noinclude><references/> {{c|— 138 —}}</noinclude> ch90mjuuj7xeoth1q3183wexlqgqizk Side:Danske digtere 1904.djvu/151 104 31697 482583 71949 2026-10-11T16:41:32Z MGA73 457 /* Validated */ 482583 proofread-page text/x-wiki <noinclude><pagequality level="4" user="MGA73" />{{c|JOHANNES JØRGENSEN.}} {{streg}}</noinclude>ægte — svarede i middelalderens ånd. ''Derfor'' arbeidede middelalderen — for at Gud skulde se det. Den altseende var hine mestres publikum. Deraf rinder hin utømmelige rigdom, hvorom enhver af gothikens kirker vidner. Alt blev udarbeidet med lige omhu og kærlighed; ingen del blev holdt for ringere end en anden, thi alt var lige nær ved Guds øie. For den moderne kunstner, hvis publikum er menneskeligt, gælder et andet princip. Hans kreds af velyndere er ubestandig — det gælder derfor at fængsle den. Den er vægelsindet — det gælder derfor om at følge dens smag. Den er (heldigvis!) ikke altid så dybtseende — derfor gælder det at blænde den. Og således opstår en kunst, hvis grundsætning er „at behage publikum,“ „at træffe den herskende smag,“ og hvis frembringelser vidner sørgeligt om, hvad det herskende publikum finder velsmagende.“ Det er vakkert, hvad Johannes Jørgensen sier om middelalderens kunst. Og hans billeder fra Sydtysklands gamle byer har ofte en fin og ægte stemning. Glæden ved malerisk og arkitektonisk skjønhed er vel den, der bunder dybest i Jørgensens sind. Men hvorofte — desværre — føler man, at just den karakteristik, Jørgensen i de citerede ord gir af moderne kunst, „hvis publikum er menneskeligt (!)“, passer på hans egne mariafarinaduftende helvedsnovelletter. Hvor ynkelig tillært lyder ikke hans forklaring og forsvar, når han taler om afladen — hvor uappetitlig virker ikke hans begeistring for Heinrich Suso, dette omvandrende lusebeite — hvor tam og klangløs<noinclude><references/> {{c|— 139 —}}</noinclude> ezckjmef9887lea4ymsh55rv44rrdvf Side:Danske digtere 1904.djvu/152 104 31698 482584 71945 2026-10-11T17:41:14Z MGA73 457 /* Validated */ 482584 proofread-page text/x-wiki <noinclude><pagequality level="4" user="MGA73" />{{c|JOHANNES JØRGENSEN.}} {{streg}}</noinclude>er ikke hans beskrivelse af munkenes lod: de nyder dog, alt iberegnet, etslags borgerligt velvære! Stakkars Jørgensen — han stod engang høit i tårnet, og han er, efter sin egen læres lov, blit hårdeligen fornedret. Én trøst har han: det kan ikke betviles, at hans bøger har fundet stor udbredelse både i Danmark og i Norge. En andagtsbog er en andagtsbog. „Publikum er heldigvis ikke dybtseende.“ Jeg har fundet „Livsløgn og livssandhed“ som underholdning for stølsjenten oppe i en afdal i Søndfjord. — „Den hellige ild“ synes mig allerbedst at betegne den triste tilbagegang hos Jørgensen. Giovanni Colombinis historie skulde kunne git en utvilsom koloristisk begavelse af Jørgensens rang et taknemmeligt materiale. Et middelalderligt maleri, hvor man så den religiøse ekstase, denne blanding af angst og begeistring, af helvedfrygt og af længsel mod den uopnåelige skjønhed, drive menneskene til et liv i den hårdeste forsagelse, mens deres eget kraftige og blodfulde jeg begjærede at mættes ved livets gilde, der lød så larmende i deres nærhed, — måtte være en såre interessant opgave for en kunstner, der selv mener at være gjennembævet af „den hellige ild.“ Johs. Jørgensen har imidlertid savnet ''kraften,'' det brede penselstrøg, de stærke lysmættede farvetoner. Værre endda: hvor man beder om liv, får man snak. Denne Colombini holder mange taler, de samme om igjen, kjendte taler, kun svagere end Jørgensens engang var. Disse ulastelige, men kjedelige sætninger har tabt den skjære metalklang, som var Jørgensens egen. Sjelden har Jørgensen som digter således veget rang og<noinclude><references/> {{c|— 140 —}}</noinclude> eh9yr216rekvnl6ynjiwgl3g590jqm5 Modul:Author 828 125738 482570 2026-10-11T13:58:37Z Johshh 9757 Oprettede siden med "require('strict') local p = {} -- Local variables local getArgs = require('Module:Arguments').getArgs local yesno = require('Module:Yesno') local construct_header = require('Module:Header structure').construct_header local dateModule = require('Module:Era') local TableTools = require('Module:TableTools') local ordinal = require('Module:Ordinal')._ordinal local categories = {} -- List of categories to add page to. local function preprocess(args) return mw.getCurre..." 482570 Scribunto text/plain require('strict') local p = {} -- Local variables local getArgs = require('Module:Arguments').getArgs local yesno = require('Module:Yesno') local construct_header = require('Module:Header structure').construct_header local dateModule = require('Module:Era') local TableTools = require('Module:TableTools') local ordinal = require('Module:Ordinal')._ordinal local categories = {} -- List of categories to add page to. local function preprocess(args) return mw.getCurrentFrame():preprocess(args) end local wd_properties = { birth = 'P569', death = 'P570', workperiodstart = 'P2031', workperiodend = 'P2032', floruit = 'P1317', familyname = 'P734', gender = 'P21', instanceof = 'P31', medialegend = 'P2096', image = 'P18', flag_image = 'P41', logo_image = 'P154', nationalities = 'P27', occupations = 'P106', religions = 'P140', movements = 'P135', ideologies = 'P1142', employer = 'P108', positionheld = 'P39', awardreceived = 'P166', memberof = 'P463', canonizationstatus = 'P411', contributedto = 'P3919', socialclassification = 'P3716', instrument = 'P1303', describedby = 'P1343', mannerofdeath = 'P1196' } -------------------------------------------------------------------------------- -- Add a category to the current list of categories. Do not include the Category prefix. local function addCategory(category) table.insert(categories, category) end -------------------------------------------------------------------------------- -- Remove a category. Do not include the Category prefix. local function removeCategory(category) for catPos, cat in pairs(categories) do if cat == category then table.remove(categories, catPos) end end end -------------------------------------------------------------------------------- -- Get wikitext for all categories added using addCategory. local function getCategories() categories = TableTools.removeDuplicates(categories) table.sort(categories) local out = '' for _, cat in pairs(categories) do out = out .. '[[Category:' .. cat .. ']]' end return out end local function normalize_args(args) -- aliases local dup_cat = '' local oldKeys = {} local newArgs = {} for k, v in pairs(args) do local newkey = string.lower(string.gsub(string.gsub(tostring(k), '-', '_'), ' ', '_')) if newkey ~= tostring(k) then if args[newkey] then addCategory('Pages using duplicate arguments in template calls') end newArgs[newkey] = newArgs[newkey] or v table.insert(oldKeys, tostring(k)) end end for k, v in pairs(newArgs) do args[k] = v end for k, v in pairs(oldKeys) do args[v] = nil end args.wikidata = args.wikidata or args.wikidata_id args.wikidata_id = nil -- Fetch entity object for Wikidata item connected to the current page -- Let manually-specified Wikidata ID override if given and valid if args.wikidata and mw.wikibase.isValidEntityId(args.wikidata) then args.wd_entity = mw.wikibase.getEntity(args.wikidata) else args.wd_entity = mw.wikibase.getEntity() end args.use_initials = yesno(args.use_initials) ~= false and args.last_initial ~= '!NO_INITIALS' args.nocat = yesno(args.nocat) or false return args end -------------------------------------------------------------------------------- -- Get the actual parentheses-enclosed HTML string that shows the dates. local function getFormattedDates(birthyear, deathyear, workPeriodYears) if not birthyear and not deathyear and not workPeriodYears then return nil end local dates = '<br />(' local birthNotFloruit = birthyear and not birthyear:match("^fl%.") local deathNotFloruit = deathyear and not deathyear:match("^fl%.") if (birthNotFloruit and birthyear ~= '?') or (deathNotFloruit and deathyear ~= '?') or not workPeriodYears then removeCategory('Authors with approximate workperiodend dates') removeCategory('Authors with approximate workperiodstart dates') if birthyear then if birthNotFloruit and deathyear and not deathNotFloruit then dates = dates .. "b. " end dates = dates .. birthyear end if (birthyear or deathyear) and birthyear ~= deathyear then -- Add spaces if there are spaces in either of the dates. local spaces = '' if string.match((birthyear or '') .. (deathyear or ''), ' ') then spaces = ' ' end dates = dates .. spaces .. '–' .. spaces end if deathyear and birthyear ~= deathyear then if deathNotFloruit and birthyear and not birthNotFloruit then dates = dates .. "d. " end dates = dates .. deathyear end else dates = dates .. workPeriodYears addCategory('Authors with floruit dates') end if birthyear or deathyear or workPeriodYears then dates = dates .. ')' end return dates end -------------------------------------------------------------------------------- -- Take a statement of a given property and make a human-readable year string -- out of it, adding the relevant categories as we go. -- @param table statement The statement. -- @param string type One of 'birth' or 'death'. local function getYearStringFromSingleStatement(statement, year_type) local snak = statement.mainsnak -- We're not using mw.wikibase.formatValue because we only want years. -- No value. This is invalid for birth dates (should be 'somevalue' -- instead), and indicates 'still alive' for death dates. if snak.snaktype == 'novalue' and year_type == 'birth' then addCategory('Authors with missing birth dates') return nil end if snak.snaktype == 'novalue' and year_type == 'death' then addCategory('Living authors') return nil end -- Unknown value. if snak.snaktype == 'somevalue' then addCategory('Authors with unknown ' .. year_type .. ' dates') return '?' end -- Extract year from the time value. local _, _, extractedYear = string.find(snak.datavalue.value.time, '([%+%-]%d%d%d+)%-') local year = math.abs(tonumber(extractedYear)) addCategory(dateModule.era(extractedYear) .. ' authors') -- Century & millennium precision. if snak.datavalue.value.precision == 6 or snak.datavalue.value.precision == 7 then local ceilfactor = 100 local precisionName = 'century' if snak.datavalue.value.precision == 6 then ceilfactor = 1000 precisionName = 'millennium' end local cent = math.max(math.ceil(year/ceilfactor), 1) local suffixed_cent = ordinal(cent, false, false) year = suffixed_cent .. ' ' .. precisionName addCategory('Authors with approximate ' .. year_type .. ' dates') elseif snak.datavalue.value.precision == 8 then -- decade precision year = math.floor(tonumber(year)/10) * 10 .. 's' addCategory('Authors with approximate ' .. year_type .. ' dates') end if tonumber(extractedYear) < 0 then year = year .. ' BCE' end -- Remove from 'Living authors' if that's not possible. if tonumber(extractedYear) < tonumber(os.date('%Y') - 110) then removeCategory('Living authors') end -- Add to e.g. 'YYYY births' category (before we add 'c.' or 'fl.' prefixes). if year_type == 'birth' or year_type == 'death' then -- mw.logObject('Wikidata cat') -- mw.logObject(year .. ' ' .. year_type .. 's') addCategory(year .. ' ' .. year_type .. 's') end -- Extract circa (P1480 = sourcing circumstances, Q5727902 = circa) if statement.qualifiers and statement.qualifiers.P1480 then for _,qualifier in pairs(statement.qualifiers.P1480) do if qualifier.datavalue and qualifier.datavalue.value.id == 'Q5727902' then addCategory('Authors with approximate ' .. year_type .. ' dates') year = 'c. ' .. year end end end -- Add floruit abbreviation. if year_type == 'floruit' then year = 'fl. ' .. year end return year end -------------------------------------------------------------------------------- -- Get a given or family name property. -- This concatenates (with spaces) all statements of the given property in order of the series ordinal (P1545) qualifier. -- @TODO fix this. local function getNameFromWikidata(item, property) local statements = item:getBestStatements(property) local out = {} if statements[1] and statements[1].mainsnak.datavalue then local itemId = statements[1].mainsnak.datavalue.value.id table.insert(out, mw.wikibase.label(itemId) or '') end return table.concat(out, ' ') end -------------------------------------------------------------------------------- local function getPropertyValue(item, property) local statements = item:getBestStatements(property) if statements[1] and statements[1].mainsnak.datavalue then return statements[1].mainsnak.datavalue.value end end -------------------------------------------------------------------------------- -- The 'Wikisource' format for a birth or death year is as follows: -- "?" or empty for unknown (or still alive) -- Use BCE for years before year 1 -- Approximate dates: -- Decades or centuries: "1930s" or "20th century" -- Circa: "c/1930" or "c. 1930" or "ca 1930" or "circa 1930" -- Tenuous year: "1932/?" -- Choice of two or more years: "1932/1933" -- This is a slightly overly-complicated function, but one day will be able to be deleted. -- @param string type Either 'birth' or 'death' -- @return string The year to display local function formatWikisourceYear(year, year_type) if not year then return nil end -- mw.logObject('formatWikisourceYear') local yearParts = mw.text.split(year, '/', true) -- mw.logObject('yearParts') -- mw.logObject(yearParts) -- Ends in a question mark. if yearParts[2] == '?' then addCategory('Authors with unknown ' .. year_type .. ' dates') if tonumber(yearParts[1]) then -- mw.logObject('unknown') -- mw.logObject(yearParts[1] .. ' ' .. year_type .. 's') addCategory(dateModule.era(yearParts[1]) .. ' authors') addCategory(yearParts[1] .. ' ' .. year_type .. 's') else addCategory('Authors with non-numeric ' .. year_type .. ' dates') end return yearParts[1] .. '?' end -- Starts with one of the 'circa' abbreviations local circaNames = {'ca.', 'c.', 'ca', 'c', 'circa'} for _, circaName in pairs(circaNames) do local yearNumber local isCirca = false if yearParts[1] == circaName then yearNumber = mw.text.trim(yearParts[2]) isCirca = true elseif string.match(yearParts[1], '^' .. circaName) then yearNumber = string.gsub(yearParts[1], '^' .. circaName, '') isCirca = (tonumber(yearNumber) ~= nil) end if isCirca then addCategory('Authors with approximate ' .. year_type .. ' dates') if tonumber(yearNumber) then yearNumber = tonumber(yearNumber) -- mw.logObject(yearNumber) addCategory(dateModule.era(tostring(yearNumber)) .. ' authors') addCategory(yearNumber .. ' ' .. year_type .. 's') else addCategory('Authors with non-numeric ' .. year_type .. ' dates') end return 'c. ' .. yearNumber end end -- If there is more than one year part, and they're all numbers, add categories. local allPartsAreNumeric = true if #yearParts > 1 then for _, yearPart in pairs(yearParts) do if tonumber(yearPart) then -- mw.logObject('numeric') -- mw.logObject(yearPart .. ' ' .. year_type .. 's') addCategory(yearPart .. ' ' .. year_type .. 's') addCategory(dateModule.era(yearPart) .. ' authors') else allPartsAreNumeric = false end end if allPartsAreNumeric then addCategory('Authors with approximate birth dates') end elseif #yearParts == 1 and not tonumber(year) then allPartsAreNumeric = false end -- Otherwise, just use whatever's been given if not allPartsAreNumeric then addCategory('Authors with non-numeric ' .. year_type .. ' dates') end if #yearParts == 1 or allPartsAreNumeric == false then -- mw.logObject('not numeric') -- mw.logObject(year .. ' ' .. year_type .. 's') addCategory(year .. ' ' .. year_type .. 's') end return year end --[=[ Get a formatted year of the given property and add to the relevant categories ]=] local function formatWikidataYear(item, year_type) -- Check sanity of inputs if not item or not year_type or not wd_properties[year_type] then return nil end local property = wd_properties[year_type] -- Get this property's statements. local statements = item:getBestStatements(property) if #statements == 0 then -- If there are no statements of this type, add to 'missing' category. if year_type == 'birth' or year_type == 'death' then addCategory('Authors with missing ' .. year_type .. ' dates') end local isHuman = item:formatPropertyValues(wd_properties['instanceof']).value == 'human' if year_type == 'death' and isHuman then -- If no statements about death, assume to be alive. addCategory('Living authors') end end -- Compile a list of years, one from each statement. local years = {} for _, statement in pairs(statements) do local year = getYearStringFromSingleStatement(statement, year_type) if year then table.insert(years, year) end end years = TableTools.removeDuplicates(years) -- If no year found yet, try for a floruit date. Make an exception for workperiod if (#years == 0 or table.concat(years, '/') == '?') and year_type ~= "workperiodstart" and year_type ~= "workperiodend" then local floruitStatements = item:getBestStatements(wd_properties["floruit"]) for _, statement in pairs(floruitStatements) do -- If all we've got so far is 'unknown', replace it. if table.concat(years, '/') == '?' then years = {} end addCategory('Authors with floruit dates') local year = getYearStringFromSingleStatement(statement, 'floruit') if year then table.insert(years, year) end end end years = TableTools.removeDuplicates(years) if #years == 0 then return nil end return table.concat(years, '/') end -------------------------------------------------------------------------------- -- Get a single formatted date, with no categories. -- args.year, args.year_type, args.wd_entity local function date(args) if args.year then return formatWikisourceYear(args.year, args.year_type) else return formatWikidataYear(args.wd_entity, args.year_type) end end -------------------------------------------------------------------------------- -- Get a formatted string of the years that this author lived, -- and categorise in the appropriate categories. -- The returned string starts with a line break (<br />). local function dates(args) local outHtml = mw.html.create() -------------------------------------------------------------------------------- -- Check a given title as having the appropriate dates as a disambiguating suffix. local function checkTitleDatesAgainstWikidata(title, wikidata) -- All disambiguated author pages have parentheses in their titles. local titleHasParentheses = string.find(tostring(title), '%d%)') if not titleHasParentheses then return end -- The title should end with years in the same format as is used in the page header -- but with a normal hyphen instead of an en-dash. local dates = '(' .. (date({year_type = 'birth', wd_entity = args.wd_entity}) or '') .. '-' .. (date({year_type = 'death', wd_entity = args.wd_entity}) or '') .. ')' if string.sub(tostring(title), -string.len(dates)) ~= dates then addCategory('Authors with title-date mismatches') end end -- Check disambiguated page titles for accuracy. checkTitleDatesAgainstWikidata(args.pagetitle or mw.title.getCurrentTitle(), args.wikidata) -- Get the dates (do death first, so birth can override categories if required): -- Death local deathyear local wikidataDeathyear = formatWikidataYear(args.wd_entity, 'death') local wikisourceDeathyear = formatWikisourceYear(args.deathyear, 'death') if args.deathyear then -- For Wikisource-supplied death dates. deathyear = wikisourceDeathyear addCategory('Authors with override death dates') if args.wd_entity and wikisourceDeathyear ~= wikidataDeathyear then addCategory('Authors with death dates differing from Wikidata') end if tonumber(deathyear) then addCategory(dateModule.era(deathyear) .. ' authors') end else deathyear = wikidataDeathyear end if not deathyear then addCategory('Authors with missing death dates') end -- Birth local birthyear local wikidataBirthyear = formatWikidataYear(args.wd_entity, 'birth') local wikisourceBirthyear = formatWikisourceYear(args.birthyear, 'birth') if args.birthyear then -- For Wikisource-supplied birth dates. birthyear = wikisourceBirthyear addCategory('Authors with override birth dates') if args.wd_entity and wikisourceBirthyear ~= wikidataBirthyear then addCategory('Authors with birth dates differing from Wikidata') end if tonumber(birthyear) then addCategory(dateModule.era(birthyear) .. ' authors') end else birthyear = wikidataBirthyear end if not birthyear then addCategory('Authors with missing birth dates') end -- Work period local startYear = formatWikidataYear(args.wd_entity, "workperiodstart") local endYear = formatWikidataYear(args.wd_entity, "workperiodend") local workPeriodYears if startYear or endYear then if not startYear then startYear = '?' end if not endYear then endYear = '?' end workPeriodYears = "fl. " .. startYear .. "–" .. endYear else workPeriodYears = nil end -- Put all the output together, including manual override of the dates. local dates = '' if args.dates then -- The parentheses are repeated here and in getFormattedDates() addCategory('Authors with override dates') dates = '<br />(' .. args.dates .. ')' else dates = getFormattedDates(birthyear, deathyear, workPeriodYears) end if dates then outHtml:wikitext(dates) return tostring(outHtml) end return nil end --[=[ Match claims to configured categories. Utility function for constructCategories. Modifies the provided table to add categories configured in /data. ]=] local function addCategoriesFromClaims(entity, pId, knownCategories) -- Abort if the provided category mappings are missing or undefined if not knownCategories then error('Category mappings are not defined. Check [[Module:Author/data]].') end -- Get statements for the property provided (ignore deprecated statements) local statements = entity:getBestStatements(pId) -- Get the category for each statement's value if a mapping exists for _, v in pairs(statements) do -- Sometimes the property exists on the item but has no value, -- or it has an unknown value, -- so in the output from mw.wikibase.getEntity() -- .mainsnak's .datavalue will be nil. if v.mainsnak.snaktype == 'value' then local valueId = v.mainsnak.datavalue.value.id -- Add the category if we have a mapping for this statement local knownCat = knownCategories[valueId] if knownCat then addCategory(knownCat) end end end end --[=[ Get categories for nationality, occupations, etc. Returns categories as a string of wikicode ]=] local function constructCategories(entity) if not entity then return nil end -- Load the property to category mappings local DATA = mw.loadData('Module:Author/data') -- Add categories from properties for which we have a configured mapping addCategoriesFromClaims(entity, wd_properties['nationalities'], DATA.categories.nationalities) addCategoriesFromClaims(entity, wd_properties['occupations'], DATA.categories.occupations) addCategoriesFromClaims(entity, wd_properties['religions'], DATA.categories.religions) addCategoriesFromClaims(entity, wd_properties['movements'], DATA.categories.movements) addCategoriesFromClaims(entity, wd_properties['ideologies'], DATA.categories.ideologies) addCategoriesFromClaims(entity, wd_properties['employer'], DATA.categories.employer) addCategoriesFromClaims(entity, wd_properties['positionheld'], DATA.categories.positionheld) addCategoriesFromClaims(entity, wd_properties['awardreceived'], DATA.categories.awardreceived) addCategoriesFromClaims(entity, wd_properties['memberof'], DATA.categories.memberof) addCategoriesFromClaims(entity, wd_properties['canonizationstatus'], DATA.categories.canonizationstatus) addCategoriesFromClaims(entity, wd_properties['contributedto'], DATA.categories.contributedto) addCategoriesFromClaims(entity, wd_properties['socialclassification'], DATA.categories.socialclassification) addCategoriesFromClaims(entity, wd_properties['instrument'], DATA.categories.instrument) addCategoriesFromClaims(entity, wd_properties['describedby'], DATA.categories.describedby) addCategoriesFromClaims(entity, wd_properties['mannerofdeath'], DATA.categories.mannerofdeath) end -------------------------------------------------------------------------------- -- Output link and category for initial letters of family name. -- local function lastInitial(args) -- Handle special override if not args.use_initials then return nil end -- Allow manual override of initials. local initials = args.last_initial -- If a lastname is provided, get the initials from that. if not initials and args.lastname then initials = mw.ustring.sub(args.lastname, 1, 2) end -- Fetch from Wikidata. if not initials then local item = args.wd_entity if item then -- Get the first family name statement. local familyNames = item:getBestStatements(wd_properties['familyname']) if #familyNames > 0 then local familyNameId = familyNames[1].mainsnak.datavalue.value.id local familyName = mw.wikibase.getEntity(familyNameId) if familyName.labels and familyName.labels.en then -- Take the first two characters of the English label -- (this avoids issues with 'native label P1705' and is fine for English Wikisource). initials = mw.ustring.sub(familyName.labels.en.value, 1, 2) end end end end -- Put it all together and output local out if initials then out = '[[Wikisource:Authors-' .. initials .. '|Author Index: ' .. initials .. ']]' local authorCategory = mw.title.new('Authors-' .. initials, 'Category') addCategory(authorCategory.text) if authorCategory.exists ~= true then addCategory('Author pages with missing initials category') end else addCategory('Authors without initials') out = '[[:Category:Authors without initials|Authors without initials]]' end return out end -------------------------------------------------------------------------------- -- Header assembly local function ucfirst(s) return string.sub(s, 1, 1) .. string.sub(s, 2) end local function gender_from_wd(wd_entity) if not wd_entity then return nil end local statements = wd_entity:getBestStatements(wd_properties['gender']) if #statements == 0 then return nil end local genders = {} for _, statement in pairs(statements) do local snak = statement.mainsnak if snak.snaktype ~= 'value' or not snak or snak.datatype ~= 'wikibase-item' or not snak.datavalue or not snak.datavalue.value or not snak.datavalue.value.id then break end local gender_item = mw.wikibase.getEntity(snak.datavalue.value.id) if not gender_item or not gender_item.labels or not gender_item.labels.en or not gender_item.labels.en.value then break end table.insert(genders, gender_item.labels.en.value) end return genders[1] end local function image_from_wd(wd_entity, prefer_logo) if not wd_entity then return {} end local ordered_properties = {wd_properties['image'], wd_properties['flag_image'], wd_properties['logo_image']} if prefer_logo then ordered_properties = {wd_properties['flag_image'], wd_properties['logo_image'], wd_properties['image']} end local statements = {} for i, prop in ipairs(ordered_properties) do if #statements == 0 then statements = wd_entity:getBestStatements(prop) end end if #statements == 0 then return {} end local images = {} --[=[ local langcode = mw.getCurrentFrame():callParserFunction('int', {'lang'}) langcode = (mw.language.isKnownLanguageTag(langcode) and langcode) or mw.language.getContentLanguage().code local base_langcode = mw.text.split(langcode, '-', true)[1] local langcode_fallbacks_ordered = {base_langcode} for i, lang in ipairs(mw.language.getFallbacksFor(base_langcode)) do table.insert(langcode_fallbacks_ordered, lang) end if base_langcode ~= langcode then table.insert(langcode_fallbacks_ordered, 2, langcode) for i, lang in ipairs(mw.language.getFallbacksFor(langcode)) do table.insert(langcode_fallbacks_ordered, lang) end end local langcode_fallbacks = {} for i, v in ipairs(langcode_fallbacks_ordered) do langcode_fallbacks[v] = i end ]=] local langcode_fallbacks = {[mw.language.getContentLanguage().code] = 1} for _, statement in pairs(statements) do local image = statement.mainsnak.datatype == 'commonsMedia' and statement.mainsnak.datavalue and statement.mainsnak.datavalue.value local captions = {} local legends = statement['qualifiers'] and statement['qualifiers'][wd_properties['medialegend']] if legends then for i, legend in ipairs(legends) do if legend.datatype == 'monolingualtext' and legend.datavalue and legend.datavalue.value and legend.datavalue.value.text and legend.datavalue.value.language then local legend_langcode = legend.datavalue.value.language local legend_base_langcode = mw.text.split(legend_langcode, '-', true)[1] local legend_text = legend.datavalue.value.text if langcode_fallbacks[legend_langcode] then captions[langcode_fallbacks[legend_langcode]] = legend_text elseif langcode_fallbacks[legend_base_langcode] then captions[langcode_fallbacks[legend_base_langcode]] = captions[langcode_fallbacks[legend_base_langcode]] or legend_text end end end captions = TableTools.compressSparseArray(captions) end if image then table.insert(images, {image = image, image_caption = captions[1]}) end end return images[1] or {} end function p.image_from_wd(wd_entity, prefer_logo) return image_from_wd(wd_entity, prefer_logo) end local function get_image(args) local image = args.image local wd_image_info = image_from_wd(args.wd_entity, args.prefer_logo) local template_ns = args.template_ns or 'Author' if image then addCategory(template_ns .. ' pages with image') else image = wd_image_info.image if image then addCategory(template_ns .. ' pages with Wikidata image') else addCategory(template_ns .. ' pages without image') end end local image_display = '' if image then local upright = (yesno(args.upright) and '|upright=0.6') or '' args.image_caption = args.image_caption or wd_image_info.image_caption or args.name_text local caption_div = (args.image_caption and tostring(mw.html.create('div'):css({['text-align'] = 'center'}):wikitext(args.image_caption))) or '' image_display = '[[File:' .. image .. '|thumb' .. upright .. '|' .. caption_div .. '|alt=' .. (args.image_alt or '') .. ']]' end return image_display end local function construct_defaultsort(args) local defaultsort = args.defaultsort if not defaultsort then if args.firstname and args.lastname then defaultsort = ucfirst(args.lastname .. ', ' .. args.firstname) elseif args.firstname or args.lastname then defaultsort = ucfirst((args.lastname or '') .. (args.firstname or '')) end end if defaultsort then return mw.getCurrentFrame():callParserFunction('DEFAULTSORT', {defaultsort}) end return '' end local function author(args) args = normalize_args(args) -- Always tell Header structure that we're {{author}} -- TODO: Is there a use case for letting our clients set this? args.template = 'author' local current_title = mw.title.getCurrentTitle() local firstname = args.firstname local lastname = args.lastname local last_initial = args.last_initial if firstname then firstname = preprocess(firstname) end if lastname then lastname = preprocess(lastname) end if last_initial then last_initial = preprocess(last_initial) end args.header_class = 'wst-author ws-header' -- main block args.main_class = 'authortemplate' args.previous = lastInitial(args) if firstname and lastname then if yesno(args.invert_names) then args.name_text = lastname .. ' ' .. firstname else args.name_text = firstname .. ' ' .. lastname end else args.name_text = firstname or lastname end local name_text_span = '' if args.name_text then name_text_span = tostring(mw.html.create('span'):css({['font-weight'] = 'bold'}):wikitext(args.name_text)) end local dates_text = '' if not yesno(args.disambiguation) then dates_text = dates(args) or '' end args.main_title = name_text_span .. dates_text -- notes block args.notes_class = 'author_notes' args.commonscat = args.commonscat or ( args.wd_entity and args.wd_entity.claims and args.wd_entity.claims.P373 and args.wd_entity.claims.P373[1] and args.wd_entity.claims.P373[1].mainsnak and args.wd_entity.claims.P373[1].mainsnak.datatype == 'string' and args.wd_entity.claims.P373[1].mainsnak.datavalue and args.wd_entity.claims.P373[1].mainsnak.datavalue.value ) args.notes = args.description -- image local image_display = get_image(args) -- defaultsort args.defaultsort = args.defaultsort or args.sortkey local defaultsort_magicword = construct_defaultsort(args) -- categories if not args.categories then -- Author index category if last_initial then addCategory('Authors-' .. last_initial) elseif not last_initial then addCategory('Authors without initials') end -- Categorisation of author pages by gender, based on Wikidata sex or gender Property (P21) -- The main are: male (Q6581097), female (Q6581072), transgender female (Q1052281), transgender male (Q2449503) if args.wd_entity then local gender = gender_from_wd(args.wd_entity) if gender == 'transgender female' or gender == 'female' then addCategory('Women authors') addCategory('Author pages with gender in Wikidata') elseif gender == 'transgender male' or gender == 'male' then addCategory('Male authors') addCategory('Author pages with gender in Wikidata') elseif gender then addCategory('Author pages with unknown gender in Wikidata') else addCategory('Author pages with no gender in Wikidata') end if gender == 'transgender female' or gender == 'transgender male' then addCategory('Transgender and transsexual authors') end else addCategory('Author pages with gender manually categorised') end constructCategories(args.wd_entity) -- Categorisation of author pages with interwiki links (used for maintenance view only, links come from WD) if args.wikipedia then addCategory('Author pages linking to Wikipedia') end if args.wikiquote then addCategory('Author pages linking to Wikiquote') end if args.commons then addCategory('Author pages linking to Wikimedia Commons') end if args.commonscat then addCategory('Author pages linking to Wikimedia Commons categories') end -- Whether page is connected to Wikidata if (args.namespace or current_title.nsText) == 'Author' then if args.wd_entity then addCategory('Author pages connected to Wikidata') else addCategory('Author pages not connected to Wikidata') end end end -- microformat local microformat = mw.html.create('div') :attr('id', 'ws-data') :addClass('vcard ws-noexport') :css({['display'] = 'none', ['speak'] = 'none'}) local microformat_wikitext = { tostring(mw.html.create('span'):attr('id', 'ws-article-id'):wikitext(current_title.id)) } if args.wd_entity then table.insert( microformat_wikitext, tostring(mw.html.create('span') :attr('id', 'wd-article-id') :wikitext(args.wd_entity.id) ) ) end if args.name_text then table.insert( microformat_wikitext, tostring(mw.html.create('span') :attr('id', 'ws-name') :addClass('fn') :wikitext(args.name_text) ) ) table.insert( microformat_wikitext, tostring(mw.html.create('span') :addClass('n') :wikitext(table.concat({ tostring(mw.html.create('span'):addClass('given-name'):wikitext(firstname or '')), tostring(mw.html.create('span'):addClass('family-name'):wikitext(lastname or '')) })) ) ) end if args.defaultsort then table.insert(microformat_wikitext, tostring(mw.html.create('span'):attr('id', 'ws-key'):wikitext(args.defaultsort))) end if args.image then table.insert(microformat_wikitext, tostring(mw.html.create('span'):attr('id', 'ws-image'):wikitext(args.image))) end if args.birthyear then table.insert( microformat_wikitext, tostring(mw.html.create('span') :attr('id', 'ws-birthdate') :addClass('bday') :wikitext(date({['year_type'] = 'birth', ['year'] = args.birthyear})) ) ) end if args.deathyear then table.insert( microformat_wikitext, tostring(mw.html.create('span') :attr('id', 'ws-deathdate') :addClass('dday') :wikitext(date({['year_type'] = 'death', ['year'] = args.deathyear})) ) ) end if args.wikipedia then table.insert(microformat_wikitext, tostring(mw.html.create('span'):attr('id', 'ws-wikipedia'):wikitext(args.wikipedia))) end if args.wikiquote then table.insert(microformat_wikitext, tostring(mw.html.create('span'):attr('id', 'ws-wikiquote'):wikitext(args.wikiquote))) end if args.commonscat then table.insert(microformat_wikitext, tostring(mw.html.create('span'):attr('id', 'ws-commons'):wikitext(args.commonscat))) elseif args.commons then table.insert(microformat_wikitext, tostring(mw.html.create('span'):attr('id', 'ws-commons'):wikitext('Category' .. args.commons))) end if args.description then table.insert(microformat_wikitext, tostring(mw.html.create('span'):attr('id', 'ws-description'):addClass('note'):wikitext(args.description))) end microformat:wikitext(table.concat(microformat_wikitext)) -- assemble local cats = '' if not args.nocat then cats = (args.categories or '') .. getCategories() end args.post_notes = image_display .. defaultsort_magicword .. cats .. tostring(microformat) args.wikidataswitch = true return mw.getCurrentFrame():extensionTag('templatestyles', '', {src = 'Template:Author/styles.css'}) .. construct_header(args) end -- for testing function p._getCategories(args) args = normalize_args(args) p._author(args) return getCategories() end function p.getCategories(frame) return p._getCategories(getArgs(frame)) end function p._date(args) args = normalize_args(args) args.year_type = args.year_type or args['type'] or 'birth' return date(args) end function p.date(frame) return p._date(getArgs(frame)) end function p._lastInitial(args) args = normalize_args(args) return lastInitial(args) end function p.lastInitial(frame) return p._lastInitial(getArgs(frame)) end -- Debugging 1: mw.log(p._lastInitial({last_initial = 'Qx'})) -- Debugging 2: mw.log(p._lastInitial({wikidata = 'Q1107985'})) -- Debugging 1: mw.log(p._lastInitial({lastname = 'Qqxxx'})) -- Debugging 3: mw.log(p._lastInitial({last_initial = 'Qx', wikidata_id='Q1107985'})) -- used by [[Module:Person]] function p._dates(args) args = normalize_args(args) return dates(args) end function p.dates(frame) return p._dates(getArgs(frame)) end function p._get_image(args) args = normalize_args(args) if args.nocat then return get_image(args) else return get_image(args) .. getCategories() end end function p.get_image(frame) return p._get_image(getArgs(frame)) end function p._construct_defaultsort(args) args = normalize_args(args) return construct_defaultsort(args) end function p.construct_defaultsort(frame) return p._construct_defaultsort(getArgs(frame)) end -- Used by [[Module:Disambiguation]] and [[Template:Author]] function p._author(args) return author(args) end function p.author(frame) return p._author(getArgs(frame)) end return p 345ekbjn0qby75uhcq83aue5p236iho 482576 482570 2026-10-11T14:06:50Z Johshh 9757 482576 Scribunto text/plain require('strict') local p = {} -- Local variables local getArgs = require('Module:Arguments').getArgs local yesno = require('Module:Yesno') local construct_header = require('Module:Header structure').construct_header local dateModule = require('Module:Era') local TableTools = require('Module:TableTools') local ordinal = require('Module:Ordinal')._ordinal local categories = {} -- List of categories to add page to. local function preprocess(args) return mw.getCurrentFrame():preprocess(args) end local wd_properties = { birth = 'P569', death = 'P570', workperiodstart = 'P2031', workperiodend = 'P2032', floruit = 'P1317', familyname = 'P734', gender = 'P21', instanceof = 'P31', medialegend = 'P2096', image = 'P18', flag_image = 'P41', logo_image = 'P154', nationalities = 'P27', occupations = 'P106', religions = 'P140', movements = 'P135', ideologies = 'P1142', employer = 'P108', positionheld = 'P39', awardreceived = 'P166', memberof = 'P463', canonizationstatus = 'P411', contributedto = 'P3919', socialclassification = 'P3716', instrument = 'P1303', describedby = 'P1343', mannerofdeath = 'P1196' } -------------------------------------------------------------------------------- -- Add a category to the current list of categories. Do not include the Category prefix. local function addCategory(category) table.insert(categories, category) end -------------------------------------------------------------------------------- -- Remove a category. Do not include the Category prefix. local function removeCategory(category) for catPos, cat in pairs(categories) do if cat == category then table.remove(categories, catPos) end end end -------------------------------------------------------------------------------- -- Get wikitext for all categories added using addCategory. local function getCategories() categories = TableTools.removeDuplicates(categories) table.sort(categories) local out = '' for _, cat in pairs(categories) do out = out .. '[[Category:' .. cat .. ']]' end return out end local function normalize_args(args) -- aliases local dup_cat = '' local oldKeys = {} local newArgs = {} for k, v in pairs(args) do local newkey = string.lower(string.gsub(string.gsub(tostring(k), '-', '_'), ' ', '_')) if newkey ~= tostring(k) then if args[newkey] then addCategory('Pages using duplicate arguments in template calls') end newArgs[newkey] = newArgs[newkey] or v table.insert(oldKeys, tostring(k)) end end for k, v in pairs(newArgs) do args[k] = v end for k, v in pairs(oldKeys) do args[v] = nil end args.wikidata = args.wikidata or args.wikidata_id args.wikidata_id = nil -- Fetch entity object for Wikidata item connected to the current page -- Let manually-specified Wikidata ID override if given and valid if args.wikidata and mw.wikibase.isValidEntityId(args.wikidata) then args.wd_entity = mw.wikibase.getEntity(args.wikidata) else args.wd_entity = mw.wikibase.getEntity() end args.use_initials = yesno(args.use_initials) ~= false and args.last_initial ~= '!NO_INITIALS' args.nocat = yesno(args.nocat) or false return args end -------------------------------------------------------------------------------- -- Get the actual parentheses-enclosed HTML string that shows the dates. local function getFormattedDates(birthyear, deathyear, workPeriodYears) if not birthyear and not deathyear and not workPeriodYears then return nil end local dates = '<br />(' local birthNotFloruit = birthyear and not birthyear:match("^fl%.") local deathNotFloruit = deathyear and not deathyear:match("^fl%.") if (birthNotFloruit and birthyear ~= '?') or (deathNotFloruit and deathyear ~= '?') or not workPeriodYears then removeCategory('Authors with approximate workperiodend dates') removeCategory('Authors with approximate workperiodstart dates') if birthyear then if birthNotFloruit and deathyear and not deathNotFloruit then dates = dates .. "b. " end dates = dates .. birthyear end if (birthyear or deathyear) and birthyear ~= deathyear then -- Add spaces if there are spaces in either of the dates. local spaces = '' if string.match((birthyear or '') .. (deathyear or ''), ' ') then spaces = ' ' end dates = dates .. spaces .. '–' .. spaces end if deathyear and birthyear ~= deathyear then if deathNotFloruit and birthyear and not birthNotFloruit then dates = dates .. "d. " end dates = dates .. deathyear end else dates = dates .. workPeriodYears addCategory('Authors with floruit dates') end if birthyear or deathyear or workPeriodYears then dates = dates .. ')' end return dates end -------------------------------------------------------------------------------- -- Take a statement of a given property and make a human-readable year string -- out of it, adding the relevant categories as we go. -- @param table statement The statement. -- @param string type One of 'birth' or 'death'. local function getYearStringFromSingleStatement(statement, year_type) local snak = statement.mainsnak -- We're not using mw.wikibase.formatValue because we only want years. -- No value. This is invalid for birth dates (should be 'somevalue' -- instead), and indicates 'still alive' for death dates. if snak.snaktype == 'novalue' and year_type == 'birth' then addCategory('Authors with missing birth dates') return nil end if snak.snaktype == 'novalue' and year_type == 'death' then addCategory('Living authors') return nil end -- Unknown value. if snak.snaktype == 'somevalue' then addCategory('Authors with unknown ' .. year_type .. ' dates') return '?' end -- Extract year from the time value. local _, _, extractedYear = string.find(snak.datavalue.value.time, '([%+%-]%d%d%d+)%-') local year = math.abs(tonumber(extractedYear)) addCategory(dateModule.era(extractedYear) .. ' authors') -- Century & millennium precision. if snak.datavalue.value.precision == 6 or snak.datavalue.value.precision == 7 then local ceilfactor = 100 local precisionName = 'century' if snak.datavalue.value.precision == 6 then ceilfactor = 1000 precisionName = 'millennium' end local cent = math.max(math.ceil(year/ceilfactor), 1) local suffixed_cent = ordinal(cent, false, false) year = suffixed_cent .. ' ' .. precisionName addCategory('Authors with approximate ' .. year_type .. ' dates') elseif snak.datavalue.value.precision == 8 then -- decade precision year = math.floor(tonumber(year)/10) * 10 .. 's' addCategory('Authors with approximate ' .. year_type .. ' dates') end if tonumber(extractedYear) < 0 then year = year .. ' BCE' end -- Remove from 'Living authors' if that's not possible. if tonumber(extractedYear) < tonumber(os.date('%Y') - 110) then removeCategory('Living authors') end -- Add to e.g. 'YYYY births' category (before we add 'c.' or 'fl.' prefixes). if year_type == 'birth' or year_type == 'death' then -- mw.logObject('Wikidata cat') -- mw.logObject(year .. ' ' .. year_type .. 's') addCategory(year .. ' ' .. year_type .. 's') end -- Extract circa (P1480 = sourcing circumstances, Q5727902 = circa) if statement.qualifiers and statement.qualifiers.P1480 then for _,qualifier in pairs(statement.qualifiers.P1480) do if qualifier.datavalue and qualifier.datavalue.value.id == 'Q5727902' then addCategory('Authors with approximate ' .. year_type .. ' dates') year = 'c. ' .. year end end end -- Add floruit abbreviation. if year_type == 'floruit' then year = 'fl. ' .. year end return year end -------------------------------------------------------------------------------- -- Get a given or family name property. -- This concatenates (with spaces) all statements of the given property in order of the series ordinal (P1545) qualifier. -- @TODO fix this. local function getNameFromWikidata(item, property) local statements = item:getBestStatements(property) local out = {} if statements[1] and statements[1].mainsnak.datavalue then local itemId = statements[1].mainsnak.datavalue.value.id table.insert(out, mw.wikibase.label(itemId) or '') end return table.concat(out, ' ') end -------------------------------------------------------------------------------- local function getPropertyValue(item, property) local statements = item:getBestStatements(property) if statements[1] and statements[1].mainsnak.datavalue then return statements[1].mainsnak.datavalue.value end end -------------------------------------------------------------------------------- -- The 'Wikisource' format for a birth or death year is as follows: -- "?" or empty for unknown (or still alive) -- Use BCE for years before year 1 -- Approximate dates: -- Decades or centuries: "1930s" or "20th century" -- Circa: "c/1930" or "c. 1930" or "ca 1930" or "circa 1930" -- Tenuous year: "1932/?" -- Choice of two or more years: "1932/1933" -- This is a slightly overly-complicated function, but one day will be able to be deleted. -- @param string type Either 'birth' or 'death' -- @return string The year to display local function formatWikisourceYear(year, year_type) if not year then return nil end -- mw.logObject('formatWikisourceYear') local yearParts = mw.text.split(year, '/', true) -- mw.logObject('yearParts') -- mw.logObject(yearParts) -- Ends in a question mark. if yearParts[2] == '?' then addCategory('Authors with unknown ' .. year_type .. ' dates') if tonumber(yearParts[1]) then -- mw.logObject('unknown') -- mw.logObject(yearParts[1] .. ' ' .. year_type .. 's') addCategory(dateModule.era(yearParts[1]) .. ' authors') addCategory(yearParts[1] .. ' ' .. year_type .. 's') else addCategory('Authors with non-numeric ' .. year_type .. ' dates') end return yearParts[1] .. '?' end -- Starts with one of the 'circa' abbreviations local circaNames = {'ca.', 'c.', 'ca', 'c', 'circa'} for _, circaName in pairs(circaNames) do local yearNumber local isCirca = false if yearParts[1] == circaName then yearNumber = mw.text.trim(yearParts[2]) isCirca = true elseif string.match(yearParts[1], '^' .. circaName) then yearNumber = string.gsub(yearParts[1], '^' .. circaName, '') isCirca = (tonumber(yearNumber) ~= nil) end if isCirca then addCategory('Authors with approximate ' .. year_type .. ' dates') if tonumber(yearNumber) then yearNumber = tonumber(yearNumber) -- mw.logObject(yearNumber) addCategory(dateModule.era(tostring(yearNumber)) .. ' authors') addCategory(yearNumber .. ' ' .. year_type .. 's') else addCategory('Authors with non-numeric ' .. year_type .. ' dates') end return 'c. ' .. yearNumber end end -- If there is more than one year part, and they're all numbers, add categories. local allPartsAreNumeric = true if #yearParts > 1 then for _, yearPart in pairs(yearParts) do if tonumber(yearPart) then -- mw.logObject('numeric') -- mw.logObject(yearPart .. ' ' .. year_type .. 's') addCategory(yearPart .. ' ' .. year_type .. 's') addCategory(dateModule.era(yearPart) .. ' authors') else allPartsAreNumeric = false end end if allPartsAreNumeric then addCategory('Authors with approximate birth dates') end elseif #yearParts == 1 and not tonumber(year) then allPartsAreNumeric = false end -- Otherwise, just use whatever's been given if not allPartsAreNumeric then addCategory('Authors with non-numeric ' .. year_type .. ' dates') end if #yearParts == 1 or allPartsAreNumeric == false then -- mw.logObject('not numeric') -- mw.logObject(year .. ' ' .. year_type .. 's') addCategory(year .. ' ' .. year_type .. 's') end return year end --[=[ Get a formatted year of the given property and add to the relevant categories ]=] local function formatWikidataYear(item, year_type) -- Check sanity of inputs if not item or not year_type or not wd_properties[year_type] then return nil end local property = wd_properties[year_type] -- Get this property's statements. local statements = item:getBestStatements(property) if #statements == 0 then -- If there are no statements of this type, add to 'missing' category. if year_type == 'birth' or year_type == 'death' then addCategory('Authors with missing ' .. year_type .. ' dates') end local isHuman = item:formatPropertyValues(wd_properties['instanceof']).value == 'human' if year_type == 'death' and isHuman then -- If no statements about death, assume to be alive. addCategory('Living authors') end end -- Compile a list of years, one from each statement. local years = {} for _, statement in pairs(statements) do local year = getYearStringFromSingleStatement(statement, year_type) if year then table.insert(years, year) end end years = TableTools.removeDuplicates(years) -- If no year found yet, try for a floruit date. Make an exception for workperiod if (#years == 0 or table.concat(years, '/') == '?') and year_type ~= "workperiodstart" and year_type ~= "workperiodend" then local floruitStatements = item:getBestStatements(wd_properties["floruit"]) for _, statement in pairs(floruitStatements) do -- If all we've got so far is 'unknown', replace it. if table.concat(years, '/') == '?' then years = {} end addCategory('Authors with floruit dates') local year = getYearStringFromSingleStatement(statement, 'floruit') if year then table.insert(years, year) end end end years = TableTools.removeDuplicates(years) if #years == 0 then return nil end return table.concat(years, '/') end -------------------------------------------------------------------------------- -- Get a single formatted date, with no categories. -- args.year, args.year_type, args.wd_entity local function date(args) if args.year then return formatWikisourceYear(args.year, args.year_type) else return formatWikidataYear(args.wd_entity, args.year_type) end end -------------------------------------------------------------------------------- -- Get a formatted string of the years that this author lived, -- and categorise in the appropriate categories. -- The returned string starts with a line break (<br />). local function dates(args) local outHtml = mw.html.create() -------------------------------------------------------------------------------- -- Check a given title as having the appropriate dates as a disambiguating suffix. local function checkTitleDatesAgainstWikidata(title, wikidata) -- All disambiguated author pages have parentheses in their titles. local titleHasParentheses = string.find(tostring(title), '%d%)') if not titleHasParentheses then return end -- The title should end with years in the same format as is used in the page header -- but with a normal hyphen instead of an en-dash. local dates = '(' .. (date({year_type = 'birth', wd_entity = args.wd_entity}) or '') .. '-' .. (date({year_type = 'death', wd_entity = args.wd_entity}) or '') .. ')' if string.sub(tostring(title), -string.len(dates)) ~= dates then addCategory('Authors with title-date mismatches') end end -- Check disambiguated page titles for accuracy. checkTitleDatesAgainstWikidata(args.pagetitle or mw.title.getCurrentTitle(), args.wikidata) -- Get the dates (do death first, so birth can override categories if required): -- Death local deathyear local wikidataDeathyear = formatWikidataYear(args.wd_entity, 'death') local wikisourceDeathyear = formatWikisourceYear(args.deathyear, 'death') if args.deathyear then -- For Wikisource-supplied death dates. deathyear = wikisourceDeathyear addCategory('Authors with override death dates') if args.wd_entity and wikisourceDeathyear ~= wikidataDeathyear then addCategory('Authors with death dates differing from Wikidata') end if tonumber(deathyear) then addCategory(dateModule.era(deathyear) .. ' authors') end else deathyear = wikidataDeathyear end if not deathyear then addCategory('Authors with missing death dates') end -- Birth local birthyear local wikidataBirthyear = formatWikidataYear(args.wd_entity, 'birth') local wikisourceBirthyear = formatWikisourceYear(args.birthyear, 'birth') if args.birthyear then -- For Wikisource-supplied birth dates. birthyear = wikisourceBirthyear addCategory('Authors with override birth dates') if args.wd_entity and wikisourceBirthyear ~= wikidataBirthyear then addCategory('Authors with birth dates differing from Wikidata') end if tonumber(birthyear) then addCategory(dateModule.era(birthyear) .. ' authors') end else birthyear = wikidataBirthyear end if not birthyear then addCategory('Authors with missing birth dates') end -- Work period local startYear = formatWikidataYear(args.wd_entity, "workperiodstart") local endYear = formatWikidataYear(args.wd_entity, "workperiodend") local workPeriodYears if startYear or endYear then if not startYear then startYear = '?' end if not endYear then endYear = '?' end workPeriodYears = "fl. " .. startYear .. "–" .. endYear else workPeriodYears = nil end -- Put all the output together, including manual override of the dates. local dates = '' if args.dates then -- The parentheses are repeated here and in getFormattedDates() addCategory('Authors with override dates') dates = '<br />(' .. args.dates .. ')' else dates = getFormattedDates(birthyear, deathyear, workPeriodYears) end if dates then outHtml:wikitext(dates) return tostring(outHtml) end return nil end --[=[ Match claims to configured categories. Utility function for constructCategories. Modifies the provided table to add categories configured in /data. ]=] local function addCategoriesFromClaims(entity, pId, knownCategories) -- Abort if the provided category mappings are missing or undefined if not knownCategories then error('Category mappings are not defined. Check [[Module:Author/data]].') end -- Get statements for the property provided (ignore deprecated statements) local statements = entity:getBestStatements(pId) -- Get the category for each statement's value if a mapping exists for _, v in pairs(statements) do -- Sometimes the property exists on the item but has no value, -- or it has an unknown value, -- so in the output from mw.wikibase.getEntity() -- .mainsnak's .datavalue will be nil. if v.mainsnak.snaktype == 'value' then local valueId = v.mainsnak.datavalue.value.id -- Add the category if we have a mapping for this statement local knownCat = knownCategories[valueId] if knownCat then addCategory(knownCat) end end end end --[=[ Get categories for nationality, occupations, etc. Returns categories as a string of wikicode ]=] local function constructCategories(entity) if not entity then return nil end -- Load the property to category mappings local DATA = mw.loadData('Module:Author/data') -- Add categories from properties for which we have a configured mapping addCategoriesFromClaims(entity, wd_properties['nationalities'], DATA.categories.nationalities) addCategoriesFromClaims(entity, wd_properties['occupations'], DATA.categories.occupations) addCategoriesFromClaims(entity, wd_properties['religions'], DATA.categories.religions) addCategoriesFromClaims(entity, wd_properties['movements'], DATA.categories.movements) addCategoriesFromClaims(entity, wd_properties['ideologies'], DATA.categories.ideologies) addCategoriesFromClaims(entity, wd_properties['employer'], DATA.categories.employer) addCategoriesFromClaims(entity, wd_properties['positionheld'], DATA.categories.positionheld) addCategoriesFromClaims(entity, wd_properties['awardreceived'], DATA.categories.awardreceived) addCategoriesFromClaims(entity, wd_properties['memberof'], DATA.categories.memberof) addCategoriesFromClaims(entity, wd_properties['canonizationstatus'], DATA.categories.canonizationstatus) addCategoriesFromClaims(entity, wd_properties['contributedto'], DATA.categories.contributedto) addCategoriesFromClaims(entity, wd_properties['socialclassification'], DATA.categories.socialclassification) addCategoriesFromClaims(entity, wd_properties['instrument'], DATA.categories.instrument) addCategoriesFromClaims(entity, wd_properties['describedby'], DATA.categories.describedby) addCategoriesFromClaims(entity, wd_properties['mannerofdeath'], DATA.categories.mannerofdeath) end -------------------------------------------------------------------------------- -- Output link and category for initial letters of family name. -- local function lastInitial(args) -- Handle special override if not args.use_initials then return nil end -- Allow manual override of initials. local initials = args.last_initial -- If a lastname is provided, get the initials from that. if not initials and args.lastname then initials = mw.ustring.sub(args.lastname, 1, 2) end -- Fetch from Wikidata. if not initials then local item = args.wd_entity if item then -- Get the first family name statement. local familyNames = item:getBestStatements(wd_properties['familyname']) if #familyNames > 0 then local familyNameId = familyNames[1].mainsnak.datavalue.value.id local familyName = mw.wikibase.getEntity(familyNameId) if familyName.labels and familyName.labels.en then -- Take the first two characters of the English label -- (this avoids issues with 'native label P1705' and is fine for English Wikisource). initials = mw.ustring.sub(familyName.labels.en.value, 1, 2) end end end end -- Put it all together and output local out if initials then out = '[[Wikisource:Authors-' .. initials .. '|Author Index: ' .. initials .. ']]' local authorCategory = mw.title.new('Authors-' .. initials, 'Category') addCategory(authorCategory.text) if authorCategory.exists ~= true then addCategory('Author pages with missing initials category') end else addCategory('Authors without initials') out = '[[:Category:Authors without initials|Authors without initials]]' end return out end -------------------------------------------------------------------------------- -- Header assembly local function ucfirst(s) return string.sub(s, 1, 1) .. string.sub(s, 2) end local function gender_from_wd(wd_entity) if not wd_entity then return nil end local statements = wd_entity:getBestStatements(wd_properties['gender']) if #statements == 0 then return nil end local genders = {} for _, statement in pairs(statements) do local snak = statement.mainsnak if snak.snaktype ~= 'value' or not snak or snak.datatype ~= 'wikibase-item' or not snak.datavalue or not snak.datavalue.value or not snak.datavalue.value.id then break end local gender_item = mw.wikibase.getEntity(snak.datavalue.value.id) if not gender_item or not gender_item.labels or not gender_item.labels.en or not gender_item.labels.en.value then break end table.insert(genders, gender_item.labels.en.value) end return genders[1] end local function image_from_wd(wd_entity, prefer_logo) if not wd_entity then return {} end local ordered_properties = {wd_properties['image'], wd_properties['flag_image'], wd_properties['logo_image']} if prefer_logo then ordered_properties = {wd_properties['flag_image'], wd_properties['logo_image'], wd_properties['image']} end local statements = {} for i, prop in ipairs(ordered_properties) do if #statements == 0 then statements = wd_entity:getBestStatements(prop) end end if #statements == 0 then return {} end local images = {} --[=[ local langcode = mw.getCurrentFrame():callParserFunction('int', {'lang'}) langcode = (mw.language.isKnownLanguageTag(langcode) and langcode) or mw.language.getContentLanguage().code local base_langcode = mw.text.split(langcode, '-', true)[1] local langcode_fallbacks_ordered = {base_langcode} for i, lang in ipairs(mw.language.getFallbacksFor(base_langcode)) do table.insert(langcode_fallbacks_ordered, lang) end if base_langcode ~= langcode then table.insert(langcode_fallbacks_ordered, 2, langcode) for i, lang in ipairs(mw.language.getFallbacksFor(langcode)) do table.insert(langcode_fallbacks_ordered, lang) end end local langcode_fallbacks = {} for i, v in ipairs(langcode_fallbacks_ordered) do langcode_fallbacks[v] = i end ]=] local langcode_fallbacks = {[mw.language.getContentLanguage().code] = 1} for _, statement in pairs(statements) do local image = statement.mainsnak.datatype == 'commonsMedia' and statement.mainsnak.datavalue and statement.mainsnak.datavalue.value local captions = {} local legends = statement['qualifiers'] and statement['qualifiers'][wd_properties['medialegend']] if legends then for i, legend in ipairs(legends) do if legend.datatype == 'monolingualtext' and legend.datavalue and legend.datavalue.value and legend.datavalue.value.text and legend.datavalue.value.language then local legend_langcode = legend.datavalue.value.language local legend_base_langcode = mw.text.split(legend_langcode, '-', true)[1] local legend_text = legend.datavalue.value.text if langcode_fallbacks[legend_langcode] then captions[langcode_fallbacks[legend_langcode]] = legend_text elseif langcode_fallbacks[legend_base_langcode] then captions[langcode_fallbacks[legend_base_langcode]] = captions[langcode_fallbacks[legend_base_langcode]] or legend_text end end end captions = TableTools.compressSparseArray(captions) end if image then table.insert(images, {image = image, image_caption = captions[1]}) end end return images[1] or {} end function p.image_from_wd(wd_entity, prefer_logo) return image_from_wd(wd_entity, prefer_logo) end local function get_image(args) local image = args.image local wd_image_info = image_from_wd(args.wd_entity, args.prefer_logo) local template_ns = args.template_ns or 'Author' if image then addCategory(template_ns .. ' pages with image') else image = wd_image_info.image if image then addCategory(template_ns .. ' pages with Wikidata image') else addCategory(template_ns .. ' pages without image') end end local image_display = '' if image then local upright = (yesno(args.upright) and '|upright=0.6') or '' args.image_caption = args.image_caption or wd_image_info.image_caption or args.name_text local caption_div = (args.image_caption and tostring(mw.html.create('div'):css({['text-align'] = 'center'}):wikitext(args.image_caption))) or '' image_display = '[[File:' .. image .. '|thumb' .. upright .. '|' .. caption_div .. '|alt=' .. (args.image_alt or '') .. ']]' end return image_display end local function construct_defaultsort(args) local defaultsort = args.defaultsort if not defaultsort then if args.firstname and args.lastname then defaultsort = ucfirst(args.lastname .. ', ' .. args.firstname) elseif args.firstname or args.lastname then defaultsort = ucfirst((args.lastname or '') .. (args.firstname or '')) end end if defaultsort then return mw.getCurrentFrame():callParserFunction('DEFAULTSORT', {defaultsort}) end return '' end local function author(args) args = normalize_args(args) -- Always tell Header structure that we're {{author}} -- TODO: Is there a use case for letting our clients set this? args.template = 'author' local current_title = mw.title.getCurrentTitle() local firstname = args.firstname local lastname = args.lastname local last_initial = args.last_initial if firstname then firstname = preprocess(firstname) end if lastname then lastname = preprocess(lastname) end if last_initial then last_initial = preprocess(last_initial) end args.header_class = 'wst-author ws-header' -- main block args.main_class = 'authortemplate' args.previous = lastInitial(args) if firstname and lastname then if yesno(args.invert_names) then args.name_text = lastname .. ' ' .. firstname else args.name_text = firstname .. ' ' .. lastname end else args.name_text = firstname or lastname end local name_text_span = '' if args.name_text then name_text_span = tostring(mw.html.create('span'):css({['font-weight'] = 'bold'}):wikitext(args.name_text)) end local dates_text = '' if not yesno(args.disambiguation) then dates_text = dates(args) or '' end args.main_title = name_text_span .. dates_text -- notes block args.notes_class = 'author_notes' args.commonscat = args.commonscat or ( args.wd_entity and args.wd_entity.claims and args.wd_entity.claims.P373 and args.wd_entity.claims.P373[1] and args.wd_entity.claims.P373[1].mainsnak and args.wd_entity.claims.P373[1].mainsnak.datatype == 'string' and args.wd_entity.claims.P373[1].mainsnak.datavalue and args.wd_entity.claims.P373[1].mainsnak.datavalue.value ) args.notes = args.description -- image local image_display = get_image(args) -- defaultsort args.defaultsort = args.defaultsort or args.sortkey local defaultsort_magicword = construct_defaultsort(args) -- categories if not args.categories then -- Author index category if last_initial then addCategory('Authors-' .. last_initial) elseif not last_initial then addCategory('Authors without initials') end -- Categorisation of author pages by gender, based on Wikidata sex or gender Property (P21) -- The main are: male (Q6581097), female (Q6581072), transgender female (Q1052281), transgender male (Q2449503) if args.wd_entity then local gender = gender_from_wd(args.wd_entity) if gender == 'transgender female' or gender == 'female' then addCategory('Women authors') addCategory('Author pages with gender in Wikidata') elseif gender == 'transgender male' or gender == 'male' then addCategory('Male authors') addCategory('Author pages with gender in Wikidata') elseif gender then addCategory('Author pages with unknown gender in Wikidata') else addCategory('Author pages with no gender in Wikidata') end if gender == 'transgender female' or gender == 'transgender male' then addCategory('Transgender and transsexual authors') end else addCategory('Author pages with gender manually categorised') end constructCategories(args.wd_entity) -- Categorisation of author pages with interwiki links (used for maintenance view only, links come from WD) if args.wikipedia then addCategory('Author pages linking to Wikipedia') end if args.wikiquote then addCategory('Author pages linking to Wikiquote') end if args.commons then addCategory('Author pages linking to Wikimedia Commons') end if args.commonscat then addCategory('Author pages linking to Wikimedia Commons categories') end -- Whether page is connected to Wikidata if (args.namespace or current_title.nsText) == 'Author' then if args.wd_entity then addCategory('Author pages connected to Wikidata') else addCategory('Author pages not connected to Wikidata') end end end -- microformat local microformat = mw.html.create('div') :attr('id', 'ws-data') :addClass('vcard ws-noexport') :css({['display'] = 'none', ['speak'] = 'none'}) local microformat_wikitext = { tostring(mw.html.create('span'):attr('id', 'ws-article-id'):wikitext(current_title.id)) } if args.wd_entity then table.insert( microformat_wikitext, tostring(mw.html.create('span') :attr('id', 'wd-article-id') :wikitext(args.wd_entity.id) ) ) end if args.name_text then table.insert( microformat_wikitext, tostring(mw.html.create('span') :attr('id', 'ws-name') :addClass('fn') :wikitext(args.name_text) ) ) table.insert( microformat_wikitext, tostring(mw.html.create('span') :addClass('n') :wikitext(table.concat({ tostring(mw.html.create('span'):addClass('given-name'):wikitext(firstname or '')), tostring(mw.html.create('span'):addClass('family-name'):wikitext(lastname or '')) })) ) ) end if args.defaultsort then table.insert(microformat_wikitext, tostring(mw.html.create('span'):attr('id', 'ws-key'):wikitext(args.defaultsort))) end if args.image then table.insert(microformat_wikitext, tostring(mw.html.create('span'):attr('id', 'ws-image'):wikitext(args.image))) end if args.birthyear then table.insert( microformat_wikitext, tostring(mw.html.create('span') :attr('id', 'ws-birthdate') :addClass('bday') :wikitext(date({['year_type'] = 'birth', ['year'] = args.birthyear})) ) ) end if args.deathyear then table.insert( microformat_wikitext, tostring(mw.html.create('span') :attr('id', 'ws-deathdate') :addClass('dday') :wikitext(date({['year_type'] = 'death', ['year'] = args.deathyear})) ) ) end if args.wikipedia then table.insert(microformat_wikitext, tostring(mw.html.create('span'):attr('id', 'ws-wikipedia'):wikitext(args.wikipedia))) end if args.wikiquote then table.insert(microformat_wikitext, tostring(mw.html.create('span'):attr('id', 'ws-wikiquote'):wikitext(args.wikiquote))) end if args.commonscat then table.insert(microformat_wikitext, tostring(mw.html.create('span'):attr('id', 'ws-commons'):wikitext(args.commonscat))) elseif args.commons then table.insert(microformat_wikitext, tostring(mw.html.create('span'):attr('id', 'ws-commons'):wikitext('Category' .. args.commons))) end if args.description then table.insert(microformat_wikitext, tostring(mw.html.create('span'):attr('id', 'ws-description'):addClass('note'):wikitext(args.description))) end microformat:wikitext(table.concat(microformat_wikitext)) -- assemble local cats = '' if not args.nocat then cats = (args.categories or '') .. getCategories() end args.post_notes = image_display .. defaultsort_magicword .. cats .. tostring(microformat) args.wikidataswitch = true return mw.getCurrentFrame():extensionTag('templatestyles', '', {src = 'Template:Forfatter/styles.css'}) .. construct_header(args) end -- for testing function p._getCategories(args) args = normalize_args(args) p._author(args) return getCategories() end function p.getCategories(frame) return p._getCategories(getArgs(frame)) end function p._date(args) args = normalize_args(args) args.year_type = args.year_type or args['type'] or 'birth' return date(args) end function p.date(frame) return p._date(getArgs(frame)) end function p._lastInitial(args) args = normalize_args(args) return lastInitial(args) end function p.lastInitial(frame) return p._lastInitial(getArgs(frame)) end -- Debugging 1: mw.log(p._lastInitial({last_initial = 'Qx'})) -- Debugging 2: mw.log(p._lastInitial({wikidata = 'Q1107985'})) -- Debugging 1: mw.log(p._lastInitial({lastname = 'Qqxxx'})) -- Debugging 3: mw.log(p._lastInitial({last_initial = 'Qx', wikidata_id='Q1107985'})) -- used by [[Module:Person]] function p._dates(args) args = normalize_args(args) return dates(args) end function p.dates(frame) return p._dates(getArgs(frame)) end function p._get_image(args) args = normalize_args(args) if args.nocat then return get_image(args) else return get_image(args) .. getCategories() end end function p.get_image(frame) return p._get_image(getArgs(frame)) end function p._construct_defaultsort(args) args = normalize_args(args) return construct_defaultsort(args) end function p.construct_defaultsort(frame) return p._construct_defaultsort(getArgs(frame)) end -- Used by [[Module:Disambiguation]] and [[Template:Author]] function p._author(args) return author(args) end function p.author(frame) return p._author(getArgs(frame)) end return p 4b0se3swpssjt8flom8sjr8zf6tgjfs Modul:Header structure 828 125739 482571 2026-10-11T13:59:34Z Johshh 9757 Oprettede siden med "--[=[ This is a module to implement logic for header templates ]=] require('strict') local p = {} --p stands for package local getArgs = require('Module:Arguments').getArgs local plain_sister = require('Module:Plain sister')._plain_sister -- return true if any value in list is not nil or empty in args -- (nil means not present; empty string is not nil) local function has_any_arg(args, list) for k, v in pairs(list) do if args[v] ~= nil then return true end..." 482571 Scribunto text/plain --[=[ This is a module to implement logic for header templates ]=] require('strict') local p = {} --p stands for package local getArgs = require('Module:Arguments').getArgs local plain_sister = require('Module:Plain sister')._plain_sister -- return true if any value in list is not nil or empty in args -- (nil means not present; empty string is not nil) local function has_any_arg(args, list) for k, v in pairs(list) do if args[v] ~= nil then return true end end return false end --[=[ Construct the main block ]=] local function construct_main_block(args, prefix) -- header and tracking categories local main_div = mw.html.create('div') :addClass('wst-header-mainblock') :addClass(prefix .. '-mainblock') -- If an extra main class was provided, add it -- TODO: Is this used? Is it needed? if args.main_class ~= nil and args.main_class ~= "" then main_div:addClass(args.main_class) end -- "Previous" field local prev_div = main_div:tag('div') :addClass('wst-header-back') :addClass('searchaux') :addClass(prefix .. '-back') :tag('div'):addClass('wst-header-back-arrow'):wikitext('←') :done() :tag('div'):addClass('wst-header-back-link'):wikitext(args['previous']) :done() if args['previous'] == nil or args['previous'] == "" then prev_div:addClass('wst-header-nav-empty') end -- The central cell local center_div = main_div:tag('div') :addClass('wst-header-central-cell') :addClass(prefix .. '-central-cell') -- Special case to manage exceptional formatting in disambiguation-like -- pages; not otherwise documented local pretitle = '' if args.pretitle then local br = '<br/>' if not args.main_title or args.main_title == '' then br = '' end center_div:tag('span') :addClass('wst-header-pretitle') :wikitext(args.pretitle .. br) end center_div:tag('span') :addClass('wst-header-title') :addClass(prefix .. '-title') :wikitext(args.main_title or '') -- "Next" field local next_div = main_div:tag('div') :addClass('wst-header-forward') :addClass('searchaux') :addClass(prefix .. '-forward') :tag('div'):addClass('wst-header-forward-link'):wikitext(args['next']) :done() :tag('div'):addClass('wst-header-forward-arrow'):wikitext('→') :done() if args['next'] == nil or args['next'] == "" then next_div:addClass('wst-header-nav-empty') end return tostring(main_div) end --[=[ Construct the notes block ]=] local function construct_notes_block(args, prefix) local main_div = mw.html.create('div') :addClass('wst-header-notes') :addClass('header_notes') :addClass('searchaux') :addClass(prefix .. '-notes') -- If an extra main class was provided, add it -- TODO: Is this used? Is it needed? if args.notes_class ~= nil and args.notes_class ~= "" then main_div:addClass(args.notes_class) end -- Left-floated content has to come first, or it may float below the sisters. local notes_left_content = '' if args.notes_left_content then local notes_left_content_div = mw.html.create('div') :addClass('wst-header-left') :addClass('header_notes_left_content') :addClass(prefix .. '-left') :wikitext(args.notes_left_content) notes_left_content = tostring(notes_left_content_div) end local shortcut = '' if args.shortcut then shortcut = mw.getCurrentFrame():expandTemplate { title = 'shortcut', args = {args.shortcut} } end local notes_content = '' if args.notes then args.notes = mw.getCurrentFrame():preprocess(args.notes) -- linebreaks are so notes get paragraph formatting local notes_content_div = mw.html.create('div') :addClass('wst-header-content') :addClass('header_notes_content') :addClass('wst-header-notes-content') :addClass(prefix .. '-notes-content') :wikitext('\n' .. args.notes .. '\n') notes_content = tostring(notes_content_div) end local sister = plain_sister(args) if not sister and not args.notes and not args.notes_left_content then return '' end return tostring(main_div:wikitext(notes_left_content .. (sister or '') .. shortcut .. notes_content)) end --[=[ Construct header ]=] function p.construct_header(args) -- Make sure the main identifying class for the client template is set local prefix = "wst-unknown" if args.template ~= nil and args.template ~= "" then prefix = "wst-" .. args.template end local headerContainer = mw.html.create('div') :addClass("ws-header") :addClass("wst-header-structure") :addClass(prefix) -- header_class from client modules, class from individual uses if args.header_class then headerContainer:addClass(args.header_class) end if args.class then headerContainer:addClass(args.class) end headerContainer:wikitext(table.concat({ (args.pre_main or ''), construct_main_block(args, prefix), construct_notes_block(args, prefix), (args.post_notes or '') })) local stylesheet = mw.getCurrentFrame():extensionTag('templatestyles', '', {src = 'Header structure/styles.css'}) return stylesheet .. (args.pre_container or '') .. tostring(headerContainer) end function p.header_structure(frame) return p.construct_header(getArgs(frame)) end return p 971hsxfdvcp7ud5w4balnss3cmkboio Modul:Plain sister 828 125740 482572 2026-10-11T14:01:22Z Johshh 9757 Oprettede siden med "require('strict') local p = {} local getArgs = require('Module:Arguments').getArgs local yesno = require('Module:Yesno') local TableTools = require('Module:TableTools') local error_message = require('Module:Error')['error'] -- table of site data local sites = { -- interwiki prefix: parameter, label and site id (for Wikidata) ['w'] = {'wikipedia', 'Wikipedia article', 'enwiki'}, ['c'] = {'commons', 'Commons gallery', 'commonswiki'}, ['c:Category'] = {..." 482572 Scribunto text/plain require('strict') local p = {} local getArgs = require('Module:Arguments').getArgs local yesno = require('Module:Yesno') local TableTools = require('Module:TableTools') local error_message = require('Module:Error')['error'] -- table of site data local sites = { -- interwiki prefix: parameter, label and site id (for Wikidata) ['w'] = {'wikipedia', 'Wikipedia article', 'enwiki'}, ['c'] = {'commons', 'Commons gallery', 'commonswiki'}, ['c:Category'] = {'commonscat', 'Commons category', 'commonswiki'}, ['q'] = {'wikiquote', 'quotes', 'enwikiquote'}, ['wikt'] = {'wiktionary', 'definition', 'enwiktionary'}, ['b'] = {'wikibooks', 'textbook', 'enwikibooks'}, ['v'] = {'wikiversity', 'course', 'enwikiversity'}, ['wikispecies'] = {'wikispecies', 'taxonomy', 'specieswiki'}, ['voy'] = {'wikivoyage', 'travel guide', 'enwikivoyage'}, ['d'] = {'wikidata', 'Wikidata item', 'wikidatawiki'}, ['m'] = {'meta', 'Meta', 'metawiki'} } -- sites is display order (keyed as above) local sites_in_order = {'w', 'c', 'c:Category', 'q', 'wikt', 'b', 'v', 'wikispecies', 'voy', 'd', 'm'} -- some properties are not wanted from certain transitive links -- for example, the P921 (main topic) should not add the Commons category -- this is a map of WD property -> WD site ID keys local transitiveLinkBlacklist = { P921 = {'commonswiki', 'wikiquote', 'wiktionary', 'wikiversity', 'wikivoyage', 'meta'}, } -------------------------------------------------------------------------------- -- Get the item associated with the current page, or specified by the 'wikidata' -- parameter (of either the module invocation, or the parent template). -- @return mw.wikibase.entity local function getItem(args) local item = nil -- Firstly, see if the calling tempate or module has a 'wikidata' argument. if args.wikidata then item = mw.wikibase.getEntity(args.wikidata) end -- Failing that just use the current page's item. if item == nil then item = mw.wikibase.getEntity() end return item end -------------------------------------------------------------------------------- -- Get the page title of the first sitelink found on the target item for the -- given property. -- @return string|nil local function getFirstSitelink(item, property, sitename) local statements = item:getBestStatements(property) if #statements > 0 then -- Go through each 'edition of' statement. for _, statement in pairs(statements) do -- datavalue is missing if set to 'unknown value' if statement['mainsnak']['datatype'] == 'wikibase-item' and statement['mainsnak']['datavalue'] then local otherItemId = statement['mainsnak']['datavalue']['value']['id'] local sitelink = mw.wikibase.getSitelink(otherItemId, sitename) -- If the parent has the required sitelink, return it. if sitelink ~= '' and sitelink ~= nil then -- mw.log(sitename, property, sitelink) return sitelink end end -- if end end return nil end local function listContains(list, item) for _, v in pairs(list) do if v == item then return true end end return false end local function transitivePropertyBlacklisted(prop, wdSitelinkKey) -- reject prop/key pairs that we don't want local blacklisted = transitiveLinkBlacklist[prop] and listContains(transitiveLinkBlacklist[prop], wdSitelinkKey) return blacklisted end function p.getLinks(args) local item = getItem(args) local links = {} -- Build all the wikitext links. for prefix, site in pairs(sites) do local val = nil local wd_sitelink_key = site[3] local arg_name = site[1] -- Allow overriding of individual sitelinks. if args[arg_name] then val = args[arg_name] end if not val and wd_sitelink_key ~= '' and item then -- fetch it from wikidata val = item:getSitelink(wd_sitelink_key) if wd_sitelink_key == 'wikidatawiki' and item.id then val = item.id elseif wd_sitelink_key == 'commonswiki' and val then -- we have link to commons local catFlag = (#val>9 and string.sub(val, 1, 9) == 'Category:') if (arg_name == 'commonscat' and catFlag==false) or (arg_name=='commons' and catFlag==true) then val = nil -- link is to a wrong namespace so let's nuke it elseif (arg_name =='commonscat' and catFlag==true) then val = string.sub(val,10) -- trim 'Category:' from the front end end end -- Commons gallery. if not val and arg_name == 'commons' and item then local statements = item:getBestStatements('P935') -- get commons gallery page from P935 property if statements[1] and statements[1].mainsnak.datavalue then val = statements[1].mainsnak.datavalue.value end end -- Commons category. if not val and arg_name == 'commonscat' and item then local statements = item:getBestStatements('P373') -- get commons category page from P373 property if statements[1] and statements[1].mainsnak.datavalue then val = statements[1].mainsnak.datavalue.value end end -- edition or translation of (P629) -- category's main topic (P301) -- Wikimedia portal's main topic (P1204) -- main subject (P921) if item then for _,prop in pairs({ 'P629', 'P301', 'P1204', 'P921' }) do if not val and not transitivePropertyBlacklisted(prop, wd_sitelink_key) then local workSitelink = getFirstSitelink(item, prop, wd_sitelink_key) if workSitelink ~= nil then val = workSitelink break end end end end if val then links[prefix] = val end end -- tidy up redundancies in the WD data -- strip redundant commons category prefix if links['c:Category'] then links['c:Category'] = links['c:Category']:gsub('^Category:', '') end -- the gallery is exactly the same as the category, so just keep the category if links['c'] and links['c:Category'] and ('Category:' .. links['c:Category']) == links['c'] then links['c'] = nil end return links end -------- local function construct_sisicon_span(args) return mw.html.create('span') :addClass(args.class or 'sisicon') :wikitext('[[File:' .. args.image .. '|frameless|18px|link=' .. args.link .. '|alt=' .. args.alt .. ']]') end -- Get an HTML list of all links to all sister projects. function p._interprojectPart(args) local item = getItem(args) local link_data = p.getLinks(args) local links = {} -- iterate the links in the desired order and construct Wikitext links for k, v in pairs(sites_in_order) do if link_data[v] then local display = sites[v][2] local target = v .. ':' .. link_data[v] table.insert(links, '[[' .. target .. '|' .. display .. ']]') end end if #links == 0 then -- links table length is zero return nil end return mw.html.create('li') :addClass('sisitem') :node(construct_sisicon_span({ image = 'Wikimedia-logo.svg', link = 'Special:sitematrix', alt = 'Sister Projects' })) :wikitext('[[Special:sitematrix|sister projects]]: ' .. table.concat(links, ', ')) end function p.interprojectPart(frame) return p._interprojectPart(getArgs(frame)) end local function construct_related_links(sourceArgs, linkArgs, sisiconArgs) local links = {} for k, v in pairs(sourceArgs) do local key = string.gsub(string.gsub(string.gsub(string.gsub(k, ' ', ''), '_', ''), '-', ''), 's(%d*)$', '%1') if string.match(key, '^' .. linkArgs.param .. '%d*$') then local n = string.gsub(key, '^' .. linkArgs.param .. '(%d*)$', '%1') n = tonumber(n) or 1 if not links[n] then local items = mw.text.split(v, '%s*/%s*', false) local itemLinks = {} for _, item in pairs(items) do if item ~= '' then table.insert(itemLinks, '[[' .. linkArgs.nsPrefix .. item .. '|' .. item .. ']]') end end links[n] = table.concat(itemLinks, ', ') end end end links = TableTools.compressSparseArray(links) if #links == 0 then return nil end return mw.html.create('li') :addClass('sisitem') :node(construct_sisicon_span(sisiconArgs)) :wikitext(linkArgs.linkPrefix .. table.concat(links, ', ')) end function p._plain_sister(args) local current_frame = mw.getCurrentFrame() local current_title = mw.title.getCurrentTitle() local pagename = current_title.text local item = getItem(args) -- construct list local ul_list = mw.html.create('ul'):addClass('plainSister') if yesno(args.disambiguation) then local dabText = 'Search for titles ' .. tostring(mw.html.create('span'):addClass('selfreference'):wikitext('[[Special:Search/intitle:"' .. pagename .. '"|containing]]')) .. ' or ' if current_title:inNamespaces(14) then dabText = dabText .. '[[Special:Categories/' .. pagename .. '|beginning]]' elseif current_title:inNamespaces(0) then dabText = dabText .. '[[Special:PrefixIndex/' .. current_title.fullText .. '|beginning]]' else dabText = dabText .. '[[Special:PrefixIndex/' .. current_title.fullText .. '|beginning (in ' .. current_title.nsText .. 's)]]' end dabText = dabText .. ' with: "' .. pagename .. '"' ul_list:tag('li') :addClass('dabitem') :node(construct_sisicon_span({ image = 'Disambiguation.svg', link = 'WS:STYLE#Disambiguation, versions and translations pages', alt = 'Style Guide for disambiguation, version and translation pages', class = 'dabicon' })) :wikitext(dabText) end local edition_title = (args.textinfotitle and mw.title.new(args.textinfotitle)) or (yesno(args.textinfo or args.edition) and current_title) or nil local edition_title_talk = edition_title and edition_title.talkPageTitle local tracking_cats = {} if args.edition then table.insert(tracking_cats, '[[Category:' .. 'Plain sisters using edition parameter' .. ']]') end local textinfo_display if edition_title_talk and edition_title_talk.exists then textinfo_display = '[[' .. edition_title_talk.fullText .. '|information about this edition]]' elseif edition_title and not edition_title.exists then textinfo_display = error_message({'Textinfo page \"' .. edition_title.fullText .. '\" does not exist'}) table.insert(tracking_cats, '[[Category:' .. 'Plain sisters with nonexistent textinfo page' .. ']]') end if textinfo_display then ul_list:tag('li') :addClass('sisitem') :node(construct_sisicon_span({ image = 'Information icon.svg', link = 'Template:Textinfo', alt = 'Documentation for the TextInfo template', })) :wikitext(textinfo_display) end local portalLI = construct_related_links( args, { param = 'portal', nsPrefix = 'Portal:', linkPrefix = '[[Portal:Portals|related portals]]: ' }, { image = 'Wikisource-logo.svg', link = 'Portal:Portals', alt = 'Related Portals' } ) if portalLI then ul_list:node(portalLI) end local authorLI = construct_related_links( args, { param = 'relatedauthor', nsPrefix = 'Author:', linkPrefix = '[[Wikisource:Authors|related authors]]: ' }, { image = 'System-users.svg', link = 'Wikisource:Authors', alt = 'Related Authors' } ) if authorLI then ul_list:node(authorLI) end local workLI = construct_related_links( args, { param = 'relatedwork', nsPrefix = '', linkPrefix = '[[Wikisource:Works|related works]]: ' }, { image = 'Nuvola apps bookcase.svg', link = 'Wikisource:Works', alt = 'Related Works' } ) if workLI then ul_list:node(workLI) end local sisters = p._interprojectPart(args) if sisters then ul_list:node(sisters) end if yesno(args.wikidataswitch) and not item then ul_list:tag('li') :addClass('sisitem') :node(construct_sisicon_span({ image = 'Wikidata-logo.svg', link = 'Wikisource:Wikidata', alt = 'Wikidata', })) :wikitext('[[d:Special:Search/' .. pagename .. '|Search Wikidata]]') end if not yesno(args.disambiguation) and not textinfo_display and not portalLI and not authorLI and not workLI and not sisters and not yesno(args.wikidataswitch) then return nil end return current_frame:extensionTag('templatestyles', '', {src = 'Plain sister/styles.css'}) .. tostring(ul_list) .. table.concat(tracking_cats) end function p.plain_sister(frame) return p._plain_sister(getArgs(frame)) end return p -- Debug console testing: -- =p.interprojectPart(mw.getCurrentFrame():newChild{title='nop',args={wikidata='Q23308118'}}) 16utzs5483yiwu414fx07ueypib5gy9 482580 482572 2026-10-11T14:16:11Z Johshh 9757 482580 Scribunto text/plain require('strict') local p = {} local getArgs = require('Module:Arguments').getArgs local yesno = require('Module:Yesno') local TableTools = require('Module:TableTools') local error_message = require('Module:Error')['error'] -- table of site data local sites = { -- interwiki prefix: parameter, label and site id (for Wikidata) ['w'] = {'wikipedia', 'Wikipedia article', 'enwiki'}, ['c'] = {'commons', 'Commons gallery', 'commonswiki'}, ['c:Category'] = {'commonscat', 'Commons category', 'commonswiki'}, ['q'] = {'wikiquote', 'quotes', 'enwikiquote'}, ['wikt'] = {'wiktionary', 'definition', 'enwiktionary'}, ['b'] = {'wikibooks', 'textbook', 'enwikibooks'}, ['v'] = {'wikiversity', 'course', 'enwikiversity'}, ['wikispecies'] = {'wikispecies', 'taxonomy', 'specieswiki'}, ['voy'] = {'wikivoyage', 'travel guide', 'enwikivoyage'}, ['d'] = {'wikidata', 'Wikidata item', 'wikidatawiki'}, ['m'] = {'meta', 'Meta', 'metawiki'} } -- sites is display order (keyed as above) local sites_in_order = {'w', 'c', 'c:Category', 'q', 'wikt', 'b', 'v', 'wikispecies', 'voy', 'd', 'm'} -- some properties are not wanted from certain transitive links -- for example, the P921 (main topic) should not add the Commons category -- this is a map of WD property -> WD site ID keys local transitiveLinkBlacklist = { P921 = {'commonswiki', 'wikiquote', 'wiktionary', 'wikiversity', 'wikivoyage', 'meta'}, } -------------------------------------------------------------------------------- -- Get the item associated with the current page, or specified by the 'wikidata' -- parameter (of either the module invocation, or the parent template). -- @return mw.wikibase.entity local function getItem(args) local item = nil -- Firstly, see if the calling tempate or module has a 'wikidata' argument. if args.wikidata then item = mw.wikibase.getEntity(args.wikidata) end -- Failing that just use the current page's item. if item == nil then item = mw.wikibase.getEntity() end return item end -------------------------------------------------------------------------------- -- Get the page title of the first sitelink found on the target item for the -- given property. -- @return string|nil local function getFirstSitelink(item, property, sitename) local statements = item:getBestStatements(property) if #statements > 0 then -- Go through each 'edition of' statement. for _, statement in pairs(statements) do -- datavalue is missing if set to 'unknown value' if statement['mainsnak']['datatype'] == 'wikibase-item' and statement['mainsnak']['datavalue'] then local otherItemId = statement['mainsnak']['datavalue']['value']['id'] local sitelink = mw.wikibase.getSitelink(otherItemId, sitename) -- If the parent has the required sitelink, return it. if sitelink ~= '' and sitelink ~= nil then -- mw.log(sitename, property, sitelink) return sitelink end end -- if end end return nil end local function listContains(list, item) for _, v in pairs(list) do if v == item then return true end end return false end local function transitivePropertyBlacklisted(prop, wdSitelinkKey) -- reject prop/key pairs that we don't want local blacklisted = transitiveLinkBlacklist[prop] and listContains(transitiveLinkBlacklist[prop], wdSitelinkKey) return blacklisted end function p.getLinks(args) local item = getItem(args) local links = {} -- Build all the wikitext links. for prefix, site in pairs(sites) do local val = nil local wd_sitelink_key = site[3] local arg_name = site[1] -- Allow overriding of individual sitelinks. if args[arg_name] then val = args[arg_name] end if not val and wd_sitelink_key ~= '' and item then -- fetch it from wikidata val = item:getSitelink(wd_sitelink_key) if wd_sitelink_key == 'wikidatawiki' and item.id then val = item.id elseif wd_sitelink_key == 'commonswiki' and val then -- we have link to commons local catFlag = (#val>9 and string.sub(val, 1, 9) == 'Category:') if (arg_name == 'commonscat' and catFlag==false) or (arg_name=='commons' and catFlag==true) then val = nil -- link is to a wrong namespace so let's nuke it elseif (arg_name =='commonscat' and catFlag==true) then val = string.sub(val,10) -- trim 'Category:' from the front end end end -- Commons gallery. if not val and arg_name == 'commons' and item then local statements = item:getBestStatements('P935') -- get commons gallery page from P935 property if statements[1] and statements[1].mainsnak.datavalue then val = statements[1].mainsnak.datavalue.value end end -- Commons category. if not val and arg_name == 'commonscat' and item then local statements = item:getBestStatements('P373') -- get commons category page from P373 property if statements[1] and statements[1].mainsnak.datavalue then val = statements[1].mainsnak.datavalue.value end end -- edition or translation of (P629) -- category's main topic (P301) -- Wikimedia portal's main topic (P1204) -- main subject (P921) if item then for _,prop in pairs({ 'P629', 'P301', 'P1204', 'P921' }) do if not val and not transitivePropertyBlacklisted(prop, wd_sitelink_key) then local workSitelink = getFirstSitelink(item, prop, wd_sitelink_key) if workSitelink ~= nil then val = workSitelink break end end end end if val then links[prefix] = val end end -- tidy up redundancies in the WD data -- strip redundant commons category prefix if links['c:Category'] then links['c:Category'] = links['c:Category']:gsub('^Category:', '') end -- the gallery is exactly the same as the category, so just keep the category if links['c'] and links['c:Category'] and ('Category:' .. links['c:Category']) == links['c'] then links['c'] = nil end return links end -------- local function construct_sisicon_span(args) return mw.html.create('span') :addClass(args.class or 'sisicon') :wikitext('[[File:' .. args.image .. '|frameless|18px|link=' .. args.link .. '|alt=' .. args.alt .. ']]') end -- Get an HTML list of all links to all sister projects. function p._interprojectPart(args) local item = getItem(args) local link_data = p.getLinks(args) local links = {} -- iterate the links in the desired order and construct Wikitext links for k, v in pairs(sites_in_order) do if link_data[v] then local display = sites[v][2] local target = v .. ':' .. link_data[v] table.insert(links, '[[' .. target .. '|' .. display .. ']]') end end if #links == 0 then -- links table length is zero return nil end return mw.html.create('li') :addClass('sisitem') :node(construct_sisicon_span({ image = 'Wikimedia-logo.svg', link = 'Special:sitematrix', alt = 'Søsterprojekter' })) :wikitext('[[Special:sitematrix|søsterprojekter]]: ' .. table.concat(links, ', ')) end function p.interprojectPart(frame) return p._interprojectPart(getArgs(frame)) end local function construct_related_links(sourceArgs, linkArgs, sisiconArgs) local links = {} for k, v in pairs(sourceArgs) do local key = string.gsub(string.gsub(string.gsub(string.gsub(k, ' ', ''), '_', ''), '-', ''), 's(%d*)$', '%1') if string.match(key, '^' .. linkArgs.param .. '%d*$') then local n = string.gsub(key, '^' .. linkArgs.param .. '(%d*)$', '%1') n = tonumber(n) or 1 if not links[n] then local items = mw.text.split(v, '%s*/%s*', false) local itemLinks = {} for _, item in pairs(items) do if item ~= '' then table.insert(itemLinks, '[[' .. linkArgs.nsPrefix .. item .. '|' .. item .. ']]') end end links[n] = table.concat(itemLinks, ', ') end end end links = TableTools.compressSparseArray(links) if #links == 0 then return nil end return mw.html.create('li') :addClass('sisitem') :node(construct_sisicon_span(sisiconArgs)) :wikitext(linkArgs.linkPrefix .. table.concat(links, ', ')) end function p._plain_sister(args) local current_frame = mw.getCurrentFrame() local current_title = mw.title.getCurrentTitle() local pagename = current_title.text local item = getItem(args) -- construct list local ul_list = mw.html.create('ul'):addClass('plainSister') if yesno(args.disambiguation) then local dabText = 'Search for titles ' .. tostring(mw.html.create('span'):addClass('selfreference'):wikitext('[[Special:Search/intitle:"' .. pagename .. '"|containing]]')) .. ' or ' if current_title:inNamespaces(14) then dabText = dabText .. '[[Special:Categories/' .. pagename .. '|beginning]]' elseif current_title:inNamespaces(0) then dabText = dabText .. '[[Special:PrefixIndex/' .. current_title.fullText .. '|beginning]]' else dabText = dabText .. '[[Special:PrefixIndex/' .. current_title.fullText .. '|beginning (in ' .. current_title.nsText .. 's)]]' end dabText = dabText .. ' with: "' .. pagename .. '"' ul_list:tag('li') :addClass('dabitem') :node(construct_sisicon_span({ image = 'Disambiguation.svg', link = 'WS:STYLE#Disambiguation, versions and translations pages', alt = 'Style Guide for disambiguation, version and translation pages', class = 'dabicon' })) :wikitext(dabText) end local edition_title = (args.textinfotitle and mw.title.new(args.textinfotitle)) or (yesno(args.textinfo or args.edition) and current_title) or nil local edition_title_talk = edition_title and edition_title.talkPageTitle local tracking_cats = {} if args.edition then table.insert(tracking_cats, '[[Category:' .. 'Plain sisters using edition parameter' .. ']]') end local textinfo_display if edition_title_talk and edition_title_talk.exists then textinfo_display = '[[' .. edition_title_talk.fullText .. '|information about this edition]]' elseif edition_title and not edition_title.exists then textinfo_display = error_message({'Textinfo page \"' .. edition_title.fullText .. '\" does not exist'}) table.insert(tracking_cats, '[[Category:' .. 'Plain sisters with nonexistent textinfo page' .. ']]') end if textinfo_display then ul_list:tag('li') :addClass('sisitem') :node(construct_sisicon_span({ image = 'Information icon.svg', link = 'Template:Textinfo', alt = 'Documentation for the TextInfo template', })) :wikitext(textinfo_display) end local portalLI = construct_related_links( args, { param = 'portal', nsPrefix = 'Portal:', linkPrefix = '[[Portal:Portals|related portals]]: ' }, { image = 'Wikisource-logo.svg', link = 'Portal:Portals', alt = 'Related Portals' } ) if portalLI then ul_list:node(portalLI) end local authorLI = construct_related_links( args, { param = 'relatedauthor', nsPrefix = 'Author:', linkPrefix = '[[Wikisource:Authors|related authors]]: ' }, { image = 'System-users.svg', link = 'Wikisource:Authors', alt = 'Related Authors' } ) if authorLI then ul_list:node(authorLI) end local workLI = construct_related_links( args, { param = 'relatedwork', nsPrefix = '', linkPrefix = '[[Wikisource:Works|related works]]: ' }, { image = 'Nuvola apps bookcase.svg', link = 'Wikisource:Works', alt = 'Related Works' } ) if workLI then ul_list:node(workLI) end local sisters = p._interprojectPart(args) if sisters then ul_list:node(sisters) end if yesno(args.wikidataswitch) and not item then ul_list:tag('li') :addClass('sisitem') :node(construct_sisicon_span({ image = 'Wikidata-logo.svg', link = 'Wikisource:Wikidata', alt = 'Wikidata', })) :wikitext('[[d:Special:Search/' .. pagename .. '|Search Wikidata]]') end if not yesno(args.disambiguation) and not textinfo_display and not portalLI and not authorLI and not workLI and not sisters and not yesno(args.wikidataswitch) then return nil end return current_frame:extensionTag('templatestyles', '', {src = 'Plain sister/styles.css'}) .. tostring(ul_list) .. table.concat(tracking_cats) end function p.plain_sister(frame) return p._plain_sister(getArgs(frame)) end return p -- Debug console testing: -- =p.interprojectPart(mw.getCurrentFrame():newChild{title='nop',args={wikidata='Q23308118'}}) gzjhctfdgjv7xcps3yoqemrbbacu7bu 482581 482580 2026-10-11T14:17:27Z Johshh 9757 482581 Scribunto text/plain require('strict') local p = {} local getArgs = require('Module:Arguments').getArgs local yesno = require('Module:Yesno') local TableTools = require('Module:TableTools') local error_message = require('Module:Error')['error'] -- table of site data local sites = { -- interwiki prefix: parameter, label and site id (for Wikidata) ['w'] = {'wikipedia', 'Wikipedia-artikel', 'dawiki'}, ['c'] = {'commons', 'Commons gallery', 'commonswiki'}, ['c:Category'] = {'commonscat', 'Commons category', 'commonswiki'}, ['q'] = {'wikiquote', 'quotes', 'enwikiquote'}, ['wikt'] = {'wiktionary', 'definition', 'enwiktionary'}, ['b'] = {'wikibooks', 'textbook', 'enwikibooks'}, ['v'] = {'wikiversity', 'course', 'enwikiversity'}, ['wikispecies'] = {'wikispecies', 'taxonomy', 'specieswiki'}, ['voy'] = {'wikivoyage', 'travel guide', 'enwikivoyage'}, ['d'] = {'wikidata', 'Wikidata item', 'wikidatawiki'}, ['m'] = {'meta', 'Meta', 'metawiki'} } -- sites is display order (keyed as above) local sites_in_order = {'w', 'c', 'c:Category', 'q', 'wikt', 'b', 'v', 'wikispecies', 'voy', 'd', 'm'} -- some properties are not wanted from certain transitive links -- for example, the P921 (main topic) should not add the Commons category -- this is a map of WD property -> WD site ID keys local transitiveLinkBlacklist = { P921 = {'commonswiki', 'wikiquote', 'wiktionary', 'wikiversity', 'wikivoyage', 'meta'}, } -------------------------------------------------------------------------------- -- Get the item associated with the current page, or specified by the 'wikidata' -- parameter (of either the module invocation, or the parent template). -- @return mw.wikibase.entity local function getItem(args) local item = nil -- Firstly, see if the calling tempate or module has a 'wikidata' argument. if args.wikidata then item = mw.wikibase.getEntity(args.wikidata) end -- Failing that just use the current page's item. if item == nil then item = mw.wikibase.getEntity() end return item end -------------------------------------------------------------------------------- -- Get the page title of the first sitelink found on the target item for the -- given property. -- @return string|nil local function getFirstSitelink(item, property, sitename) local statements = item:getBestStatements(property) if #statements > 0 then -- Go through each 'edition of' statement. for _, statement in pairs(statements) do -- datavalue is missing if set to 'unknown value' if statement['mainsnak']['datatype'] == 'wikibase-item' and statement['mainsnak']['datavalue'] then local otherItemId = statement['mainsnak']['datavalue']['value']['id'] local sitelink = mw.wikibase.getSitelink(otherItemId, sitename) -- If the parent has the required sitelink, return it. if sitelink ~= '' and sitelink ~= nil then -- mw.log(sitename, property, sitelink) return sitelink end end -- if end end return nil end local function listContains(list, item) for _, v in pairs(list) do if v == item then return true end end return false end local function transitivePropertyBlacklisted(prop, wdSitelinkKey) -- reject prop/key pairs that we don't want local blacklisted = transitiveLinkBlacklist[prop] and listContains(transitiveLinkBlacklist[prop], wdSitelinkKey) return blacklisted end function p.getLinks(args) local item = getItem(args) local links = {} -- Build all the wikitext links. for prefix, site in pairs(sites) do local val = nil local wd_sitelink_key = site[3] local arg_name = site[1] -- Allow overriding of individual sitelinks. if args[arg_name] then val = args[arg_name] end if not val and wd_sitelink_key ~= '' and item then -- fetch it from wikidata val = item:getSitelink(wd_sitelink_key) if wd_sitelink_key == 'wikidatawiki' and item.id then val = item.id elseif wd_sitelink_key == 'commonswiki' and val then -- we have link to commons local catFlag = (#val>9 and string.sub(val, 1, 9) == 'Category:') if (arg_name == 'commonscat' and catFlag==false) or (arg_name=='commons' and catFlag==true) then val = nil -- link is to a wrong namespace so let's nuke it elseif (arg_name =='commonscat' and catFlag==true) then val = string.sub(val,10) -- trim 'Category:' from the front end end end -- Commons gallery. if not val and arg_name == 'commons' and item then local statements = item:getBestStatements('P935') -- get commons gallery page from P935 property if statements[1] and statements[1].mainsnak.datavalue then val = statements[1].mainsnak.datavalue.value end end -- Commons category. if not val and arg_name == 'commonscat' and item then local statements = item:getBestStatements('P373') -- get commons category page from P373 property if statements[1] and statements[1].mainsnak.datavalue then val = statements[1].mainsnak.datavalue.value end end -- edition or translation of (P629) -- category's main topic (P301) -- Wikimedia portal's main topic (P1204) -- main subject (P921) if item then for _,prop in pairs({ 'P629', 'P301', 'P1204', 'P921' }) do if not val and not transitivePropertyBlacklisted(prop, wd_sitelink_key) then local workSitelink = getFirstSitelink(item, prop, wd_sitelink_key) if workSitelink ~= nil then val = workSitelink break end end end end if val then links[prefix] = val end end -- tidy up redundancies in the WD data -- strip redundant commons category prefix if links['c:Category'] then links['c:Category'] = links['c:Category']:gsub('^Category:', '') end -- the gallery is exactly the same as the category, so just keep the category if links['c'] and links['c:Category'] and ('Category:' .. links['c:Category']) == links['c'] then links['c'] = nil end return links end -------- local function construct_sisicon_span(args) return mw.html.create('span') :addClass(args.class or 'sisicon') :wikitext('[[File:' .. args.image .. '|frameless|18px|link=' .. args.link .. '|alt=' .. args.alt .. ']]') end -- Get an HTML list of all links to all sister projects. function p._interprojectPart(args) local item = getItem(args) local link_data = p.getLinks(args) local links = {} -- iterate the links in the desired order and construct Wikitext links for k, v in pairs(sites_in_order) do if link_data[v] then local display = sites[v][2] local target = v .. ':' .. link_data[v] table.insert(links, '[[' .. target .. '|' .. display .. ']]') end end if #links == 0 then -- links table length is zero return nil end return mw.html.create('li') :addClass('sisitem') :node(construct_sisicon_span({ image = 'Wikimedia-logo.svg', link = 'Special:sitematrix', alt = 'Søsterprojekter' })) :wikitext('[[Special:sitematrix|søsterprojekter]]: ' .. table.concat(links, ', ')) end function p.interprojectPart(frame) return p._interprojectPart(getArgs(frame)) end local function construct_related_links(sourceArgs, linkArgs, sisiconArgs) local links = {} for k, v in pairs(sourceArgs) do local key = string.gsub(string.gsub(string.gsub(string.gsub(k, ' ', ''), '_', ''), '-', ''), 's(%d*)$', '%1') if string.match(key, '^' .. linkArgs.param .. '%d*$') then local n = string.gsub(key, '^' .. linkArgs.param .. '(%d*)$', '%1') n = tonumber(n) or 1 if not links[n] then local items = mw.text.split(v, '%s*/%s*', false) local itemLinks = {} for _, item in pairs(items) do if item ~= '' then table.insert(itemLinks, '[[' .. linkArgs.nsPrefix .. item .. '|' .. item .. ']]') end end links[n] = table.concat(itemLinks, ', ') end end end links = TableTools.compressSparseArray(links) if #links == 0 then return nil end return mw.html.create('li') :addClass('sisitem') :node(construct_sisicon_span(sisiconArgs)) :wikitext(linkArgs.linkPrefix .. table.concat(links, ', ')) end function p._plain_sister(args) local current_frame = mw.getCurrentFrame() local current_title = mw.title.getCurrentTitle() local pagename = current_title.text local item = getItem(args) -- construct list local ul_list = mw.html.create('ul'):addClass('plainSister') if yesno(args.disambiguation) then local dabText = 'Search for titles ' .. tostring(mw.html.create('span'):addClass('selfreference'):wikitext('[[Special:Search/intitle:"' .. pagename .. '"|containing]]')) .. ' or ' if current_title:inNamespaces(14) then dabText = dabText .. '[[Special:Categories/' .. pagename .. '|beginning]]' elseif current_title:inNamespaces(0) then dabText = dabText .. '[[Special:PrefixIndex/' .. current_title.fullText .. '|beginning]]' else dabText = dabText .. '[[Special:PrefixIndex/' .. current_title.fullText .. '|beginning (in ' .. current_title.nsText .. 's)]]' end dabText = dabText .. ' with: "' .. pagename .. '"' ul_list:tag('li') :addClass('dabitem') :node(construct_sisicon_span({ image = 'Disambiguation.svg', link = 'WS:STYLE#Disambiguation, versions and translations pages', alt = 'Style Guide for disambiguation, version and translation pages', class = 'dabicon' })) :wikitext(dabText) end local edition_title = (args.textinfotitle and mw.title.new(args.textinfotitle)) or (yesno(args.textinfo or args.edition) and current_title) or nil local edition_title_talk = edition_title and edition_title.talkPageTitle local tracking_cats = {} if args.edition then table.insert(tracking_cats, '[[Category:' .. 'Plain sisters using edition parameter' .. ']]') end local textinfo_display if edition_title_talk and edition_title_talk.exists then textinfo_display = '[[' .. edition_title_talk.fullText .. '|information about this edition]]' elseif edition_title and not edition_title.exists then textinfo_display = error_message({'Textinfo page \"' .. edition_title.fullText .. '\" does not exist'}) table.insert(tracking_cats, '[[Category:' .. 'Plain sisters with nonexistent textinfo page' .. ']]') end if textinfo_display then ul_list:tag('li') :addClass('sisitem') :node(construct_sisicon_span({ image = 'Information icon.svg', link = 'Template:Textinfo', alt = 'Documentation for the TextInfo template', })) :wikitext(textinfo_display) end local portalLI = construct_related_links( args, { param = 'portal', nsPrefix = 'Portal:', linkPrefix = '[[Portal:Portals|related portals]]: ' }, { image = 'Wikisource-logo.svg', link = 'Portal:Portals', alt = 'Related Portals' } ) if portalLI then ul_list:node(portalLI) end local authorLI = construct_related_links( args, { param = 'relatedauthor', nsPrefix = 'Author:', linkPrefix = '[[Wikisource:Authors|related authors]]: ' }, { image = 'System-users.svg', link = 'Wikisource:Authors', alt = 'Related Authors' } ) if authorLI then ul_list:node(authorLI) end local workLI = construct_related_links( args, { param = 'relatedwork', nsPrefix = '', linkPrefix = '[[Wikisource:Works|related works]]: ' }, { image = 'Nuvola apps bookcase.svg', link = 'Wikisource:Works', alt = 'Related Works' } ) if workLI then ul_list:node(workLI) end local sisters = p._interprojectPart(args) if sisters then ul_list:node(sisters) end if yesno(args.wikidataswitch) and not item then ul_list:tag('li') :addClass('sisitem') :node(construct_sisicon_span({ image = 'Wikidata-logo.svg', link = 'Wikisource:Wikidata', alt = 'Wikidata', })) :wikitext('[[d:Special:Search/' .. pagename .. '|Search Wikidata]]') end if not yesno(args.disambiguation) and not textinfo_display and not portalLI and not authorLI and not workLI and not sisters and not yesno(args.wikidataswitch) then return nil end return current_frame:extensionTag('templatestyles', '', {src = 'Plain sister/styles.css'}) .. tostring(ul_list) .. table.concat(tracking_cats) end function p.plain_sister(frame) return p._plain_sister(getArgs(frame)) end return p -- Debug console testing: -- =p.interprojectPart(mw.getCurrentFrame():newChild{title='nop',args={wikidata='Q23308118'}}) okpd9mlsx43xkyrvjhd9j6ya76reqpe Modul:Era 828 125741 482573 2026-10-11T14:02:03Z Johshh 9757 Oprettede siden med "--[[ Get the name of an era, based on Wikisource's definition. This implements the logic of Template:What era is --]] require('strict') local getArgs = require('Module:Arguments').getArgs local p = {} function p.main(frame) local args = getArgs(frame, { wrappers = { 'Template:What era is', } }) return p.era(args[1]) end function p.era(year) -- Nil years need to trigger bailout before we do anything else. if year == nil then return 'Unknown era' en..." 482573 Scribunto text/plain --[[ Get the name of an era, based on Wikisource's definition. This implements the logic of Template:What era is --]] require('strict') local getArgs = require('Module:Arguments').getArgs local p = {} function p.main(frame) local args = getArgs(frame, { wrappers = { 'Template:What era is', } }) return p.era(args[1]) end function p.era(year) -- Nil years need to trigger bailout before we do anything else. if year == nil then return 'Unknown era' end --[[ The template (What era is) treated every year that failed to parse as "Ancient", and years given as "BCE" fell into this category. With the module logic this no loonger works, so we need to treat BCE years as negative instead, so the numeric logic can deal wiith them. --]] if mw.ustring.match(year, ' BCE$') ~= nil then year = mw.ustring.gsub(year, ' BCE$', '') -- Strip the "BCE" year = '-' .. year -- And prepend a minus (we tonumber() it later) end -- Unknown value. if tonumber(year) == nil or mw.ustring.lower(year) == 'unknown' or year == '?' then return 'Unknown era' end -- Handle numeric years. year = tonumber(year) local today = tonumber(os.date('%Y')) if year <= 600 then return 'Ancient' elseif year <= 1420 then return 'Medieval' elseif year <= 1630 then return 'Renaissance' elseif year <= 1900 then return 'Early modern' elseif year <= today then return 'Modern' else return 'Future' end end return p bfmpf98v2j1nr4x6v43qbycl5n6hw6b Modul:Ordinal 828 125742 482574 2026-10-11T14:02:36Z Johshh 9757 Oprettede siden med "--[[ This template will add the appropriate ordinal suffix to a given integer. Please do not modify this code without applying the changes first at Module:Ordinal/sandbox and testing. ]] local p = {} local yesno = require('Module:Yesno') -- boolean value interpretation --[[ This function converts an integer value into a numeral followed by ordinal indicator. The output string might contain HTML tags. Usage: {{#invoke:Ordinal|ordinal|1=|2=|sup=}} {{#inv..." 482574 Scribunto text/plain --[[ This template will add the appropriate ordinal suffix to a given integer. Please do not modify this code without applying the changes first at Module:Ordinal/sandbox and testing. ]] local p = {} local yesno = require('Module:Yesno') -- boolean value interpretation --[[ This function converts an integer value into a numeral followed by ordinal indicator. The output string might contain HTML tags. Usage: {{#invoke:Ordinal|ordinal|1=|2=|sup=}} {{#invoke:Ordinal|ordinal}} - uses the caller's parameters Parameters 1: Any number or string. 2: Set to "d" if the module should display "d" instead of "nd" and "rd". sup: Set to yes/no to toggle superscript ordinal suffix. ]] function p.ordinal(frame) local args = frame.args if args[1] == nil then args = frame:getParent().args end if args[1] == nil then args[1] = "{{{1}}}" end return p._ordinal(args[1], (args[2] == 'd'), yesno(args.sup)) end function p._ordinal(n, d, sup) local x = tonumber(mw.ustring.match(n, "(%d*)%W*$")) local suffix = "th" -- If tonumber(n) worked: if x then local mod10 = math.abs(x) % 10 local mod100 = math.abs(x) % 100 if mod10 == 1 and mod100 ~= 11 then suffix = "st" elseif mod10 == 2 and mod100 ~= 12 then if d then suffix = "d" else suffix = "nd" end elseif mod10 == 3 and mod100 ~= 13 then if d then suffix = "d" else suffix = "rd" end end end if sup then suffix = "<sup>" .. suffix .. "</sup>" end return n .. suffix end return p azbrsdhoe8ec6qvwgy7myjj7iz9onjy Modul:Author/data 828 125743 482575 2026-10-11T14:03:27Z Johshh 9757 Oprettede siden med "return { categories = { nationalities = { Q889 = 'Afghan authors', Q222 = 'Albanian authors', Q262 = 'Algerian authors', Q414 = 'Argentine authors', Q399 = 'Armenian authors', Q408 = 'Australian authors', Q40 = 'Austrian authors', Q131964 = 'Austrian authors', -- Austrian Empire Q699964 = 'Austrian authors', -- Archduchy of Austria Q227 = 'Azerbaijani authors', Q31 = 'Belgian authors', Q161885 = 'British authors', -- 1707-1801..." 482575 Scribunto text/plain return { categories = { nationalities = { Q889 = 'Afghan authors', Q222 = 'Albanian authors', Q262 = 'Algerian authors', Q414 = 'Argentine authors', Q399 = 'Armenian authors', Q408 = 'Australian authors', Q40 = 'Austrian authors', Q131964 = 'Austrian authors', -- Austrian Empire Q699964 = 'Austrian authors', -- Archduchy of Austria Q227 = 'Azerbaijani authors', Q31 = 'Belgian authors', Q161885 = 'British authors', -- 1707-1801 Q174193 = 'British authors', -- until 1927 Q179876 = 'English authors', -- to 1707 Q21 = 'English authors', Q23148 = 'Cornish authors', Q9676 = 'Manx authors', Q230791 = 'Scottish authors', Q22 = 'Scottish authors', Q26 = 'Northern Irish authors', Q25 = 'Welsh authors', Q785 = 'Jersey authors', Q25230 = 'Guernsey authors', Q145 = 'United Kingdom authors', Q27 = 'Irish authors', Q215530 = 'Irish authors', -- Kingdom of Ireland Q31747 = 'Irish authors', --Irish Free State Q398 = 'Bahraini authors', Q902 = 'Bangladeshi authors', Q244 = 'Barbadian authors', Q184 = 'Belarusian authors', Q750 = 'Bolivian authors', Q155 = 'Brazilian authors', Q219 = 'Bulgarian authors', Q424 = 'Cambodian authors', Q16 = 'Canadian authors', Q298 = 'Chilean authors', Q148 = 'Chinese authors', Q8646 = 'Hong Kong authors', Q13426199 = 'Republic of China authors', Q739 = 'Colombian authors', Q224 = 'Croatian authors', Q241 = 'Cuban authors', Q213 = 'Czech authors', Q33946 = 'Czechoslovakian authors', Q140359 = 'Czechoslovakian authors', Q2010024 = 'Czechoslovakian authors', Q2454585 = 'Czechoslovakian authors', Q11178782 = 'Czechoslovakian authors', Q853348 = 'Czechoslovakian authors', Q1998866 = 'Czechoslovakian authors', Q43266 = 'Moravian authors', Q35 = 'Danish authors', Q4628 = 'Faroese authors', Q55 = 'Dutch authors', Q29999 = 'Dutch authors', -- Kingdom of the Netherlands Q574 = 'East Timorese authors', Q79 = 'Egyptian authors', Q191 = 'Estonian authors', Q115 = 'Ethiopian authors', Q712 = 'Fijian authors', Q928 = 'Filipino authors', Q33 = 'Finnish authors', Q142 = 'French authors', Q70972 = 'French authors', -- Kingdom of France Q58296 = 'French authors', -- French First Republic Q58326 = 'French authors', -- French Second Republic Q70802 = 'French authors', -- French Third Republic Q842091 = 'Norman authors', -- Duchy of Normandy Q230 = 'Georgian authors', Q183 = 'German authors', Q1206012 = 'German authors', -- 1930s-1940s Q43287 = 'German authors', -- German Empire Q156199 = 'German authors', -- Electorate of Saxony Q151624 = 'German authors', -- German Confederation Q20135 = 'German authors', -- Grand Duchy of Hesse Q159631 = 'German authors', -- Kingdom of Wurttemberg Q38872 = 'Prussian authors', Q27306 = 'Prussian authors', -- Kingdom of Prussia Q117 = 'Ghanaian authors', Q41 = 'Greek authors', Q11772 = 'Greek authors', Q734 = 'Guyanese authors', Q790 = 'Haitian authors', Q28 = 'Hungarian authors', Q28513 = 'Austro-Hungarian authors', Q533534 = 'Austro-Hungarian authors', -- Cisleithania, could also be Czech Q1879239 = 'Austro-Hungarian authors', Q12548 = 'Holy Roman Empire authors', Q189 = 'Icelandic authors', Q668 = 'Indian authors', Q252 = 'Indonesian authors', Q794 = 'Iranian authors', Q796 = 'Iraqi authors', Q149805 = 'Iraqi authors', Q3041595 = 'Iraqi authors', Q3108185 = 'Iraqi authors', Q3746183 = 'Persian authors', -- Persis Q3708094 = 'Persian authors', -- Seljuk empire Q7418448 = 'Persian authors', -- Eldiguzid state Q18234383 = 'Persian authors', -- Safavid Empire Q63158027 = 'Persian authors', -- Qajar Iran Q484195 = 'Persian authors', -- Timurid Empire Q12536 = 'Persian authors', -- Abbasid Caliphate Q5684 = 'Babylonian authors', Q801 = 'Israeli authors', Q38 = 'Italian authors', Q172579 = 'Italian authors', -- Kingdom of Italy Q223936 = 'Italian authors', -- Kingdom of Italy, v. 2 Q173065 = 'Italian authors', -- Kingdom of Naples Q170174 = 'Papal States authors', Q1747689 = 'Ancient Roman authors', Q766 = 'Jamaican authors', Q17 = 'Japanese authors', Q810 = 'Jordanian authors', Q822 = 'Lebanese authors', Q32 = 'Luxembourgian authors', Q232 = 'Kazakh authors', Q114 = 'Kenyan authors', Q2090473 = 'Khazar authors', Q18097 = 'Korean authors', Q864 = 'South Korean authors', Q1014 = 'Liberian authors', Q1016 = 'Libyan authors', Q37 = 'Lithuanian authors', Q83958 = 'Macedonian authors', Q833 = 'Malaysian authors', Q96 = 'Mexican authors', Q711 = 'Mongolian authors', Q236 = 'Montenegrin authors', Q1028 = 'Moroccan authors', Q837 = 'Nepalese authors', Q1030 = 'Namibian authors', Q664 = 'New Zealand authors', Q811 = 'Nicaraguan authors', Q1033 = 'Nigerian authors', Q20 = 'Norwegian authors', Q219060 = 'Palestinian authors', Q843 = 'Pakistani authors', Q419 = 'Peruvian authors', Q36 = 'Polish authors', Q207272 = 'Polish authors', Q45 = 'Portuguese authors', Q218 = 'Romanian authors', Q203493 = 'Romanian authors', -- Kingdom of Romania Q159 = 'Russian authors', Q34266 = 'Russian authors', -- 1721-1917 Q15180 = 'Soviet Union authors', Q851 = 'Saudi Arabian authors', Q403 = 'Serbian authors', Q1044 = 'Sierra Leonean authors', Q334 = 'Singaporean authors', Q214 = 'Slovak authors', Q215 = 'Slovenian authors', Q258 = 'South African authors', Q29 = 'Spanish authors', Q854 = 'Sri Lankan authors', Q1049 = 'Sudanese authors', Q39 = 'Swiss authors', Q23366230 = 'Genevan authors', Q34 = 'Swedish authors', Q858 = 'Syrian authors', Q869 = 'Thai authors', Q17269 = 'Tibetan authors', Q2444884 = 'Tibetan authors', -- 1912–1951 Q43 = 'Turkish authors', Q12560 = 'Ottoman Empire authors', Q1036 = 'Ugandan authors', Q212 = 'Ukrainian authors', Q30 = 'United States authors', Q81931 = 'Confederate States authors', Q1183 = 'Puerto Rican authors', Q237 = 'Vatican City authors', Q170174 = 'Papal States authors', Q23725 = 'Byzantine authors', Q32047 = 'Illyrian authors', Q717 = 'Venezuelan authors', Q881 = 'Vietnamese authors', Q954 = 'Zimbabwean authors', Q36704 = 'Yugoslavian authors', Q191077 = 'Yugoslavian authors', -- Kingdom of Yugoslavia Q83286 = 'Yugoslavian authors', -- Socialist Federal Republic of Yugoslavia Q838261 = 'Yugoslavian authors', -- Federal Republic of Yugoslavia Q1277557 = 'Yugoslavian authors', -- Democratic Federal Yugoslavia Q1290149 = 'Yugoslavian authors', -- Federal People's Republic of Yugoslavia Q757 = 'Vincentian authors', Q40169 = 'Assyrian authors', Q13053139 = 'Hittite authors', Q104028 = 'Judean authors', Q1003997 = 'Judean authors', Q809806 = 'Bashkir authors', Q1150344 = 'Johori authors', -- Johor Sultanate Q31929 = 'Frankish authors', -- Carolingian Empire -- these seem like ethnicities rather than nationalities -- = 'Bengali authors', -- = 'African authors', -- = 'Arab authors', -- = 'Kurdish authors', -- = 'Nepali authors', }, occupations = { -- Q49757 = 'Poets', -- split by nationality - should we do that too? Q16360440 = 'Anthologists', Q18814623 = 'Autobiographers', Q8246794 = 'Bloggers', Q4853732 = 'Children\'s authors', Q27431213 = 'Cookbook authors', Q18939491 = 'Diarists', Q11774202 = 'Essayists', Q3064032 = 'Fabulists', Q5434338 = 'Fantasy authors', Q11500768 = 'Food writers', Q12406482 = 'Humourists', Q13424456 = 'Hymnists', Q3589290 = 'Letter writers', -- correspondent Q11774156 = 'Memoirists', Q42361191 = 'Military writers', Q18533509 = 'Medical writers', Q10297252 = 'Mystery authors', -- crime fiction writers ? this preferred Q15958642 = 'Political authors', --Q15980158 = 'Non-fiction authors', -- too broad, rem'd Q6625963 = 'Novelists', Q3075052 = 'Folklorists', Q16254673 = 'Pamphleteers', Q214917 = 'Playwrights', Q2629392 = 'Puppeteers as authors', Q15077007 = 'Podcasters', Q9334029 = 'Satirists', Q3745071 = 'Science authors', Q18844224 = 'Science fiction authors', Q15949613 = 'Short story authors', Q121594 = 'Professors as authors', Q13210922 = 'Turkologists as authors', Q15255771 = 'Sinologists as authors', Q16314501 = 'Encyclopedists as authors', Q1731155 = 'Orientalists as authors', Q17598791 = 'Latinists as authors', Q15976341 = 'Slavists as authors', Q19361459 = 'Assyriologists as authors', Q1350189 = 'Egyptologists as authors', Q2109655 = 'Mayanists as authors', Q3333377 = 'Mesoamericanists as authors', Q15991218 = 'Japanologists as authors', Q21197924 = 'Celticists as authors', Q16402907 = 'Semioticians as authors', Q18524037 = 'Indologists as authors', Q2505739 = 'Hispanists as authors', Q620573 = 'Arabists as authors', Q1607826 = 'Editors as authors', Q589298 = 'Editors as authors', -- editor-in-chief Q2516852 = 'Editors as authors', -- literary editor Q1930187 = 'Journalists as authors', Q17351648 = 'Newspaper editors as authors', Q106568011 = 'Magazine editors as authors', Q1086863 = 'Columnists as authors', Q998550 = 'Booksellers as authors', Q182436 = 'Librarians as authors', Q2306091 = 'Sociologists as authors', Q333634 = 'Translators as authors', Q37226 = 'Educators as authors', Q974144 = 'Educators as authors', Q1622272 = 'Educators as authors', -- university teachers Q29182003 = 'Educators as authors', -- mathematics teacher Q1569495 = 'Educators as authors', -- lecturer Q15977927 = 'Educators as authors', -- art educators Q2251335 = 'School teachers as authors', Q1459149 = 'School teachers as authors', -- schoolmaster Q63676514 = 'Educationalists as authors', -- educational theorist Q1231865 = 'Educationalists as authors', -- pedagogue Q95674799 = 'Educationalists as authors', -- examiner Q4988856 = 'Hebraists as authors', Q82955 = 'Politicians as authors', Q97667506 = 'Politicians as authors', -- Ancient Roman politician Q8125919 = 'Political advisors as authors', Q175301 = 'Speechwriters as authors', Q11986654 = 'Lobbyists as authors', Q65997 = 'Caliphs as authors', -- duplicates usage as position Q186360 = 'Nurses as authors', Q3410028 = 'Psychoanalysts as authors', Q1900167 = 'Psychotherapists as authors', Q39631 = 'Physicians as authors', Q551835 = 'Physicians as authors', -- physician writer Q4002666 = 'Physicians as authors', -- military physician Q10872101 = 'Anatomists as authors', Q96781864 = 'Vaccinologists as authors', Q2114605 = 'Pharmacologists as authors', Q2447386 = 'Dermatologists as authors', Q2055046 = 'Physiologists as authors', Q16831721 = 'Ethologists as authors', Q13638192 = 'Obstetricians as authors', Q17345122 = 'Urologists as authors', Q774306 = 'Surgeons as authors', Q211346 = 'Psychiatrists as authors', Q212980 = 'Psychologists as authors', Q2640827 = 'Gynecologists as authors', Q1919436 = 'Pediatricians as authors', Q27349 = 'Dentists as authors', Q3368718 = 'Pathologists as authors', Q651566 = 'Hygienists as authors', Q42673468 = 'Naturopaths as authors', Q12013238 = 'Ophthalmologists as authors', Q783906 = 'Neurologists as authors', Q2920595 = 'Sexologists as authors', Q10295465 = 'Hydrographers as authors', Q138858 = 'Entertainers as authors', Q245068 = 'Comedians as authors', Q33999 = 'Actors as authors', Q10800557 = 'Actors as authors', -- film actors Q2526255 = 'Film directors as authors', Q3282637 = 'Film producers as authors', Q28389 = 'Screenwriters as authors', Q69423232 = 'Screenwriters as authors', -- film screenwriter Q222344 = 'Cinematographers as authors', Q135301631 = 'Broadcasters as authors', Q266569 = 'Animators as authors', Q1114448 = 'Cartoonists as authors', Q3658608 = 'Caricaturists as authors', Q715301 = 'Comic strip artists as authors', Q33231 = 'Photographers as authors', Q10429346 = 'Bibliographers as authors', Q1781198 = 'Agronomists as authors', Q1371796 = 'Gunsmiths as authors', Q13235160 = 'Manufacturers as authors', Q6606110 = 'Manufacturers as authors', -- industrialist Q758780 = 'Gardeners as authors', Q131512 = 'Farmers as authors', Q3140857 = 'Horticulturalists as authors', Q1781198 = 'Agriculturalists as authors', Q1549283 = 'Landholders as authors', -- large estate owner Q55982999 = 'Landholders as authors', -- pastoralist Q9325191 = 'Land valuers as authors', -- real estate appraiser Q2478141 = 'Aristocrats as authors', Q715222 = 'Ladies-in-waiting as authors', Q12362622 = 'Philanthropists as authors', Q43845 = 'Businesspeople as authors', Q24266767 = 'Businesspeople as authors', -- newspaper proprietors Q1979607 = 'Financiers as authors', Q215536 = 'Merchants as authors', Q2556132 = 'Merchants as authors', -- wine merchant Q836904 = 'Brewers as authors', Q15442776 = 'Cryptographers as authors', Q14972848 = 'Lexicographers as authors', Q483501 = 'Artists as authors', Q1925963 = 'Artists as authors', -- graphic artist Q3391743 = 'Artists as authors', -- visual artist Q1028181 = 'Painters as authors', Q644687 = 'Illustrators as authors', Q19507792 = 'Scientific illustrators as authors', Q3303330 = 'Calligraphers as authors', Q1281618 = 'Sculptors as authors', Q1955150 = 'Instrument makers as authors', Q15977971 = 'Woodworkers as authors', Q6138343 = 'Woodworkers as authors', -- wood carver Q559597 = 'Woodworkers as authors', -- cabinetmaker Q7541856 = 'Ceramicists as authors', Q3400050 = 'Ceramicists as authors', -- potter Q674426 = 'Curators as authors', Q780596 = 'Curators as authors', -- exhibition curator Q107106416 = 'Museum administrators as authors', Q22132694 = 'Museum administrators as authors', -- museum director Q26903663 = 'Arts administrators as authors', Q158852 = 'Conductors as authors', Q177220 = 'Singers as authors', Q62523648 = 'Phrenologists as authors', Q822146 = 'Lyricists as authors', Q639669 = 'Musicians as authors', Q5371902 = 'Musicians as authors', -- harpsichordist Q36834 = 'Composers as authors', Q4964182 = 'Philosophers as authors', Q753110 = 'Songwriters as authors', Q8178443 = 'Librettists', Q101084010 = 'Folk musicians as authors', Q14915627 = 'Musicologists as authors', Q17484288 = 'Ethnomusicologists as authors', Q16031530 = 'Music theorists as authors', Q2675537 = 'Music teachers as authors', Q16145150 = 'Music teachers as authors', -- second of same label Q1259917 = 'Violinists as authors', Q855091 = 'Guitarists as authors', Q6168364 = 'Guitarists as authors', -- jazz guitarist Q24067349 = 'Guitarists as authors', -- classical guitarist Q765778 = 'Organists as authors', Q10475818 = 'Organists as authors', -- cathedral organists Q66357787 = 'Organists as authors', -- jazz organists Q2361162 = 'Organists as authors', -- titular organists Q106610718 = 'Organists as authors', -- stadium organists Q66357406 = 'Organists as authors', -- church organist -- see also {instrument} Q486748 = 'Pianists as authors', -- see also {instrument} Q16003954 = 'Oboists as authors'; Q12902372 = 'Flautists as authors'; Q1776724 = 'Theatre managers and producers as authors', Q1759246 = 'Theatre managers and producers as authors', Q47064 = 'Military personnel as authors', Q189290 = 'Military personnel as authors', -- military officer Q4991371 = 'Soldiers as authors', Q38239859 = 'Army officers as authors', Q19934710 = 'Air force officers as authors', Q10669499 = 'Naval officers as authors', Q45199 = 'Sailors as authors', Q476246 = 'Sailors as authors', Q6785172 = 'Master mariners as authors', Q1766113 = 'Lighthouse keepers as authors', Q500251 = 'Shipowners as authors', Q728425 = 'Balloonists as authors', Q2295938 = 'Furriers as authors', Q1895303 = 'Foresters as authors', Q329439 = 'Engravers as authors', Q47005195 = 'Engravers as authors', -- wood engraver, printmaking Q1708232 = 'Medallists as authors', Q10862983 = 'Etchers as authors', Q11569986 = 'Printmakers as authors', Q2034021 = 'Dressmakers as authors', Q15319501 = 'Social scientists as authors', Q10333969 = 'Museologists as authors', Q22082717 = 'Eugenicists as authors', Q5697103 = 'Antiquarians as authors', Q2004963 = 'Numismatists as authors', Q56027890 = 'Political staffers as authors', Q3400985 = 'Academics as authors', Q1650915 = 'Academics as authors', -- Researchers Q326653 = 'Accountants as authors', Q179985 = 'Actuaries as authors', Q15954519 = 'Alchemists as authors', Q42973 = 'Architects as authors', Q26224000 = 'Castellologists as authors', Q635734 = 'Archivists as authors', Q155647 = 'Astrologers as authors', Q2095549 = 'Aviators as authors', Q618694 = 'Aviators as authors', Q864380 = 'Biographers as authors', Q201788 = 'Historians as authors', Q11486702 = 'Architectural historians as authors', Q1792450 = 'Art historians as authors', Q1743122 = 'Church historians as authors', Q15462162 = 'Cultural historians as authors', Q17488363 = 'Economic historians as authors', Q20971250 = 'Film historians as authors', Q2135538 = 'Law historians as authors', Q13570226 = 'Literary historians as authors', Q15985128 = 'Medical historians as authors', Q1493121 = 'Military historians as authors', Q67202187 = 'Naval historians as authors', Q1595570 = 'Local historians as authors', Q16063546 = 'Historians of science as authors', Q17488357 = 'Historians of religion as authors', Q24265174 = 'Historians of philosophy as authors', Q30740797 = 'Historic preservationists as authors', Q17486330 = 'Historians of mathematics as authors', Q101064325 = 'Philosophers of mathematics as authors', Q11063 = 'Astronomers as authors', Q15839134 = 'Ecologists as authors', Q16271428 = 'Embryologists as authors', Q16063497 = 'Evolutionary biologists as authors', Q18576582 = 'Metallurgists as authors', Q15623737 = 'Glaciologists as authors', Q2310145 = 'Meteorologists as authors', Q1113838 = 'Climatologists as authors', Q3546255 = 'Oceanographers as authors', Q18805 = 'Naturalists as authors', Q3126128 = 'Geneticists as authors', Q15974789 = 'Coptologists as authors', Q16334509 = 'Pteridologists as authors', Q63959218 = 'Horologists as authors', Q1238570 = 'Political scientists as authors', Q15994177 = 'Political theorists as authors', Q175151 = 'Printers as authors', Q16533 = 'Judges as authors', Q6731168 = 'Judges as authors', -- magistrate Q185351 = 'Jurists as authors', Q1134614 = 'Coroners as authors', Q806798 = 'Bankers as authors', Q2883465 = 'Bankers as authors', Q316490 = 'Funeral directors as authors', Q8963721 = 'Genealogists as authors', Q3247049 = 'Officers of arms as authors', Q202883 = 'Veterinarians as authors', Q2516866 = 'Publishers as authors', Q1320047 = 'Publishers as authors', -- book publisher Q222836 = 'Music publishers as authors', Q2443377 = 'Topographers as authors', Q294126 = 'Surveyors as authors', -- land surveyor Q116994205 = 'Geodesists as authors', Q1371378 = 'Ethnologists as authors', Q9352089 = 'Spies as authors', Q7019111 = 'Social workers as authors', Q16060693 = 'Conservationists as authors', Q4182927 = 'Stockbrokers as authors', Q3621491 = 'Archaeologists as authors', Q15983985 = 'Archaeologists as authors', -- classical archaeologist Q205375 = 'Inventors as authors', Q901 = 'Scientists as authors', Q169470 = 'Physicists as authors', Q752129 = 'Astrophysicists as authors', Q29909337 = 'Experimental physicists as authors', Q109096773 = 'Relativity theorists as authors', Q19350898 = 'Theoretical physicists as authors', Q17276189 = 'Atmospheric scientists as authors', Q21329070 = 'Materials scientists as authors', Q15142825 = 'Crystallographers as authors', Q170790 = 'Mathematicians as authors', Q17344952 = 'Arachnologists as authors', Q15816836 = 'Bacteriologists as authors', Q3779582 = 'Microbiologists as authors', Q864503 = 'Biologists as authors', Q497294 = 'Lepidopterists as authors', Q43095928 = 'Conchologists as authors', Q51954785 = 'Biogeographers as authors', Q47825396 = 'Phytogeographists as authors', Q14906342 = 'Biophysicists as authors', Q3640160 = 'Marine biologists as authors', Q350979 = 'Zoologists as authors', Q88106580 = 'Paleozoologists as authors', Q16831394 = 'Mammalogists as authors', Q19798999 = 'Acarologists as authors', Q105186 = 'Pharmacists as authors', Q12119633 = 'Immunologists as authors', Q16868721 = 'Carcinologists as authors', Q3055126 = 'Entomologists as authors', Q11741162 = 'Coleopterists as authors', Q109093961 = 'Hymenopterists as authors', Q2125610 = 'Cyclists as authors', Q2309784 = 'Cyclists as authors', -- sport cyclist Q17765219 = 'Colonial administrators as authors', Q193391 = 'Diplomats as authors', Q121998 = 'Diplomats as authors', -- ambassador Q3734658 = 'Diplomats as authors', -- consul general Q738142 = 'Clerks as authors', Q16532929 = 'Administrators as authors', Q56224063 = 'Bookkeepers as authors', Q188094 = 'Economists as authors', Q105572010 = 'Political economists as authors', Q2732142 = 'Statisticians as authors', Q12360779 = 'Demographers as authors', Q12347522 = 'Ethnographers as authors', Q121594 = 'Professors as authors', Q24049451 = 'Chronologists as authors', Q15855449 = 'Magicians as authors', Q12356615 = 'Travelers as authors', Q3579035 = 'Travel writers', -- travel writer Q4610556 = 'Models as authors', Q21281706 = 'Academic administrators as authors', Q1318390 = 'Radio operators as authors', Q2722764 = 'Radio presenters as authors', Q11900058 = 'Explorers as authors', Q13382749 = 'Explorers as authors', -- polar explorer Q13416354 = 'Mineralogists as authors', Q520549 = 'Geologists as authors', Q3501317 = 'Fashion designers as authors', Q56314891 = 'Historiographers as authors', Q17132038 = 'Paleographers as authors', Q16267158 = 'Papyrologists as authors', Q189010 = 'Notaries as authors', Q24387326 = 'Mythographers as authors', -- secretaries, assistants Q80687 = 'Secretaries as authors', Q1096316 = 'Secretaries as authors', -- personal assistant Q1388151 = 'Press secretaries as authors', Q212238 = 'Civil servants as authors', --critics Q6430706 = 'Critics as authors', Q4164507 = 'Art critics as authors', Q4263842 = 'Literary critics as authors', Q1350157 = 'Music critics as authors', Q17337766 = 'Theatre critics as authors', Q1086863 = 'Columnists as authors', --sports people Q50995749 = 'Sportspeople as authors', Q12299841 = 'Cricketers as authors', Q13415036 = 'Rugby players as authors', Q14089670 = 'Rugby players as authors', -- rugby union players Q10871364 = 'Baseball players as authors', Q13382576 = 'Rowers as authors', Q2066131 = 'Athletes as authors', Q6665249 = 'Judoka as authors', Q11338576 = 'Boxers as authors', Q28164897 = 'Jujutsuka as authors', Q12839983 = 'Wrestlers as authors', Q13474373 = 'Wrestlers as authors', -- professional wrestler Q12369333 = 'Wrestlers as authors', -- amateur wrestler Q11303721 = 'Golfers as authors', Q9149093 = 'Mountaineers as authors', Q10873124 = 'Chess players as authors', Q16402890 = 'Draughts players as authors', --scholars Q13418253 = 'Philologists as authors', Q16267607 = 'Philologists as authors', -- classical philologist Q18916225 = 'Philologists as authors', -- hellenist -- Q2248623 = 'Scholars as authors', -- scrapped, amended at WD Q20826540 = 'Scholars as authors', Q16308156 = 'English scholars as authors', -- scholar of English Q11499929 = 'Literary scholars as authors', Q17167049 = 'Literary scholars as authors', -- merged into Q11499929, can be removed once bots have updated Q2468727 = 'Classical scholars as authors', Q19829990 = 'Biblical scholars as authors', Q3155377 = 'Islamic scholars as authors', Q5121550 = 'Jewish scholars as authors', Q21584816 = 'Talmudists as authors', Q98637226 = 'Shakespeare scholars as authors', Q67221165 = 'Vexillographers as authors', Q14467526 = 'Linguists as authors', Q860918 = 'Esperanto authors', Q15991187 = 'Grammarians as authors', Q47491160 = 'Phoneticians as authors', Q16312408 = 'Etymologists as authors', Q15991192 = 'Sanskrit scholars as authors', Q109094544 = 'Syntacticians as authors', Q11424130 = 'Toponymists as authors', Q12094958 = 'Geophysicists as authors', Q901402 = 'Geographers as authors', Q38053159 = 'Geomorphologists as authors', Q1734662 = 'Cartographers as authors', Q15632632 = 'Epigraphers as authors', Q12859263 = 'Orators as authors', Q10732476 = 'Art collectors as authors', Q18930236 = 'Philosophers of language as authors', Q361809 = 'Rhetoricians as authors', Q3332711 = 'Medievalists as authors', Q2259532 = 'Clerics as authors', -- cleric Q42603 = 'Clerics as authors', -- priest Q1423891 = 'Clerics as authors', -- christian minister Q3315492 = 'Clerics as authors', --clergyman Q152002 = 'Clerics as authors', --pastor Q733786 = 'Monks', Q250867 = 'Roman Catholic clergy as authors', Q1469535 = 'Roman Catholic clergy as authors', -- Latin Catholic priest Q3409375 = 'Anglican clergy as authors', Q49476 = 'Archbishops', Q191808 = 'Nuns as authors', Q1234713 = 'Theologians as authors', Q432386 = 'Preachers as authors', Q219477 = 'Missionaries as authors', Q125482 = 'Imams as authors', Q133485 = 'Rabbis as authors', Q81096 = 'Engineers as authors', Q13582652 = 'Civil engineers as authors', Q1326886 = 'Electrical engineers as authors', Q1324245 = 'Military engineers as authors', Q10497074 = 'Aerospace engineers as authors', Q1906857 = 'Mechanical engineers as authors', Q151197 = 'Military engineers as authors', Q18524075 = 'Mining engineers as authors', Q109094822 = 'Signal engineers as authors', Q1644847 = 'Naval engineers as authors', -- marine engineer Q2860259 = 'Naval architects as authors', -- marine architect Q3363630 = 'Parapsychologists as authors', Q82594 = 'Computer scientists as authors', Q15994177 = 'Political theorists as authors', Q4773904 = 'Anthropologists as authors', Q102123287 = 'Physical anthropologists as authors', Q109096223 = 'Comparative anatomists as authors', Q1225716 = 'Ornithologists as authors', Q1907198 = 'Taxonomists as authors', Q2374149 = 'Botanists as authors', Q30059961 = 'Paleobotanists as authors', Q1662561 = 'Paleontologists as authors', Q21272406 = 'Paleoanthropologists as authors', Q12358881 = 'Phycologists as authors', Q4205432 = 'Ichthyologists as authors', Q12773412 = 'Parasitologists as authors', Q16271064 = 'Herpetologists as authors', Q12358881 = 'Algologists as authors', Q2998308 = 'Cosmologists as authors', Q15839136 = 'Cytologists as authors', Q593644 = 'Chemists as authors', Q43668003 = 'Chemists as authors', -- analytical chemist Q1645306 = 'Chemists as authors', -- textile chemist Q34463094 = 'Organic chemists as authors', Q2919046 = 'Biochemists as authors', Q16335312 = 'Geochemists as authors', Q15941468 = 'Forensic scientists as authors', Q11424604 = 'Earth scientists as authors', Q12051314 = 'Seismologists as authors', Q15627169 = 'Trade unionists as authors', Q19945412 = 'Cheese makers as authors', Q3499072 = 'Chefs as authors', Q2516866 = 'Publishers as authors', Q1413170 = 'Bookbinders as authors', Q16389557 = 'Philosophers of science as authors', Q18930007 = 'Philosophers of politics as authors', Q21550346 = 'Philosophers of art as authors', Q88105593 = 'Philosophers of history as authors', Q23760244 = 'Philosophers of law as authors', Q106921327 = 'Philosophers of mind as authors', Q1297719 = 'Philosophers of morals as authors', Q88114145 = 'Philosophers of religion as authors', Q16743941 = 'Metaphysicians as authors', Q14565331 = 'Logicians as authors', Q15632482 = 'Epistemologists as authors', Q7783170 = 'Thermodynamicists as authors', Q12358881 = 'Phycologists as authors', Q22813567 = 'Pyrotechnists as authors', Q13381863 = 'Fencers as authors', Q1475726 = 'Philatelists as authors', Q3243461 = 'Collectors as authors', Q207978 = 'Consuls as authors', Q40779 = 'Consuls as authors', -- Roman consul Q15253558 = 'Activists as authors', Q16323111 = 'Activists as authors', -- peace activist Q1476215 = 'Activists as authors', -- human rights defender Q61048378 = 'Activists as authors', -- climate activists Q1021386 = 'Civil rights activists as authors', -- civil rights advocate Q28692502 = 'Women\'s rights activists as authors', Q109120252 = 'Free speech activists as authors', Q11499147 = 'Political activists as authors', Q18510179 = 'Abolitionists as authors'; Q27532437 = 'Suffragists as authors', Q322170 = 'Suffragists as authors', -- suffragettes Q34074720 = 'feminists as authors', Q16611574 = 'Social reformers as authors', Q27497422 = 'Helminthologists as authors', Q16947657 = 'Lithographers as authors', Q17505902 = 'Watercolorists as authors', Q5322166 = 'Designers as authors', Q2133309 = 'Interior designers as authors', Q15432439 = 'Garden designers as authors', Q28933278 = 'Book designers as authors', Q106675732 = 'Legal writers as authors', Q16012028 = 'Legal scholars as authors', Q16271261 = 'Malacologists as authors', Q16334507 = 'Bryologists as authors', Q2487799 = 'Mycologists as authors', Q15924544 = 'Lichenologists as authors', Q3746192 = 'Phytopathologists as authors', Q3578589 = 'Environmentalists as authors', Q16062369 = 'Oncologists as authors', Q852389 = 'Beekeepers as authors', Q2114844 = 'Taxidermists as authors', Q12359071 = 'Anarchists as authors', Q8142883 = 'Criminologists as authors', Q40348 = 'Lawyers as authors', Q1144892 = 'Lawyers as authors', -- patent attorney Q808967 = 'Barristers as authors', Q380075 = 'Barristers as authors', -- advocate Q14284 = 'Solicitors as authors', Q2159907 = 'Criminals as authors', Q2627286 = 'Criminals as authors', -- bushranger Q989174 = 'Convicts as authors', Q55983771 = 'Assassins as authors', Q1862087 = 'Prisoners as authors', Q179637 = 'Prisoners of war as authors', Q217105 = 'Political prisoners as authors', Q116 = 'Royalty as authors', -- monarch Q39018 = 'Royalty as authors', -- emperor Q2304859 = 'Royalty as authors', -- sovereign Q477406 = 'Royalty as authors', -- Q37110 = 'Pharaohs', Q2478141 = 'Aristocrats as authors', Q6503343 = 'Law enforcement officers as authors', Q384593 = 'Law enforcement officers as authors', -- police officer Q683462 = 'Law enforcement officers as authors', -- chief police officer Q55187 = 'Hairdressers as authors', Q109120330 = 'Dravidologists as authors', Q10355417 = 'Advertising people as authors', Q4178004 = 'Publicists as authors', Q820037 = 'Miners as authors', Q559597 = 'Cabinetmakers as authors', Q1489454 = 'Harbour masters as authors', Q683754 = 'Drafters as authors', Q14623005 = 'Drafters as authors', -- draftsperson Q593362 = 'Drapers as authors', Q109120482 = 'Aviculturists as authors', Q40318865 = 'Aviculturists as authors', -- pigeon fancier Q937857 = 'Association football players as authors', }, religions = { --worldview Q1841 = 'Catholic authors', Q42504 = 'Mormon authors', -- protestant Q23540 = 'Protestant authors', Q6423963 = 'Anglican authors', Q27827 = 'Christadelphian authors', Q1062789 = 'Congregationalist authors', Q18245005 = 'Congregationalist authors', -- Congregationalism in the US Q960252 = 'Congregationalist authors', -- congregational polity Q178169 = 'Presbyterian authors', Q782613 = 'Presbyterian authors', -- Orthodox Presbyterian Church Q33203 = 'Methodist authors', Q106687 = 'Unitarian authors', Q93191 = 'Baptist authors', Q170208 = 'Quaker authors', Q75809 = 'Lutheran authors', Q101849 = 'Calvinist authors', Q19001724 = ' Universalist authors', -- Universalism Q6843150 = ' Universalist authors', -- universalism Q331563 = 'Transcendentalist authors', -- jew Q9268 = 'Jews', -- this WS category seems to conflate ethnicity and religion? Q80970 = 'Orthodox Jews', Q1133485 = 'Reform Jews', -- muslim Q432 = 'Muslim authors', Q483654 = 'Sunni authors', Q9585 = 'Shiite authors', Q9603 = 'Sufi authors', -- non-Christian Q748 = 'Buddhists', Q483889 = 'Buddhists', -- Tibetan Buddhism Q9581 = 'Confucian authors', Q812767 = 'Shintoists', Q9598 = 'Taoists', Q9089 = 'Hindu authors', Q178671 = 'Theosophist authors', Q178761 = 'Theosophist authors', -- Blavatskian theosophy Q9601 = 'Zoroastrian authors', Q1541838 = 'Druids', Q7066 = 'Atheist authors', Q288928 = 'Agnostic authors', }, ideologies = { Q188993 = 'Anarchists as authors', Q1852084 = 'Socialists', }, movements = { Q331563 = 'Transcendentalist authors', Q58848 = 'Pacifists', Q37068 = 'Romanticism', }, positionheld = { Q37349 = 'Dalai Lamas', Q29282 = 'Archbishops of Canterbury', Q172748 = 'Antipopes', Q19546 = 'Popes as authors', -- the RC version Q105080069 = 'Archbishops of Canterbury', -- RC flavour Q611644 = 'Roman Catholic bishops', Q10847705 = 'Catholic archbishops', Q45722 = 'Catholic archbishops', --cardinal Q1140706 = 'Presidents of Afghanistan', Q1625960 = 'Presidents of Albania', Q16009376 = 'Prime Ministers of Albania', Q4283840 = 'Presidents of Armenia', Q1123764 = 'Prime Ministers of Armenia', Q610669 = 'Governors-General_of_Australia', Q1571023 = 'Governors and administrators of states and territories of Australia', -- Gov of Vic Q55616845 = 'Governors and administrators of states and territories of Australia', -- Lt Gov of Vic Q1528895 = 'Governors and administrators of states and territories of Australia', -- Gov of NSW Q1840570 = 'Governors and administrators of states and territories of Australia', -- Gov of SA Q1372518 = 'Governors and administrators of states and territories of Australia', -- Gov of WA Q1779581 = 'Governors and administrators of states and territories of Australia', -- Gov of Tas Q1467097 = 'Governors and administrators of states and territories of Australia', -- Gov of Qld Q3249421 = 'Governors and administrators of states and territories of Australia', -- Admin of NT Q29291882 = 'Governors and administrators of states and territories of Australia', -- Admin of Norfolk Island Q319145 = 'Prime Ministers of Australia', Q475658 = 'Presidents of Austria', Q15902790 = 'Ministers-President of Austria', Q205602 = 'Presidents of Azerbaijan', Q1049659 = 'Presidents of Belarus', Q13592862 = 'Monarchs of Belgium', Q213107 = 'Prime Ministers of Belgium', Q732859 = 'Governors of Bermuda', Q5176750 = 'Presidents of Brazil', Q390776 = 'Governors-General of Canada', Q5589553 = 'Governors-General of Canada', -- Governor General of the Province of Canada -- Q3238289 = 'Lieutenant-Governors of Lower Canada', -- Lieutenant Governor of Quebec -- been appropriated, not using Q15303916 = 'Lieutenant-Governors of Lower Canada', -- possibly ineffective Q116698441 = 'Members of the King\'s Privy Council for Canada', Q839078 = 'Prime Ministers of Canada', Q4377218 = 'Prime Ministers of the Cape Colony', Q466956 = 'Presidents of Chile', Q655407 = 'Presidents of the People\'s Republic of China', Q4122271 = 'Premiers of the People\'s Republic of China', Q853475 = 'Presidents of Colombia', Q1370482 = 'Presidents of Cuba', Q1819381 = 'Presidents of the Czech Republic', Q15233311 = 'Presidents of Czechoslovakia', Q28530145 = 'Prime Ministers of Czechoslovakia', -- France Q191954 = 'Presidents of the French Republic', Q1587677 = 'Prime Ministers of France', Q15135541 = 'Prime Ministers of France', -- head of gov Q843405 = 'Presidents of Georgia', Q1975365 = 'Prime Ministers of Georgia', Q1159846 = 'Governors of Hong Kong', Q313383 = 'Presidents of India', Q11755916 = 'Presidents of Indonesia', Q192711 = 'Prime Ministers of India', Q838380 = 'Presidents of Iran', Q889817 = 'Presidents of Iraq', Q1476165 = 'Prime Ministers of Iraq', Q213702 = 'Presidents of Ireland', Q327948 = 'Presidents of Israel', Q208487 = 'Prime Ministers of Israel', Q7243300 = 'Prime Ministers of Jordan', Q5256775 = 'Presidents of Kazakhstan', Q2416315 = 'Prime Ministers of Kazakhstan', Q19161825= 'Presidents of Liberia', Q878222 = 'Presidents of Lithuania', Q845439 = 'Prime Ministers of Lithuania', Q1149153 = 'Presidents of Montenegro', Q2353252 = 'Prime Ministers of Montenegro', Q628004 = 'Presidents of Mexico', Q455690 = 'Governors-General of New Zealand', Q1071117 = 'Prime Ministers of New Zealand', Q18145518 = 'Members of the New Zealand House of Representatives', Q65997 = 'Caliphs as authors', Q28541943 = 'Caliphs as authors', -- Abbasid caliph Q14723495 = 'Caliphs as authors', -- Almohad caliph Q67497236 = 'Caliphs as authors', -- Umayyad caliph Q14979753 = 'Caliphs as authors', -- Fatimid caliph Q180465 = 'Caliphs as authors', -- Rashidun Q15057711 = 'Caliphs as authors', -- caliph of Cordoba Q115556515 = 'Caliphs as authors', -- sultan of Grenada Q15315411 = 'Sultans of the Ottoman Empire', Q15063567 = 'Grand Viziers of the Ottoman Empire', Q2336111 = 'Presidents of the Palestinian National Authority', Q1209571 = 'Presidents of the Philippines', Q2723485 = 'Vice Presidents of the Philippines', Q18579098 = 'Senators of the Philippines', Q3259469 = 'Prime Ministers of Poland', Q15304810 = 'Prime Ministers of Romania', Q218295 = 'Presidents of Russia', Q842386 = 'Prime Ministers of Russia', Q462189 = 'Premiers of the Soviet Union', -- Heads of government of the Soviet Union Q7018575 = 'Premiers of the Soviet Union', Q889950 = 'Presidents of Serbia and Montenegro', Q835586 = 'Prime Ministers of Serbia', Q6468838 = 'Presidents of Slovakia', Q273884 = 'Presidents of South Africa', --South Korea Q6296418 = 'Presidents of South Korea', Q489813 = 'Vice Presidents of South Korea', Q15407843 = 'Prime Ministers of South Korea', Q58330145 = 'Presidents of Spain', Q18171345 = 'Members of the Spanish Congress of Deputies', Q1922067 = 'Presidents of Turkey', Q2430415 = 'Prime Ministers of Turkey', Q21030356 = 'Members of the Turkish Parliament', Q14211 = 'Prime Ministers of the United Kingdom', -- Prime Ministers of Great Britain (not separated) Q943379 = 'Lord Presidents of the Privy Council of the United Kingdom', Q28841847 = 'Members of the Privy Council of the United Kingdom', Q28837708 = 'Members of the Privy Council of Ireland', --US Q11696 = 'Presidents of the U.S.', Q11699 = 'Vice presidents of the U.S.', Q14213 = 'United States Secretaries of State', Q2419102 = 'United States Secretaries of War', Q735015 = 'United States Secretaries of Defense', Q4215834 = 'United States Secretaries of the Treasury', Q1414246 = 'United States National Security Advisors', Q2666591 = 'Chairs of the Federal Reserve', Q4416090 = 'United States senators', Q13218630 = 'United States representatives', Q16149111 = 'Governors of Oregon', Q579677 = 'Presidents of Ukraine', Q11942698 = 'Presidents of Venezuela', Q61039224 = 'Presidents of Yugoslavia', Q1419999 = 'Prime Ministers of Yugoslavia', Q81066 = 'Secretaries-General of the United Nations', Q55713110 = 'Presidents of the Royal Society', Q44648694 = 'Secretaries of the Royal Society', Q117066292 = 'Presidents of the Royal Society of Edinburgh', Q7241336 = 'Presidents of the Geological Society of London', Q16854337 = 'Presidents of the Royal Geographical Society', Q116923363 = 'Presidents of the Royal Historical Society', Q104594648 = 'Presidents of the Royal Statistical Society', Q98271207 = 'Presidents of the Royal Numismatic Society', Q41726462 = 'Presidents of the Society of Antiquaries of London', Q20602711 = 'Presidents of the Society for Classical Studies', Q105071160 = 'Presidents of the Royal Society of New Zealand', Q877838 = 'Poets laureate of the United Kingdom', }, awardreceived = { Q46525 = 'Pulitzer Prize winners', -- Pulitzer Prize Q289214 = 'Pulitzer Prize winners', -- Pulitzer Prize for Drama Q833633 = 'Pulitzer Prize winners', -- Pulitzer Prize for Fiction Q2117891 = 'Pulitzer Prize winners', -- Pulitzer Prize for Poetry Q599254 = 'Pulitzer Prize winners', -- Pulitzer Prize for History Q1783509 = 'Pulitzer Prize winners', -- Pulitzer Prize for Music Q285117 = 'Pulitzer Prize winners', -- Pulitzer Prize for Biography or Autobiography Q784589 = 'Pulitzer Prize winners', -- Pulitzer Prize for General Non-Fiction Q644995 = 'Pulitzer Prize winners', -- Pulitzer Prize for Public Service Q387488 = 'Pulitzer Prize winners', -- Pulitzer Prize for Reporting Q93285026 = 'Pulitzer Prize winners', -- Pulitzer Prize for Audio Reporting Q1228241 = 'Pulitzer Prize winners', -- Pulitzer Prize for Beat Reporting Q636181 = 'Pulitzer Prize winners', -- Pulitzer Prize for Breaking News Reporting Q1434915 = 'Pulitzer Prize winners', -- Pulitzer Prize for Explanatory Reporting Q2117807 = 'Pulitzer Prize winners', -- Pulitzer Prize for International Reporting Q2117825 = 'Pulitzer Prize winners', -- Pulitzer Prize for Investigative Reporting Q7259352 = 'Pulitzer Prize winners', -- Pulitzer Prize for Local Reporting Q1671917 = 'Pulitzer Prize winners', -- Pulitzer Prize for National Reporting Q2117840 = 'Pulitzer Prize winners', -- Pulitzer Prize for Editorial Writing Q649953 = 'Pulitzer Prize winners', -- Pulitzer Prize for Editorial Cartooning Q1503021 = 'Pulitzer Prize winners', -- Pulitzer Prize for Photography Q643752 = 'Pulitzer Prize winners', -- Pulitzer Prize for Breaking News Photography Q634577 = 'Pulitzer Prize winners', -- Pulitzer Prize for Feature Photography Q3494428 = 'Pulitzer Prize winners', -- Pulitzer Prize for Spot News Photography Q2117828 = 'Pulitzer Prize winners', -- Pulitzer Prize for Criticism Q2117817 = 'Pulitzer Prize winners', -- Pulitzer Prize for Commentary Q2117813 = 'Pulitzer Prize winners', -- Pulitzer Prize for Feature Writing Q180340 = 'Pulitzer Prize winners', -- Pulitzer Prize for Correspondence Q1155483 = 'Pulitzer Prize winners', -- Pulitzer Prize for Novels -- Nobel Prize Q7191 = 'Nobel prize winners', -- Nobel Prize Q44585 = 'Nobel laureates in Chemistry', -- Nobel Prize in Chemistry Q37922 = 'Nobel laureates in Literature', -- Nobel Prize in Literature Q47170 = 'Nobel laureates in Economics', -- Prize in Economic Sciences in Memory of Alfred Nobel Q35637 = 'Nobel Peace Prize laureates', -- Nobel Peace Prize Q38104 = 'Nobel laureates in Physics', -- Nobel Prize in Physics Q80061 = 'Nobel laureates in Physiology or Medicine', -- Nobel Prize in Physiology or Medicine --UK learned societies Q15631401 = 'Fellows of the Royal Society', Q27988727 = 'Fellows of the British Academy', Q26204035 = 'Fellows of the Royal College of Physicians', Q20006267 = 'Fellows of the Royal Geographical Society', Q41942190 = 'Fellows of the Royal Institute of British Architects', Q26196499 = 'Fellows of the Society of Antiquaries of London', Q25513903 = 'Fellows of the Zoological Society of London', Q24591090 = 'Fellows of the Linnean Society of London', Q24590727 = 'Fellows of the Geological Society of London', Q5438598 = 'Fellows of the Royal Society of Edinburgh', Q63126958 = 'Fellows of the Royal Photographic Society', Q4905728 = 'Fellows of the Royal Society of Arts', Q24659199 = 'Fellows of the Royal Historical Society', Q117808713 = 'Fellows of the Royal College of Organists', Q26111565 = 'Fellows of the Royal Astronomical Society', Q20010681 = 'Fellows of the Royal Entomological Society', Q68554963 = 'Fellows of the Royal Society of Antiquaries of Ireland', -- USA learned societies Q52382875 = 'Fellows of the American Academy of Arts and Sciences', Q41955909 = 'Fellows of the American Physical Society', -- Recipients Q28003 = 'Recipients of the Copley Medal', -- award of the Royal Society Q1634098 = 'Recipients of the Murchison Medal', -- award of the Geological Society of London Q832424 = 'Recipients of the Wollaston Medal', -- award of the Geological Society of London Q705153 = 'Royal Guelphic Order', Q215248 = 'Order of the Garter', Q1326308 = 'Order of St Patrick', Q391911 = 'National Order of Quebec', Q17132005 = 'Recipients of the Hoover Medal', }, memberof = { Q161806 = 'Members of the Académie française', Q11993457 = 'Members of the Royal Spanish Academy', Q110587 = 'Members of the Royal Irish Academy', Q539216 = 'Members of the Bibliographical Society', Q5378172 = 'Members of the English Association', }, canonizationstatus = { Q43115 = 'Saints as authors', Q3464126 = 'Roman Catholic saints as authors', }, employer = { Q1661231 = 'Indian Civil Service officers as authors', Q245247 = 'Faculty of King\'s College London', Q6373 = 'British Museum', -- omnibus category, may wish to move author pages Q18748726= 'Royal Botanic Gardens, Kew', Q188617 = 'Royal Botanic Gardens, Kew', -- Kew Gardens Q1869031 = 'London Missionary Society', }, contributedto = { Q773087 = 'PSM contributors', }, socialclassification = { Q11573099 = 'Royalty as authors', -- royalty }, instrument = { -- see also occupations Q5994 = 'Pianists as authors', -- piano Q1444 = 'Organists as authors', -- organ Q8355 = 'Violinists as authors', -- violin Q6607 = 'Guitarists as authors', -- guitar Q8377 = 'Oboists as authors', -- oboe Q11405 = 'Flautists as authors', -- flute }, describedby = { Q15987216 = 'authors in DNB00', Q16014700 = 'authors in DNB01', Q16014697 = 'authors in DNB12', Q116234546 = 'authors in DNB27', Q867541 = 'authors in EB1911', Q16011749 = 'authors in DMM', }, mannerofdeath = { Q8454 = 'Executed people as authors', Q3966286 = 'Executed people as authors', Q1752350 = 'Executed people as authors', }, } } 76e5drah57a79isvtvq0xy4h14sr2d6 Skabelon:Forfatter/styles.css 10 125744 482577 2026-10-11T14:07:14Z Johshh 9757 Oprettede siden med ".wst-author-mainblock { border: 1px solid #BEA2A2; background-color: #E4D8D8; } .wst-author-notes { border-bottom: 1px solid #A88; background-color: var(--background-color-neutral, #FFFBFC); color: inherit; } .wst-author-seealso { border: 1px solid #CCC; } @media screen { html.skin-theme-clientpref-night .wst-author-mainblock { background-color: #4B3434; } } @media screen and (prefers-color-scheme: dark) { html.skin-theme-clientpref-os .wst-author-mainblock..." 482577 sanitized-css text/css .wst-author-mainblock { border: 1px solid #BEA2A2; background-color: #E4D8D8; } .wst-author-notes { border-bottom: 1px solid #A88; background-color: var(--background-color-neutral, #FFFBFC); color: inherit; } .wst-author-seealso { border: 1px solid #CCC; } @media screen { html.skin-theme-clientpref-night .wst-author-mainblock { background-color: #4B3434; } } @media screen and (prefers-color-scheme: dark) { html.skin-theme-clientpref-os .wst-author-mainblock { background-color: #4B3434; } } tgzt2z800mw88pivvf3hrig02w1w64s Skabelon:Header structure/styles.css 10 125745 482578 2026-10-11T14:08:01Z Johshh 9757 Oprettede siden med "/* Styles used by header templates (not just header) */ /* * main block */ /* The top level wrapper for the header main block. */ .wst-header-mainblock { margin: 4px auto 4px auto; padding: 0 3px; display: flex; align-items: center; } /* Common styles for back and forward links */ .wst-header-back, .wst-header-forward { display: flex; flex: 1 4 100%; min-width: min-content; align-items: center; font-size: .9em; } .wst-header-nav-empty { visibility: hidden..." 482578 sanitized-css text/css /* Styles used by header templates (not just header) */ /* * main block */ /* The top level wrapper for the header main block. */ .wst-header-mainblock { margin: 4px auto 4px auto; padding: 0 3px; display: flex; align-items: center; } /* Common styles for back and forward links */ .wst-header-back, .wst-header-forward { display: flex; flex: 1 4 100%; min-width: min-content; align-items: center; font-size: .9em; } .wst-header-nav-empty { visibility: hidden; } /* The container for the back (previous) link. */ .wst-header-back { justify-content: flex-start; text-align: left; } /* The container for the central cell. */ .wst-header-central-cell { flex: 4 1 100%; max-width: max-content; text-align: center; } /* The container for the forward (next) link. */ .wst-header-forward { justify-content: flex-end; text-align: right; } @media(max-width:768px) { /* Put title on its own flexbox row */ .wst-header-mainblock { flex-wrap:wrap; } .wst-header-central-cell { flex:0 0 100%; order:-2; width:auto; } .wst-header-back, .wst-header-forward { width:auto; } } /* * notes block */ /* The overall notes container. */ .wst-header-notes { display:inline-block; border-collapse:collapse; border-spacing:0; empty-cells:hide; font-size:.9em; line-height:1.4; margin:0 auto 4px auto; width:100%; } /* Left-floated content. */ .wst-header-left { float:left; } endbvjhthg540or09glpy5cpeygobni Skabelon:Plain sister/styles.css 10 125746 482579 2026-10-11T14:08:36Z Johshh 9757 Oprettede siden med ".plainSister { display:block; font-size:93%; line-height:normal; list-style-type:none; list-style-image:none; list-style-position:outside; border:1px solid var(--border-color-interactive--hover, #AAA); float:right; clear:right; margin:0.5ex 0 0.5ex 0.5ex; padding:0; background:var(--background-color-base, #FFFFFF); color:var(--color-base, #202122); } .sisicon, .dabicon { padding-right:1ex }" 482579 sanitized-css text/css .plainSister { display:block; font-size:93%; line-height:normal; list-style-type:none; list-style-image:none; list-style-position:outside; border:1px solid var(--border-color-interactive--hover, #AAA); float:right; clear:right; margin:0.5ex 0 0.5ex 0.5ex; padding:0; background:var(--background-color-base, #FFFFFF); color:var(--color-base, #202122); } .sisicon, .dabicon { padding-right:1ex } 9u4b2frpymhp7399l44mvdwuwjijgut