Difference between revisions of "Module:Set page header"

From Yugipedia
Jump to: navigation, search
(Add region parameter to allow handling special cases like Set Card Lists:Boss Duel.)
(Making the region and edition matching more dynamic, less dependent on the "CG" in the page name)
 
(13 intermediate revisions by 2 users not shown)
Line 13: Line 13:
 
local UTIL = require( 'Module:Util' )
 
local UTIL = require( 'Module:Util' )
  
local LANGUAGE_ENGLISH = DATA.getLanguage( 'English' )
+
local mwTitle = mw.title
  
local mwTitle = mw.title
+
-- Object containing data on this release of the set
 +
-- (Object is called `releaseData` rather than `setData`, which is ambiguous in programming terms.)
 +
--
 +
-- @param pagename    string    The name of the current page (the list/gallery)
 +
-- @param set        string    The page name of the set
 +
-- @param name        string    The English name of the set
 +
-- @param localName  string    The name of the set in this particular print and language
 +
-- @param language    table    The language of this particular print e.g. "English", "Korean", etc.
 +
--                              (See [[Module:Data/static/language/data]] for the table structure)
 +
-- @param region      table    The distribution region of this print e.g. "European English", "Korean", etc.
 +
--                              (See [[Module:Data/static/region/data]] for the table structure)
 +
-- @param medium      table    The medium (OCG, TCG, etc.)
 +
--                              (See [[Module:Data/static/medium/data]] for the table structure)
 +
-- @param edition    table    The edition of this particular print
 +
--                              (See [[Module:Data/static/edition/data]] for the table structure)
 +
-- @param releaseDate string    The date this print was released
 +
local releaseData = {
 +
pagename = nil,
 +
set = nil,
 +
name = nil,
 +
localName = nil,
 +
language = {},
 +
region = {},
 +
medium = {},
 +
edition = nil,
 +
releaseDate = nil,
 +
isParentSet = nil,
 +
}
  
 
local function getRegion( pagename )
 
local function getRegion( pagename )
local index = pagename:match( 'CG%-(%a+)%-?' )
+
-- Get content after the first hyphen after the last `(` in the page name
 +
-- up until the next `-` or `)`
 +
-- More specifically match
 +
-- `(`
 +
-- Any amount of non-`(` non-`-`
 +
-- `-`
 +
-- Any amount of non-`(` non-`-` (Capture the text in this group)
 +
-- An optional `-`
 +
-- An optional amout of non-`(` non-`-`
 +
-- A `)`
 +
-- the end of the string
 +
local index = pagename:match( '%([^%(-]*-([^%(-]*)-?[^%(-]*%)$' )
  
 
local region = DATA.getRegion( index ) -- TODO: handle erroneous region (nil)?
 
local region = DATA.getRegion( index ) -- TODO: handle erroneous region (nil)?
Line 26: Line 64:
  
 
local function getEdition( pagename )
 
local function getEdition( pagename )
local index = pagename:match( 'CG%-%a+%-(%w+)' )
+
-- Get content after the second hyphen after the last `(` in the page name.
 +
local index = pagename:match( '%([^%(-]*-[^%(-]*-([^%(]*)%)$' )
  
 
local edition = DATA.getEdition( index ) -- TODO: handle erroneous edition (nil)?
 
local edition = DATA.getEdition( index ) -- TODO: handle erroneous edition (nil)?
Line 36: Line 75:
 
local parts = mw.text.split( pagename, '%(' )
 
local parts = mw.text.split( pagename, '%(' )
  
