Открыть главное меню
Документация Документация

Запускается из шаблона {{обавторе}}, рендерит шапку и подвал страницы о персоне.

Основной блок внизу: function p.render. Создаётся карточка о персоне (infobox), ссылки на братские проекты, ссылки на персоналии в энциклопедиях Викитеки, блок внизу с дополнительными ссылками и нормативным контролем, категоризация.

Используются Модуль:Навигация-мини, Модуль:Другие источники.

ToDo
  • По возможности заменить вызовы шаблонов на код Lua
  • Учесть, что в Викиданных свойства могут иметь несколько значений. Тогда брать с rank=='preferred', если они равны то первое. Пример в реализации выбора изображений.
local p = {}
local is_author_page = true

-- объект с методами. здесь сборка результата
-- заметка: в Lua метод из метода вызывается с self, напр.: self.div_m5(self, s)
local about = {
		t = {},  -- текст
		c = {},  -- категории
	}
function about:result() 
	self:change_wd_categories()
	return table.concat(self.t) .. table.concat(self.c) end
function about:add(s) if type(s) == 'string' then table.insert(self.t, s) 
	elseif type(s) == 'table' then table.insert(self.t, table.concat(s)) end end
function about:wrap_div_m5(s)
	local _s; if type(s) == 'string' then _s = s elseif type(s) == 'table' then _s = table.concat(s) end
	self.add(self, {'<div style="margin:5px;">', _s, '</div>'}) end
function about:add_category(s) table.insert(self.c, '[[Категория:'..s..']]') end
function about:add_category_author_wd(s) table.insert(self.c, '[[Категория:Авторы:Ссылка из Викиданных:'..s..']]') end
function about:add_category_manual_link(s) table.insert(self.c, '[[Категория:Авторы:Ручная ссылка:'..s..']]') end
function about:change_wd_categories() 
	-- Изменение общих категорий устанавливаемых в Модуль:Другие источники и Модуль:Навигация-мини на категории типа 'Авторы:'
	-- mw.logObject(self.c, "self.c")
	local cats = {}
	for _, c in pairs(self.c) do
		if not mw.ustring.find(c, ':Викиданные$') then
			c = c:gsub('Категория:Ссылка из Викиданных:', 'Категория:Авторы:Ссылка из Викиданных:')
			c = c:gsub('Категория:Ручная ссылка:', 'Категория:Авторы:Ручная ссылка:')
			c = c:gsub('Категория:Ручная ссылка совпадает со ссылкой из Викиданных:([^%]]+)', 'Категория:Авторы:Ручная ссылка:%1:Совпадает со ссылкой из Викиданных')
		end
		table.insert(cats, c)
	end
	self.c = cats
end
function names_family(names, family) return mw.text.trim( table.concat({names,family},' ') ) end

-- подготовка параметров
local function args_normalization(frame)
	local pargs = frame:getParent().args
	local title_obj = mw.title.getCurrentTitle()
	local d = {
		pagename = title_obj.text,
		namespace = title_obj.namespace,
		edo = frame:expandTemplate{ title = 'ЕДО'}, -- {{ЕДО}}
		entity = mw.wikibase.getEntity(),  -- for test 'Q13054180', 'Q43718'
		
		family = pargs['ФАМИЛИЯ'] or '',
		names = pargs['ИМЕНА'] or '',
		names_variants = is(pargs['ВАРИАНТЫИМЁН']),
		date_birth = is(pargs['ДАТАРОЖДЕНИЯ']),
		date_death = is(pargs['ДАТАСМЕРТИ']),
		place_birth = is(pargs['МЕСТОРОЖДЕНИЯ']),
		place_death = is(pargs['МЕСТОСМЕРТИ']),
		desc = is(pargs['ОПИСАНИЕ']),
		other = is(pargs['ДРУГОЕ']),
		image = is(pargs['ИЗОБРАЖЕНИЕ']),
		wikipedia = is(pargs['ВИКИПЕДИЯ']),
		wikiquote = is(pargs['ВИКИЦИТАТНИК']),
		commons = is(pargs['ВИКИСКЛАД']),
		wikispecies = is(pargs['ВИКИВИДЫ']),
		wikinews = is(pargs['ВИКИНОВОСТИ']),
		wikilivres = is(pargs['ВИКИЛИВР']),
		wikilivres_ru = is(pargs['ВИКИЛИВРУ']),
		disambig = is(pargs['НЕОДНОЗНАЧНОСТЬ']),
		esbe = is(pargs['ЭСБЕ']),
		mesbe = is(pargs['МЭСБЕ']),
		eebe = is(pargs['ЕЭБЕ']),
		nes = is(pargs['НЭС']),
		el = is(pargs['ЭЛ']),
		resb = is(pargs['РЭСБ']),
		beu = is(pargs['БЭЮ']),
		beu2 = is(pargs['БЭЮ2']),
		bse1 = is(pargs['БСЭ1']),
		rbs = is(pargs['РБС']),
		pbe = is(pargs['ПБЭ']),
		ve = is(pargs['ВЭ']),
		msr = is(pargs['МСР']),
		rskd = is(pargs['РСКД']),
		bbsrp = is(pargs['ББСРП']),
		esg = is(pargs['ЭСГ']),
		scolrs = is(pargs['СЧОЛРС']),
		britannica = is(pargs['Britannica']),
		lentapedia = is(pargs['ЛЕНТАПЕДИЯ']),
		category = pargs['КАТЕГОРИЯ'],
		year_death = is(pargs['ГОД']),
		GPW = is(pargs['ВОВ']),
		yrehab = is(pargs['ГОДРЕАБИЛИТАЦИИ']),
	}
	return d
