Module:Part

Documentation for this module may be created at Module:Part/doc

local p = {}

function p.main(frame)
	local html, template, number, page, namespace, ns, fullname, root, display_title, levels, parent, nav, query_prev, query_next, credits, credit_line, is_altered, varlua

	template = frame:getParent().args
	weight = template[1] or '1'
	page = mw.title.getCurrentTitle()
	namespace = page.namespace
	ns = page.nsText
	fullname = page.fullText
	root = page.rootText
	subpage = page.subpageText
	display_title = frame:preprocess('{{DISPLAYTITLE:' .. subpage .. '}}')
	levels = mw.text.split(fullname, '/') or {}
	parent = table.concat(levels, '/', 1, #levels - 1)

	if ns ~= '' then
		root = string.format('%s:%s', ns, root)
	end

	if weight ~= '' then
		frame:preprocess('{{DEFAULTSORT:{{padleft:' .. weight .. '|6}}. ' .. root .. '}}')
	end

	local rootProperties = mw.smw.ask({
		'[[' .. root .. ']][[Modification date::+]]',
		'?Is collaborative research',
		'?Area',
		'mainlabel=-',
	}) or {}

	local isCollabResearch = false
	local area = ''

	if #rootProperties > 0 then
		isCollabResearch = rootProperties[1]['Is collaborative research'] or false
		area = rootProperties[1]['Area']
	end

	local displayBanner = false
	displayBanner = isCollabResearch

	mw.smw.set({
		['Is subpage of'] = root,
		['Has level'] = #levels,
		['Has weight'] = weight,
		['Has parent page'] = parent,
	})

	local function querySibling(weightOperator, order)
		local result = mw.smw.ask{
			'[[Is subpage of::' .. root .. ']][[Has weight::' .. weightOperator .. weight .. ']]',
			'mainlabel=Page',
			'sort=Has weight',
			'order=' .. order,
			'limit=1',
			'link=none'
		} or {}

		if #result == 0 or not result[1]['Page'] then
			return '<span></span>'
		end

		return result[1]['Page']
	end

	query_prev = querySibling('<<', 'desc')
	query_next = querySibling('>>', 'asc')

	html = mw.html.create()

	local articlepath = html:tag('div')
		:attr('id', 'article-path')
		:addClass('interface d-flex align-items-center justify-content-between')
		:addClass('font-weight-bold text-uppercase d-print-none screenonly noprint')

	articlepath:tag('span'):attr('id', 'observatory-path'):addClass('d-print-none noprint'):wikitext(
		'[['.. frame:preprocess('{{int:mainpage}}|{{SITENAME}}') .. ']] &raquo;&nbsp;'
		.. '[['	.. area .. ']] &raquo;&nbsp;'
		.. '[[' .. root .. ']]'
	)

	articlepath:tag('span'):wikitext(frame:expandTemplate({
		title = 'Article buttons',
		args = {
			['Area'] = area,
			['DeepArea'] = area
		},
	}))

	nav = html:tag('div')
		:attr('id', 'inpagenav')
		:addClass('d-flex flex-column flex-md-row justify-content-between')
		:addClass('rounded-0 interface small py-3 align-items-center text-center')
		:css({
			['gap'] = '0 1rem',
		})

	nav:tag('div'):addClass('prev col px-0 text-center text-md-left')
		:tag('span')
			:tag('span'):addClass('inpagenav-label'):wikitext('Prev: '):done()
			:tag('span'):addClass('inpagenav-link-wrapper'):wikitext(query_prev):done()
		:done()
	
	nav:tag('div'):addClass('next col px-0 text-center text-md-right')
		:tag('span')
			:tag('span'):addClass('inpagenav-label'):wikitext('Next: '):done()
			:tag('span'):addClass('inpagenav-link-wrapper'):wikitext(query_next):done()
		:done()

	local function showCollabBanner(displayBanner)
		local banner = mw.html.create()
		if displayBanner == true then
			local contactUrl = frame:preprocess(
				'[{{fullurl:Special:Contact/contactauthor|author={{anchorencode:{{#show:{{#var:namespace}}{{ROOTPAGENAME}}|?Text author|link=none}}}}&article={{urlencode:{{ROOTPAGENAME}}}}&hashtag=collaborativeresearch&hosturl={{fullurl:{{ROOTPAGENAME}}}}}} <span class="mw-ui-button mw-ui-progressive text-nowrap" title="Familiar with this subject? The author invites you to help research and contribute to this page">Collaborative Research</span>]'
			)
			banner
				:tag('div')
				:addClass('collaborative-research mt-4')
				:tag('div')
				:addClass(
					'd-flex flex-column flex-md-row justify-content-between align-items-md-center w-100 mt-4 mt-md-0 mb-3 plainlinks'
				)
				:tag('div')
				:addClass('small')
				:wikitext(
					[=['''''Familiar with this subject?'''''<br>''The author invites you to help research and contribute to this page.''']=]
				)
				:done()
				:tag('div')
				:addClass('d-flex mt-2 mt-md-0 ml-auto w-min-content')
				:wikitext(contactUrl)
				:done()
				:done()
		end
		return tostring(banner)
	end

	local scb = showCollabBanner(displayBanner)

	html:tag('div'):wikitext(scb)

	local footer = mw.smw.ask({
		'[[' .. root .. ']]',
		'mainlabel=-',
		'?Credit line',
		'?Is altered',
		'?URL of the source#',
	}) or {}

	local widget = frame:callParserFunction('#widget', 'nositesub')

	local printfooter =
		html:tag('div'):attr('id', 'creditline'):addClass('border-top py-3 my-3'):wikitext(widget .. scb)

	for _, item in ipairs(footer) do
		local creditline = item['Credit line'] or ''
		local isaltered = item['Is altered'] or false
		local rurl = item['URL of the source'] or ''

		if creditline ~= '' then
			printfooter:tag('div'):addClass('small text-muted interface mb-3'):wikitext(creditline)
		end

		if isaltered == true then
			local encodedSource = frame:preprocess('{{urlencode:' .. rurl .. '|WIKI}}')
			local referSource = ''
			if rurl ~= '' then
				referSource = string.format(
					'%s [%s %s].',
					'To find the original source material as it was originally written and/or formatted, please ',
					encodedSource,
					' click here'
				)
			end

			printfooter:tag('div'):attr('id', 'is_altered'):wikitext(
				'Please note that the original source '
					.. 'material has been altered by a human editor or was '
					.. 'human-edited with AI-assist to be easier to read '
					.. 'and search for on the Observatory. '
					.. referSource
			)
		end
	end

	local authors = frame:callParserFunction('#show', root, '?Text author', 'valuesep=;')

	local source = frame:callParserFunction('#show', root, '?Source', 'valuesep=;')

	local authorsTable = mw.text.split(authors, ';') or {}

	if #authorsTable > 0 then
		local tabone = html:tag('div'):attr('id', 'article-authors')

		for _, author in ipairs(authorsTable) do
			local encodedAuthorPage = frame:preprocess('{{urlencode:' .. author .. '}}')
			local photo =
				frame:callParserFunction('#show', author, '?Has photo', 'link=none', 'default=File:Johndoe.png')

			local imagepath = frame:preprocess('{{filepath:{{PAGENAME:' .. photo .. '}}}}')

			local authorsection = 'Classics'
			if namespace == 0 then
				authorsection = 'Observatory'
			end

			local formlink = frame:callParserFunction(
				'#formredlink',
				'form=Author',
				'link text=' .. author,
				'existing page link text=' .. author,
				'Author[Section]=' .. authorsection,
				'target=' .. author
			)

			local author_bio = frame:callParserFunction('#show', author, '?Biography') or ''

			local card = tabone:tag('div'):addClass('author-card')

			local imageblock = card:tag('div'):addClass('author-card-img-top'):attr('data-bg', imagepath)

			local plane = frame:preprocess(
				'[{{fullurl:Special:Contact/contactauthor|author='
					.. encodedAuthorPage
					.. '}} <i class="fas fa-paper-plane" title="Contact author"></i>]'
			)

			local contact = card:tag('div')
				:attr('id', 'contactauthor')
				:attr('title', 'Contact author')
				:addClass('plainlinks')
				:wikitext(plane)

			local footer = card:tag('div'):addClass('card-body')

			footer:tag('div'):addClass('card-title interface'):wikitext(formlink)

			footer:tag('div'):addClass('card-subtitle'):wikitext(author_bio)
		end
	end

	local source_table = {}

	if source ~= nil then
		source_table = mw.text.split(source, ';')
	end

	if namespace == '3220' then
		table.insert(source_table, 'Public Domain')
	end

	if #source_table > 0 then
		local sidesource = html:tag('div'):attr('id', 'article-sources')

		local source_label = ''
		if #source_table > 1 then
			source_label = 'SOURCES'
		else
			source_label = 'SOURCE'
		end

		sidesource
			:tag('div')
			:addClass('article-toc-section interface font-weight-bold')
			:wikitext(source_label)
			:done()
			:tag('div')
			:addClass('my-2')
			:done()

		local list = sidesource:tag('div'):addClass('interface')

		for _, item in ipairs(source_table) do
			local formlink
			if item == 'Public Domain' then
				formlink = item
			else
				formlink = frame:callParserFunction(
					'#formredlink',
					'form=Organization',
					'link text=' .. item,
					'existing page link text=' .. item,
					'target=' .. item
				)
			end
			list:tag('div'):wikitext(formlink)
		end
	end

	html:tag('div')
		:attr('id', 'tab2-content')
		:addClass('hideable interface')
		:wikitext(frame:expandTemplate({ title = 'Classics subpages', args = {} }))

	html:wikitext('[[Category:Parts]]')

	return tostring(html)
end

return p