return table.concat( parts, '(', 1, #parts - 1 )
+
local length = #parts
 +
 
 +
return table.concat( parts, '(', 1, length == 1 and length or ( length - 1 ) )
 
end
 
end
 +
  
 
local function makeHeader( setPagename, region, edition )
 
local function makeHeader( setPagename, region, edition )
local language = DATA.getLanguage( region.index )
 
 
local medium = DATA.getMedium( region.index )
 
 
local englishName = DATA.getName(
 
setPagename,
 
LANGUAGE_ENGLISH
 
)
 
 
local localizedName = DATA.getName(
 
setPagename,
 
language
 
)
 
  
 
local header = mw.html.create( 'div' ):addClass( 'page-header' )
 
local header = mw.html.create( 'div' ):addClass( 'page-header' )
Line 59: Line 88:
 
header:tag( 'div' )
 
header:tag( 'div' )
 
:addClass( 'page-header__link' )
 
:addClass( 'page-header__link' )
:wikitext( UTIL.link( setPagename, englishName ) )
+
:wikitext( UTIL.link( releaseData.set, releaseData.name ) )
  
 
-- Localized set name:
 
-- Localized set name:
if language.index ~= LANGUAGE_ENGLISH.index and localizedName then
+
if releaseData.language.index ~= 'en' and releaseData.localName then
 
header:tag( 'div' )
 
header:tag( 'div' )
 
:addClass( 'page-header__localized' )
 
:addClass( 'page-header__localized' )
:attr( 'lang', language.index )
+
:attr( 'lang', releaseData.language.index )
:wikitext( localizedName )
+
:wikitext( releaseData.localName )
 
end
 
end
  
Line 72: Line 101:
 
header:tag( 'div' )
 
header:tag( 'div' )
 
:addClass( 'page-header__caption' )
 
:addClass( 'page-header__caption' )
:wikitext( region.full )
+
:wikitext( releaseData.region.full )
:wikitext( edition and ( ' - %s' ):format( edition.full ) )
+
:wikitext( releaseData.edition and ( ' - %s' ):format( releaseData.edition.full ) )
 +
 
 +
-- If there is a release date, show it in the header
 +
if ( releaseData.releaseDate ) then
 +
header:tag( 'div' ):wikitext( '(Release date: ' .. releaseData.releaseDate .. ')' )
 +
end
  
 
return tostring( header )
 
return tostring( header )
 
end
 
end
  
local function makeCategories( ns, region, edition )
+
local function makeCategories( ns )
return table.concat{
+
local categories = {
( '[[Category:%s %s]]' ):format( region.full, ns ),
+
( '[[Category:%s %s]]' ):format( releaseData.region.full, ns )
edition and ( '[[Category:%s %s]]' ):format( edition.full, ns ),
 
 
}
 
}
 +
 +
if ( releaseData.edition ) then
 +
table.insert( categories, ( '[[Category:%s %s]]' ):format( releaseData.edition.full, ns ) )
 +
end
 +
 +
if ( ns == 'Set Card Lists' and releaseData.isParentSet ) then
 +
table.insert( categories, '[[Category:Set Card Lists for parent sets]]' )
 +
end
 +
 +
-- Set lists with no release dates
 +
-- Excludes lists for parent sets, whose children each have individual release dates
 +
if ( ns == 'Set Card Lists' and not releaseData.releaseDate and not releaseData.isParentSet ) then
 +
table.insert( categories, '[[Category:Set Card Lists with no release date]]' )
 +
end
 +
 +
return table.concat(categories)
 +
end
 +
 +
local function setSmwData( ns, setPagename, region, edition )
 +
mw.smw.set({
 +
['Set page']    = releaseData.set,
 +
['Local name']  = releaseData.localName,
 +
['Release']      = releaseData.medium and releaseData.medium.full,
 +
['Language']    = releaseData.language.full,
 +
['Locality']    = releaseData.region and releaseData.region.full,
 +
['Edition']      = releaseData.edition and releaseData.edition.full,
 +
['Release date'] = releaseData.releaseDate
 +
})
 +
end
 +
 +
-- Fetch data from the set page
 +
-- @return table    name, localName, releaseDate
 +
local function querySetData()
 +
local results = mw.smw.ask{
 +
'[[' .. releaseData.set .. ']]',
 +
'?English name = name' ,
 +
'?' .. releaseData.language.full .. ' name = localName',
 +
'?' .. releaseData.region.full .. ' release date = releaseDate',
 +
-- Bit sloppy, but we need to fallback to this if "Worldwide English release date" is empty
 +
'?English release date = englishReleaseDate',
 +
'?-Parent set = isParentSet',
 +
mainlabel = '-'
 +
}
 +
 +
-- Reurn the first result, if there is one
 +
return results and results[ 1 ]
 +
end
 +
 +
-- Set data for the `releaseData` table based on the page name and parameters
 +
local function setReleaseData( ns, currentPageName, args )
 +
-- Set the set page equal to the supplied set
 +
-- or defaul to to the one that can be inferred from the page name
 +
releaseData.set = args.set or getSetPagename( currentPageName )
 +
 +
-- Set the region equal to the supplied region
 +
-- or default to the one that can be inferred from the page name
 +
releaseData.region = args.region
 +
and DATA.getRegion( args.region )
 +
or getRegion( currentPageName )
 +
 +
-- Set the language, based on the region
 +
releaseData.language = DATA.getLanguage( releaseData.region.index )
 +
 +
-- Set the medium based on the region
 +
releaseData.medium = DATA.getMedium( releaseData.region.index )
 +
 +
-- Set the edition based on the page name
 +
releaseData.edition = getEdition( currentPageName )
 +
 +
-- Query the set page to find more information
 +
local queriedData = querySetData()
 +
 +
-- Exit early if no results were found
 +
if ( not queriedData ) then
 +
-- todo: Tracking category
 +
return
 +
end
 +
 +
-- Update the `releaseData` object based on the results of the query
 +
-- except where overwritten by the `args`.
 +
releaseData.name        = queriedData.name
 +
releaseData.localName  = args.name        or queriedData.localName
 +
releaseData.isParentSet = queriedData.isParentSet and true or false
 +
 +
-- For now, only do the release date for list pages
 +
-- Don't add it to parent set lists e.g. the overall "Shonen Jump promotional cards" list
 +
-- which have multiple releases, each with their own set list.
 +
if ( ns == 'Set Card Lists' and not queriedData.isParentSet ) then
 +
releaseData.releaseDate = args.releaseDate or queriedData.releaseDate
 +
 +
-- If 'Worldwide English' and the `releaseDate` is empty, check the `englishReleaseDate`
 +
if ( not releaseData.releaseDate and releaseData.region.full == 'Worldwide English' ) then
 +
releaseData.releaseDate = queriedData.englishReleaseDate
 +
end
 +
end
 
end
 
end
  
 
function main( args )
 
function main( args )
 +
-- Get the name of the current page (distinct from the name of the set page)
 
local currentTitle = args.pagename
 
local currentTitle = args.pagename
 
and mwTitle.new( args.pagename )
 
and mwTitle.new( args.pagename )
Line 92: Line 221:
 
local ns = currentTitle.subjectNsText
 
local ns = currentTitle.subjectNsText
  
 +
-- Skip everything if this is in the main namespace
 
if not UTIL.trim( ns ) then
 
if not UTIL.trim( ns ) then
 
return
 
return
 
end
 
end
  
local pagename = currentTitle.text
+
-- Update the `releaseData` object based on information from the page name
 
+
-- and the supplied arguments.
local region = args.region and DATA.getRegion( args.region ) or getRegion( pagename )
+
setReleaseData( ns, currentTitle.text, args )
 
 
local edition = getEdition( pagename )
 
  
local setPagename = args.set or getSetPagename( pagename )
+
-- Get the header wikitext
 +
local header = makeHeader()
  
local header = makeHeader( setPagename, region, edition )
+
-- Get the categories wikitext
 +
local categories = makeCategories( ns )
  
local categories = makeCategories( ns, region, edition )
+
-- Set SMW properties
 +
setSmwData()
  
 +
-- Return the wikitext to render
 
return table.concat{
 
return table.concat{
 
'__NOTOC__',
 
'__NOTOC__',

Latest revision as of 22:03, 4 October 2023

-- <pre>
--[=[Doc
@module Set page header
@description 
@author [[User:Becasita]]
@contact [[User talk:Becasita]]
TODO:
- Validate stuff?
- Create instance?
]=]

local DATA = require( 'Module:Data' )
local UTIL = require( 'Module:Util' )

local mwTitle = mw.title

-- Object containing data on this release of the set
-- (Object is called `releaseData` rather than `setData`, which is ambiguous in programming terms.)
--
-- @param pagename    string    The name of the current page (the list/gallery)
-- @param set         string    The page name of the set
-- @param name        string    The English name of the set
-- @param localName   string    The name of the set in this particular print and language
-- @param language    table     The language of this particular print e.g. "English", "Korean", etc.
--                              (See [[Module:Data/static/language/data]] for the table structure)
-- @param region      table     The distribution region of this print e.g. "European English", "Korean", etc.
--                              (See [[Module:Data/static/region/data]] for the table structure)
-- @param medium      table     The medium (OCG, TCG, etc.)
--                              (See [[Module:Data/static/medium/data]] for the table structure)
-- @param edition     table     The edition of this particular print
--                              (See [[Module:Data/static/edition/data]] for the table structure)
-- @param releaseDate string    The date this print was released
local releaseData = {
	pagename = nil,
	set = nil,
	name = nil,
	localName = nil,
	language = {},
	region = {},
	medium = {},
	edition = nil,
	releaseDate = nil,
	isParentSet = nil,
}

local function getRegion( pagename )
	-- Get content after the first hyphen after the last `(` in the page name
	-- up until the next `-` or `)`
	-- More specifically match
	-- `(`
	-- Any amount of non-`(` non-`-`
	-- `-`
	-- Any amount of non-`(` non-`-` (Capture the text in this group)
	-- An optional `-`
	-- An optional amout of non-`(` non-`-`
	-- A `)`
	-- the end of the string
	local index = pagename:match( '%([^%(-]*-([^%(-]*)-?[^%(-]*%)$' )

	local region = DATA.getRegion( index ) -- TODO: handle erroneous region (nil)?

	return region
end

local function getEdition( pagename )
	-- Get content after the second hyphen after the last `(` in the page name.
	local index = pagename:match( '%([^%(-]*-[^%(-]*-([^%(]*)%)$' )

	local edition = DATA.getEdition( index ) -- TODO: handle erroneous edition (nil)?

	return edition
end

local function getSetPagename( pagename )
	local parts = mw.text.split( pagename, '%(' )

	local length = #parts

	return table.concat( parts, '(', 1, length == 1 and length or ( length - 1 ) )
end


local function makeHeader( setPagename, region, edition )

	local header = mw.html.create( 'div' ):addClass( 'page-header' )

	-- Link to set page:
	header:tag( 'div' )
		:addClass( 'page-header__link' )
		:wikitext( UTIL.link( releaseData.set, releaseData.name ) )

	-- Localized set name:
	if releaseData.language.index ~= 'en' and releaseData.localName then
		header:tag( 'div' )
			:addClass( 'page-header__localized' )
			:attr( 'lang', releaseData.language.index )
			:wikitext( releaseData.localName )
	end

	-- Region and edition
	header:tag( 'div' )
		:addClass( 'page-header__caption' )
		:wikitext( releaseData.region.full )
		:wikitext( releaseData.edition and ( ' - %s' ):format( releaseData.edition.full ) )

	-- If there is a release date, show it in the header
	if ( releaseData.releaseDate ) then
		header:tag( 'div' ):wikitext( '(Release date: ' .. releaseData.releaseDate .. ')' )
	end

	return tostring( header )
end

local function makeCategories( ns )
	local categories = {
		( '[[Category:%s %s]]' ):format( releaseData.region.full, ns )
	}
	
	if ( releaseData.edition ) then
		table.insert( categories, ( '[[Category:%s %s]]' ):format( releaseData.edition.full, ns ) )
	end

	if ( ns == 'Set Card Lists' and releaseData.isParentSet ) then
		table.insert( categories, '[[Category:Set Card Lists for parent sets]]' )
	end

	-- Set lists with no release dates
	-- Excludes lists for parent sets, whose children each have individual release dates
	if ( ns == 'Set Card Lists' and not releaseData.releaseDate and not releaseData.isParentSet ) then
		table.insert( categories, '[[Category:Set Card Lists with no release date]]' )
	end

	return table.concat(categories)
end

local function setSmwData( ns, setPagename, region, edition )
	mw.smw.set({
		['Set page']     = releaseData.set,
		['Local name']   = releaseData.localName,
		['Release']      = releaseData.medium and releaseData.medium.full,
		['Language']     = releaseData.language.full,
		['Locality']     = releaseData.region and releaseData.region.full,
		['Edition']      = releaseData.edition and releaseData.edition.full,
		['Release date'] = releaseData.releaseDate
	})
end

-- Fetch data from the set page
-- @return table    name, localName, releaseDate
local function querySetData()
	local results = mw.smw.ask{
		'[[' .. releaseData.set .. ']]',
		'?English name = name' ,
		'?' .. releaseData.language.full .. ' name = localName',
		'?' .. releaseData.region.full .. ' release date = releaseDate',
		-- Bit sloppy, but we need to fallback to this if "Worldwide English release date" is empty
		'?English release date = englishReleaseDate',
		'?-Parent set = isParentSet',
		mainlabel = '-'
	}

	-- Reurn the first result, if there is one
	return results and results[ 1 ]
end

-- Set data for the `releaseData` table based on the page name and parameters
local function setReleaseData( ns, currentPageName, args )
	-- Set the set page equal to the supplied set
	-- or defaul to to the one that can be inferred from the page name
	releaseData.set = args.set or getSetPagename( currentPageName )

	-- Set the region equal to the supplied region
	-- or default to the one that can be inferred from the page name
	releaseData.region = args.region
		and DATA.getRegion( args.region )
		or getRegion( currentPageName )

	-- Set the language, based on the region
	releaseData.language = DATA.getLanguage( releaseData.region.index )

	-- Set the medium based on the region
	releaseData.medium = DATA.getMedium( releaseData.region.index )

	-- Set the edition based on the page name
	releaseData.edition = getEdition( currentPageName )

	-- Query the set page to find more information
	local queriedData = querySetData()

	-- Exit early if no results were found
	if ( not queriedData ) then
		-- todo: Tracking category
		return
	end

	-- Update the `releaseData` object based on the results of the query
	-- except where overwritten by the `args`.
	releaseData.name        = queriedData.name
	releaseData.localName   = args.name        or queriedData.localName
	releaseData.isParentSet = queriedData.isParentSet and true or false

	-- For now, only do the release date for list pages
	-- Don't add it to parent set lists e.g. the overall "Shonen Jump promotional cards" list
	-- which have multiple releases, each with their own set list.
	if ( ns == 'Set Card Lists' and not queriedData.isParentSet ) then
		releaseData.releaseDate = args.releaseDate or queriedData.releaseDate

		-- If 'Worldwide English' and the `releaseDate` is empty, check the `englishReleaseDate`
		if ( not releaseData.releaseDate and releaseData.region.full == 'Worldwide English' ) then
			releaseData.releaseDate = queriedData.englishReleaseDate
		end
	end
end

function main( args )
	-- Get the name of the current page (distinct from the name of the set page)
	local currentTitle = args.pagename
		and mwTitle.new( args.pagename )
		or mwTitle.getCurrentTitle()

	local ns = currentTitle.subjectNsText

	-- Skip everything if this is in the main namespace
	if not UTIL.trim( ns ) then
		return
	end

	-- Update the `releaseData` object based on information from the page name
	-- and the supplied arguments.
	setReleaseData( ns, currentTitle.text, args )

	-- Get the header wikitext
	local header = makeHeader()

	-- Get the categories wikitext
	local categories = makeCategories( ns )

	-- Set SMW properties
	setSmwData()

	-- Return the wikitext to render
	return table.concat{
		'__NOTOC__',
		header,
		categories,
	}
end

return setmetatable({
	main = function( frame )
		local args = frame:getParent().args

		return main( args )
	end,
}, {
	__call = function( t, args )
		mw.log( main( args ) )
	end,
})
-- </pre>