end

-- карточка
function render_infobox(d, frame)
	local infobox = {
		t = {
			'<table class="prettytable" style="width:250px;float:right;font-size:95%;margin:0 0 1em 1em;">',
			'<tr><th style="background-color:#DDDDFF;font-size:large;text-align:center;">',
			'<span id="ws-name">',names_family(d.names, d.family),'</span>','</th></tr>'}
	}
	function infobox:result() return table.concat(self.t) end
	function infobox:add(s) table.insert(self.t, s) end
	function infobox:add_td(s) if is(s) then self.add(self, '<tr align=center><td>'..s..'</td></tr>') end end
	
	-- изображение
	local image_link_wd, images_wd
	if type(d.entity) == 'table' then
		images_wd = d.entity:getBestStatements( 'P18' )
		if images_wd[1] and images_wd[1]["mainsnak"]["datavalue"] then image_link_wd = images_wd[1]["mainsnak"]["datavalue"]["value"] end
	end
	if d.image then 
		about:add_category_manual_link('Изображение')
		infobox:add_td(frame:expandTemplate{ title = 'wikidata/p18', args = {[1]=d.image, size='220px'} })
	elseif image_link_wd then 
		about:add_category_author_wd('Изображение') 
		infobox:add_td(frame:expandTemplate{ title = 'wikidata/p18', args = {[1]=image_link_wd, size='220px'} })
	end
	if d.image and d.image == image_link_wd then about:add_category_manual_link('Изображение:Совпадает со ссылкой из Викиданных') end
	
	-- варианты имён
	if d.names_variants then infobox:add_td(d.names_variants) end

	-- даты и места рождения и смерти
	local db = d.date_birth or frame:expandTemplate{ title = 'wikidata/p569'} --args = {tostring(d.date_birth), tostring(d.date_death)}
	local dd = d.date_death or frame:expandTemplate{ title = 'wikidata/p570', args = {d.date_death or d.date_birth, d.date_death}}
	local pb = d.place_birth or frame:expandTemplate{ title = 'wikidata/p19', args = {d.place_birth or ''}}
	local pd = d.place_death or frame:expandTemplate{ title = 'wikidata/p20', args = {d.place_death}}
	if is(db) then
		local s = 'р. <span id="ws-birthdate">' ..db ..'</span>'
		if is(pb) then s = s..', '..pb end
		infobox:add_td(s)	end
	if is(dd) then 
		local s = 'ум. <span id="ws-deathdate">' ..dd ..'</span>'
		if is(pd) then s = s..', '..pd end
		infobox:add_td(s)	end
	
	if d.desc then infobox:add_td('<span id="ws-description">'..d.desc..'</span>') end
	if d.other then infobox:add_td(d.other) end

	infobox:add('</table>')
	-- mw.logObject(infobox,"infobox")
	return infobox:result()
end	


-- ссылки на братские проекты и соответствующая категоризация
-- Проверка на ручные ссылки и Проверка совпадения ручной ссылки со ссылкой из Викиданных
function links_to_wikiprojects(d, frame)
	
	local dataset = require( "Модуль:Навигация-мини" ).scrape_data( frame, is_author_page)
	local names_family = names_family(d.names, d.family)
	
	-- оформление
	if #dataset.wlinks_data > 0 then 
		local links = {}
		for _, v in pairs(dataset.wlinks_data) do
			local project, s_link, manual_link, wd_link = v[1], v[2], v[3], v[4]
			local s  = {
					wiki = 'Биография в Википедии',
					commons = 'Изображения и медиаданные на Викискладе',
					wikinews = names_family..' в Викиновостях',
					specieswiki = names_family ..' в Викивидах',
					wikiquote = 'Сборник цитат в Викицитатнике',
					wikilivres = names_family..' в Wikilivres',
					wikilivres_ru = names_family..' в Wikilivres.ru',
					-- wikisource = 
					-- wikivoyage = 
					-- wikidata = 
					-- wikidictionary = 
					-- wikibooks = 
					-- wikiversity = 
				}
			local s_title = s[project.project]
			if s_title and s_link then  -- ограничение ссылок на проекты
				about:wrap_div_m5({
					'[[Файл:'..project.logo..'|20px|link='..s_link ..']]&nbsp;',
					'[['..s_link..'|'..s_title..']]',
					'<span id="ws-wikipedia" style="display: none;">'..s_link..'</span>' })
			end
		end
	end

	-- категории
	for _, c in pairs(dataset.categories_raw) do about:add_category(c) end
	
end


-- рендеринг ссылок на словарные персоналии об авторе и соответствующая категоризация
function other_sources_links(d, frame)
	local test = true
	local dataset = require( "Модуль:Другие источники" ).scrapeOtherSources( frame, is_author_page, test )
	if #dataset.wlinks == 0 then return '' end
	local x = {}; function add(s) table.insert(x, s) end

	-- сборка ссылок
	if #dataset.wlinks > 0 then
		add('[[Файл:Wikisource-logo.svg|20px|link=]] ')
		if d.wikisource then add('[['..d.wikisource..'|Материалы об авторе в Викитеке:]]&nbsp;') else add('Биография в ') end
		add( table.concat(dataset.wlinks, ' &bull;&nbsp;') ) -- конвертация списка в строку с разделителем
			
	elseif d.wikisource then 
		add('[['..d.wikisource..'|Материалы об авторе в Викитеке]]')
	end

	about:wrap_div_m5(x)
	
	for _, c in pairs(dataset.categories_raw) do about:add_category(c) end
end

-- function copyright(frame)
-- 	local copyright = require('Модуль:Copyright')
-- 	return copyright.template(frame)
-- end

function p.render(frame)
	local d = args_normalization(frame)  -- параметры шаблона
	d.entity = mw.wikibase.getEntity()
	
	if d.disambig then about:add({
		'<div style="font-size:0.9em; margin-left:2em;" class="similar">',
		"''См. [["..d.disambig.."|других авторов с подобными именами]].''",
		'</div>'})
	end
	
	-- {{Footer|{{Внешние ссылки|nocat=yes}}}}
	about:add({'<div id="ws-footer" style="display: none">',
		frame:expandTemplate{ title = 'Внешние ссылки', args = {nocat='yes'}},
		'</div>'})
	-- frame:extensionTag{ name = 'div', 
	-- 	content = frame:expandTemplate{ title = 'Внешние ссылки', args = {nocat='yes'}}, 
	-- 	args = { id = 'ws-footer', style = 'display: none' } }
	
	about:add('<br clear="all" style="line-height:0px" />')
	
	-- карточка
	about:add(render_infobox(d, frame))
	
	-- ссылки на братские проекты и соответствующая категоризация
	about:add(links_to_wikiprojects(d, frame))
	
	-- ссылки на персоналии в словарях Викитеки
	about:add(other_sources_links(d, frame))
	
	if is(d.google) then 
		about:wrap_div_m5({
			'[[Файл:Google free icon.svg|20px|link=w:Google]]',
			'[http://books.google.com/books'..d.google..' Книги на сайте books.google.com]'})
		about:add_category_manual_link('Google')
	end

	local family = is(d.category) or is(d.family)
	if family then
			local cnames = ''; if d.names~='' then cnames = ', '..d.names end
			about:add(frame:callParserFunction('DEFAULTSORT:'..family..cnames))
			about:add({'<span id="ws-key" style="display: none;">', family, cnames, '</span>'})
			about:add_category('Авторы-'..mw.ustring.upper(mw.ustring.sub(family, 1, 1))) -- с первой заглавной буквой фамилии
			if not is(d.category) then about:add_category(names_family(d.names, family)..'|*') else  about:add_category(d.category..'|*') end
			about:add_category('Все авторы|'..family)
	else 
		about:add_category('Авторы без параметра ФАМИЛИЯ в шаблоне Обавторе')	
	end
	if is(d.category) then about:add_category('Авторы:Используется параметр КАТЕГОРИЯ') end
	if d.category == '' then about:add_category('Авторы:Пустой параметр КАТЕГОРИЯ') end

	if d.namespace == 0 then
		if d.entity == nil or not (d.entity["claims"] and d.entity["claims"]['P21']) then -- P21 = пол персоны
			about:add_category('Авторы:Не персона') 
		end
	end

	-- шаблон АП
	-- local copyright = require('Модуль:Copyright')
	-- return copyright.template(frame)
	-- about:add(copyright(frame))

	result = about:result()
	-- mw.logObject(about,"about")
	-- mw.logObject(result,"result")
	return result 
end

	
-- проверка переменной, возврат её или nil если пустая
function is(v) if (v=='' or v==nil) then return nil else return v end end
	
return p