Module:Sandbox/Chao: Difference between revisions

From BlazBlue Wiki
mNo edit summary
m (insert subheader only when there are images to include below it)
 
(63 intermediate revisions by the same user not shown)
Line 2: Line 2:
{{#invoke:Sandbox/Chao|GallerySection|character=Noel Vermillion|section=Portraits}}
{{#invoke:Sandbox/Chao|GallerySection|character=Noel Vermillion|section=Portraits}}
simulate passing a frame to the function in the console with:
simulate passing a frame to the function in the console with:
myFrame = { args = { character='Noel Vermillion', section='Portraits' } }
myFrame = { args = { character='Noel Vermillion' } }
=p.main(myFrame)
=p.GallerySection ( myFrame )
=p.GallerySection ( myFrame )
=p.testExpandTemplate( myFrame )
=p.testExpandTemplate( myFrame )
=p.render(myFrame)


local itemData = mw.loadData('Module:ItemData')
--]]
--]]


local p = {}
local cargo = mw.ext.cargo
local cargo = mw.ext.cargo


local sections = {
-------------------------------------
['Arcade'] = {
-- Gallery Section Class
{
-------------------------------------
template = 'Gallery Section (Cargo)',
 
source = 'BlazBlue: Calamity Trigger',
local GalleryTemplate = {}
section = 'Arcade Mode',
GalleryTemplate.__index = GalleryTemplate
header="plain",
 
},{
GalleryTemplate.fields = {
template = 'Gallery Section (Cargo)',
character = true,
source = 'BlazBlue: Continuum Shift',
source = true,
section = 'Arcade Mode',
section = true,
header="plain",
limit = true,
},{
widths = true,
template = 'Gallery Section (Cargo)',
header = true,
source = 'BlazBlue: Chrono Phantasma',
title = true,
section = 'Arcade Mode',
sort = true,
header="plain",
see_all = true,
}
see_cameos = true,
},
--Gallery Section (BBRadio)
['Story'] = {
season = true,
{
episode = true,
template = 'Gallery Section (Cargo)',
widths = true,
source = 'BlazBlue: Calamity Trigger',
--Gallery Section
section = 'Story',
cat = true,
header="plain",
cat2 = true,
}
--Misc/Shared
}
count_all = true,
count_cameos = true,
images_in_section = true,
}
 
GalleryTemplate.templateMethods = {
['Gallery Section (Cargo)'] = 'makeGallerySectionCargo',
['Gallery Section (BBRadio)'] = 'makeGallerySectionBBRadio',
['Gallery Section'] = 'makeGallerySection',
}
}


function p.render(frame)
function GalleryTemplate.new(frame, templateType, params)
text = {}
local self = setmetatable({}, GalleryTemplate)
_char = frame.args['character'] or ''
self.templateType= templateType
self.frame = frame
for k,v in pairs (sections) do
for field in pairs(GalleryTemplate.fields) do
section = k
self[field] = params[field] or ''
end
 
self.images_in_section = 0
self.cat = params.category or ''
if (params.character == nil)
then self.character = frame.args.character or ''
else self.character = params.character or ''
end
return self
end
 
function GalleryTemplate:__tostring()
local method = GalleryTemplate.templateMethods[self.templateType]
if method then
return self[method](self)
end
return ''
end


-- v is a table of templates in this section
function GalleryTemplate.makeGallerySectionCargo(self)
t = {}
local expanded_template = nil
for k2,v2 in pairs (v) do


--fill in any missing template arguments
self.character = cargo_escape(self.character)
v2.character = _char
v2.source = v2.source or ''
v2.section = v2.section or ''
v2.limit = v2.limit or ''
v2.widths = v2.widths or ''
v2.header = v2.header or ''
v2.title = v2.title or ''
v2.sort = v2.sort or ''
v2.see_all = v2.see_all or ''
v2.see_combos = v2.see_combos or ''


if v2.template == 'Gallery Section (Cargo)' then
self.count_all = GalleryTemplate._countImages_GallerySectionCargo(self,false) or 0
v2.count_all = p.countImagesCargo(v2, false) or 0
self.count_cameos = GalleryTemplate._countImages_GallerySectionCargo(self,true) or 0
v2.count_cameos = p.countImagesCargo(v2, true) or 0
local total_images = self.count_all + self.count_cameos
total_images = v2.count_all + v2.count_cameos
if self.count_all > 0 then
if total_images > 0 then
self.see_all = 'y'
table.insert(t, dump(v))
end
table.insert(text, frame:expandTemplate{ title = v2.template, args = v2 })
else
if self.count_cameos > 0 then
mw.log("count returned 0: " .. v2.count_all)
self.see_cameos = 'y'
end
end
end
--templates = concatvalues(t,"")
templates = concathtml(t)
if not templates == "" then
-- insert the section, prepended by its header, to the final text
table.insert(text, k .. templates)
end
end
end
gallery = table.concat(text)
if total_images > 0 then
mw.log(dump(gallery))
expanded_template = GalleryTemplate._expandTemplate_GallerySectionCargo(self, self.frame)
return "<pre>" .. gallery .. "</pre>"
--table.insert(t_galleries, expanded_template)
self.images_in_section = self.images_in_section + total_images
end
 
return expanded_template
end
 
function GalleryTemplate.makeGallerySectionBBRadio(self)
self.character = cargo_escape(self.character)
self.count_all = GalleryTemplate._countImages_GallerySectionBBRadio(self) or 0
local expanded_template = GalleryTemplate._expandTemplate_GallerySectionBBRadio(self,self.frame)
--table.insert(t_galleries, expanded_template)
self.images_in_section = self.images_in_section + self.count_all
return expanded_template
end
 
function GalleryTemplate.makeGallerySection(self)
self.count_all = GalleryTemplate._countImages_GallerySection(self) or 0
local expanded_template = GalleryTemplate._expandTemplate_GallerySection(self,self.frame)
--table.insert(t_galleries, expanded_template)
self.images_in_section = self.images_in_section + self.count_all
return expanded_template
end
end


function p.countImagesCargo(v, countCameos)
-- counts the number of images with this character (or cameo) for sections using Template:Gallery Section (Cargo)
-- countCameos: boolean
function GalleryTemplate._countImages_GallerySectionCargo(self, countCameos)
tables = 'Files'
tables = 'Files'
fields = 'COUNT(Files._pageName)'
fields = 'COUNT(Files._pageName)'


character = v.character or ''
character = self.character or ''
source = v.source or ''
source = self.source or ''
section = v.section or ''
section = self.section or ''


where_clause_parts = {}
where_clause_parts = {}
Line 106: Line 132:
table.insert(where_clause_parts, "Files.Characters HOLDS '" .. character .. "'")
table.insert(where_clause_parts, "Files.Characters HOLDS '" .. character .. "'")
end
end
if not source == '' then
table.insert(where_clause_parts, "Files.Source HOLDS '" .. source .. "'")
if source == '' then else table.insert(where_clause_parts, "Files.Source HOLDS '" .. source .. "'") end
end
if section == '' then else table.insert(where_clause_parts, "Files.Gallery_Sections HOLDS '" .. section .. "'") end
if not section == '' then
table.insert(where_clause_parts, "Files.Gallery_Sections = '" .. section .. "'")
end
where_clause = concatvalues(where_clause_parts, " AND ")
where_clause = concatvalues(where_clause_parts, " AND ")


Line 124: Line 147:
end
end


function p.testExpandTemplate(frame)
function GalleryTemplate._countImages_GallerySectionBBRadio(self)
tables = 'Files,BBRadio_Cuts'
fields = 'COUNT(Files._pageName)'
join_on = 'Files._pageName=BBRadio_Cuts._pageName'
mw.log("Count images for " .. self.character .. ' season ' .. self.season)
 
where_clause = 'Files.Characters HOLDS "' .. self.character .. '" AND BBRadio_Cuts.Season="' .. self.season .. '"'
 
local args = {
where = where_clause,
join = join_on
}
 
result = cargo.query( tables, fields, args )
count = result[1][fields] or '0'
 
return tonumber(count)
end
 
function GalleryTemplate._countImages_GallerySection(self)
cat1 = self.character or ''
cat2 = self.cat or ''
cat3 = self.cat2 or ''
 
local query = {}
if cat1 ~= '' then table.insert(query, '[[Category:' .. cat1 .. ']]') end
if cat2 ~= '' then table.insert(query, '[[Category:' .. cat2 .. ']]') end
if cat3 ~= '' then table.insert(query, '[[Category:' .. cat3 .. ']]') end
local result = mw.smw.getQueryResult( query )
count = result.meta.count or 0
 
return count
end
 
function GalleryTemplate._expandTemplate_GallerySectionCargo(self)
_limit = tonumber(self.limit) or 4
 
if self.frame.expandTemplate == nil then return '' end
gallery = self.frame:expandTemplate{ title = 'Gallery Section (Cargo)', args = {
character = self.character,
source = self.source,
section = self.section,
limit = _limit,
title = self.title,
header = self.header,
see_all = self.see_all,
see_cameos = self.see_cameos,
count_all = self.count_all,
count_cameos = self.count_cameos
}}
 
return gallery
end
 
function GalleryTemplate._expandTemplate_GallerySectionBBRadio(self)
_limit = tonumber(self.limit) or 4
_widths = tonumber(self.widths) or 250
 
if self.frame.expandTemplate == nil then return '' end
gallery = self.frame:expandTemplate { title = 'Gallery Section (BBRadio)', args = {
self.character,
self.season,
self.episode,
self.header,
self.title,
widths = _widths,
limit = _limit,
count_all = self.count_all
}}
 
return gallery
end
 
function GalleryTemplate._expandTemplate_GallerySection(self)
_limit = tonumber(self.limit) or 4
_widths = tonumber(self.widths) or 250
_count_all = self.count_all or 0
_title = self.title or ''
 
if self.frame.expandTemplate == nil then return '' end
gallery = self.frame:expandTemplate { title = 'Gallery Section', args = {
self.character,
self.cat,
self.cat2,
self.header,
self.title,
widths = _widths,
limit = _limit,
count_all = _count_all,
}}
 
return gallery
end
 
function GalleryTemplate:getNumberOfImages(self)
return self.images_in_section
end
 
-------------------------------------
-- Gallery Class
-------------------------------------
 
local Gallery = {}
Gallery.__index = Gallery
 
function Gallery.new(data, frame)
local self = setmetatable({}, Gallery)
self.galleryData = mw.loadData(data)
self.ordering = self.galleryData.ordering
self.sections = self.galleryData.sections
self.frame = frame
return self
end
 
function Gallery:__tostring()
local frame = self.frame
text = {}
_char = frame.args['character'] or ''
text = p._testExpandTemplate(frame, 'BlazBlue: Central Fiction', '', 8, 'title', 'h3', 'y', 'y', '7')
for i,v in ipairs (self.ordering) do
category = v
local params = self.sections[v] or ''
if params == '' then
else
local t_section = {}
local t_galleries = {}
local images_in_section = 0
local images_in_subsection = 0
local current_subheader = ''
-- add a wrapper div if there's a class to apply to the section
class = params.class or ''
if class ~= '' then
table.insert(t_section, '<div class="' .. class .. '">')
end
 
-- each v2 represents one template call
for k2,v2 in pairs(params) do
template = v2.template or ''
 
local title = v2.title or ''
mw.log(template .. ": " .. title)
 
if not (template == 'Header') and template ~= '' then
local g = nil
local expanded_g = nil
 
g = GalleryTemplate.new(frame, template, v2)
if g ~= nil then
expanded_g = tostring(g)
mw.log("imgs: " .. g:getNumberOfImages(g) or 0 )
if expanded_g ~= nil and expanded_g ~= '' then
table.insert(t_galleries, expanded_g)
num_images = tonumber(g:getNumberOfImages(g)) or 0
images_in_subsection = images_in_subsection  + num_images
images_in_section = images_in_section + num_images
mw.log("expanded_g: " .. expanded_g)
end
mw.log("t_galleries: " .. table.concat(t_galleries))
end
elseif template == 'Header' then
-- if this is not the first subheader in this section
if current_subheader ~= '' then
-- check if the previous subheader's galleries had images in them
if images_in_subsection > 0 then
table.insert(t_section, current_subheader)
g = table.concat(t_galleries)
if g ~= "" then
table.insert(t_section, g)
end
-- reset galleries and images for the next subsection
clear_table(t_galleries)
images_in_subsection = 0
end
end
local header = v2.header or ''
-- save the new subheader and wait to see if the following galleries have any images in them
current_subheader = '<' .. header .. '>' .. title .. '</' .. header .. ">\n"
end
end
 
-- check the number of images in the section
mw.log("---\n" .. category .. " images_in_section = " .. images_in_section)
mw.log("t_galleries: " .. table.concat(t_galleries))
 
if images_in_section > 0 then
-- if there is a subheader to insert, then insert it
if current_subheader ~= "" and images_in_subsection > 0 then
table.insert(t_section, current_subheader)
end
-- if there are galleries to insert, then insert them
g = table.concat(t_galleries)
table.insert(t_section, g)
 
-- close the wrapping div if one was added
if class ~= "" then
table.insert(t_section, "</div>")
end
 
-- insert the section, prepended by the section header, to the final text
s = concatvaluesonly(t_section, '')
mw.log('t_section ' .. category .. ' ' .. s)
if s ~= "" then
table.insert(text, '<h2>' .. category .. '</h2>\n' .. s)
end
end
 
mw.log("\n")
clear_table(t_galleries)
clear_table(t_section)
end
end
gallery = table.concat(text)
return gallery
end
 
-------------------------------------
-- Main
-------------------------------------
local p = {}
 
function p.main(frame)
data = frame.args.data or 'Module:Character Gallery/data'
gallery = Gallery.new(data, frame)
 
--mw.log(dump(tostring(gallery)))
return tostring(gallery)
end
 
-------------------------------------
-- Tests
-------------------------------------
 
function p.testExpandTemplate_1(frame)
v = {
character = 'Noel Vermillion',
source = 'BlazBlue: Central Fiction',  
section = '',  
limit = 8,  
title = 'title',  
header = 'h3',  
see_all = 'y',  
see_cameos = 'y',  
count_all = '7'
}
text = p._expandTemplate_GallerySectionCargo(frame, v)
return text
return text
end
end


function p._testExpandTemplate(frame, source, section, limit, title, header, see_all, see_cameo, count_all)
function p.testExpandTemplate_2(frame)
_character = frame.args.character or ''
_source = frame.args.source or source or ''
v = {
_section = section or ''
character = 'Noel Vermillion',
_limit = tonumber(limit) or 4
season = 'NEO',
_title = title or ''
limit = 8,
_header = header or ''
title = 'title',
_see_all = see_all or ''
header = 'h3',
_see_cameo = see_cameo or ''
see_all = 'y',
_count_all = count_all or ''
count_all = '7',
}
text = p._expandTemplate_GallerySectionBBRadio(frame, v)
gallery = frame:expandTemplate{ title = 'Gallery Section (Cargo)', args = {
return text
  character = _character
end
    ,source = _source
 
  ,section = _section
function p.testOrdering()
    ,limit = _limit
for i,v in ipairs (ordering) do
    ,title = _title
section = v
    ,header = _header
k = sections[v] or ''
  ,see_all = _see_all
,see_cameo = _see_cameo
,count_all = _count_all
} }


return gallery
mw.log('\n' .. i .. ': ' .. section)
if k == '' then
mw.log('no parameters found')
else
mw.log(k.class)
for k2,v2 in pairs (k) do
mw.log(k2)
end
end
end
end
end


-- concat values in a table as html nodes?
-------------------------------------
function concathtml(s)
-- Utility Functions
local div = mw.html.create('div')
-------------------------------------
for k,v in ipairs(s) do
 
div:node(v)
-- clear a table
function clear_table(t)
for k in pairs (t) do
    t [k] = nil
end
end
mw.log(div)
return div
end
end


Line 186: Line 467:
     end
     end
     return table.concat(t,delimiter)
     return table.concat(t,delimiter)
end
function cargo_escape(s)
return (string.gsub(s, "[']", {
["'"] = "",
['"'] = "",
}))
end
function quote_escape(s)
return (string.gsub(s, "[\"']", {
["\'"] = "\\'",
['\"'] = '\\"'
}))
end
end



Latest revision as of 01:26, 29 April 2020

Main Visuals

ⓘ How to add an image hereTo add an image to this section, upload it with all of the following categories:
[[Category:Noel Vermillion]][[Category:Main Artwork]]
OR make sure the file has the following filled out on its page:
{{Gallery Metadata
|characters=Noel Vermillion
|locations=
|weapons=
|artists=
|section=Main Artwork
|sources=
}}
Load 3 more...

Gallery Section (Cargo)/Q3 4 7 50 Noel Vermillion Main Artwork _pageName

Character Crest

ⓘ How to add an image hereTo add an image to this section, upload it with all of the following categories:
[[Category:Noel Vermillion]][[Category:Crests]]
OR make sure the file has the following filled out on its page:
{{Gallery Metadata
|characters=Noel Vermillion
|locations=
|weapons=
|artists=
|section=Crests
|sources=
}}

Chibi

ⓘ How to add an image hereTo add an image to this section, upload it with all of the following categories:
[[Category:Noel Vermillion]][[Category:Chibi]]
OR make sure the file has the following filled out on its page:
{{Gallery Metadata
|characters=Noel Vermillion
|locations=
|weapons=
|artists=
|section=Chibi
|sources=
}}

Gameplay

Arcade

BlazBlue: Calamity Trigger

ⓘ How to add an image hereTo add an image to this section, upload it with all of the following categories:
[[Category:Noel Vermillion]][[Category:Arcade Mode]][[Category:BlazBlue: Calamity Trigger]]
OR make sure the file has the following filled out on its page:
{{Gallery Metadata
|characters=Noel Vermillion OR
|cameos=Noel Vermillion
|locations=
|weapons=
|artists=
|section=Arcade Mode
|sources=BlazBlue: Calamity Trigger
}}
Load 2 more...

Gallery Section (Cargo)/Q3 4 6 50 Noel Vermillion BlazBlue: Calamity Trigger Arcade Mode _pageName

BlazBlue: Continuum Shift

ⓘ How to add an image hereTo add an image to this section, upload it with all of the following categories:
[[Category:Noel Vermillion]][[Category:Arcade Mode]][[Category:BlazBlue: Continuum Shift]]
OR make sure the file has the following filled out on its page:
{{Gallery Metadata
|characters=Noel Vermillion OR
|cameos=Noel Vermillion
|locations=
|weapons=
|artists=
|section=Arcade Mode
|sources=BlazBlue: Continuum Shift
}}

BlazBlue: Chrono Phantasma

ⓘ How to add an image hereTo add an image to this section, upload it with all of the following categories:
[[Category:Noel Vermillion]][[Category:Arcade Mode]][[Category:BlazBlue: Chrono Phantasma]]
OR make sure the file has the following filled out on its page:
{{Gallery Metadata
|characters=Noel Vermillion OR
|cameos=Noel Vermillion
|locations=
|weapons=
|artists=
|section=Arcade Mode
|sources=BlazBlue: Chrono Phantasma
}}
Load 6 more...

Gallery Section (Cargo)/Q3 4 10 50 Noel Vermillion BlazBlue: Chrono Phantasma Arcade Mode _pageName

BlazBlue: Central Fiction

ⓘ How to add an image hereTo add an image to this section, upload it with all of the following categories:
[[Category:Noel Vermillion]][[Category:Arcade Mode]][[Category:BlazBlue: Central Fiction]]
OR make sure the file has the following filled out on its page:
{{Gallery Metadata
|characters=Noel Vermillion OR
|cameos=Noel Vermillion
|locations=
|weapons=
|artists=
|section=Arcade Mode
|sources=BlazBlue: Central Fiction
}}
Load 3 more...

Gallery Section (Cargo)/Q3 4 7 50 Noel Vermillion BlazBlue: Central Fiction Arcade Mode _pageName

Load 9 more...

Gallery Section (Cargo)/Q3 4 13 50 Noel Vermillion BlazBlue: Central Fiction Arcade Mode _pageName

Story

Portraits

ⓘ How to add an image hereTo add an image to this section, upload it with all of the following categories:
[[Category:Noel Vermillion]][[Category:Portraits]]
OR make sure the file has the following filled out on its page:
{{Gallery Metadata
|characters=Noel Vermillion
|locations=
|weapons=
|artists=
|section=Portraits
|sources=
}}
Load 7 more...

Gallery Section (Cargo)/Q3 4 11 50 Noel Vermillion Portraits _pageName

Short Stories

ⓘ How to add an image hereTo add an image to this section, upload it with all of the following categories:
[[Category:Noel Vermillion]][[Category:Short Story Illustrations]]
OR make sure the file has the following filled out on its page:
{{Gallery Metadata
|characters=Noel Vermillion
|locations=
|weapons=
|artists=
|section=Short Story Illustrations
|sources=
}}

BlazBlue: Calamity Trigger

ⓘ How to add an image hereTo add an image to this section, upload it with all of the following categories:
[[Category:Noel Vermillion]][[Category:Story]][[Category:BlazBlue: Calamity Trigger]]
OR make sure the file has the following filled out on its page:
{{Gallery Metadata
|characters=Noel Vermillion OR
|cameos=Noel Vermillion
|locations=
|weapons=
|artists=
|section=Story
|sources=BlazBlue: Calamity Trigger
}}
Load 11 more...

Gallery Section (Cargo)/Q3 4 15 50 Noel Vermillion BlazBlue: Calamity Trigger Story _pageName

Load 1 more...

Gallery Section (Cargo)/Q3 4 5 50 Noel Vermillion BlazBlue: Calamity Trigger Story _pageName

BlazBlue: Continuum Shift

ⓘ How to add an image hereTo add an image to this section, upload it with all of the following categories:
[[Category:Noel Vermillion]][[Category:Story]][[Category:BlazBlue: Continuum Shift]]
OR make sure the file has the following filled out on its page:
{{Gallery Metadata
|characters=Noel Vermillion OR
|cameos=Noel Vermillion
|locations=
|weapons=
|artists=
|section=Story
|sources=BlazBlue: Continuum Shift
}}
Load 8 more...

Gallery Section (Cargo)/Q3 4 12 50 Noel Vermillion BlazBlue: Continuum Shift Story _pageName

BlazBlue: Chrono Phantasma

ⓘ How to add an image hereTo add an image to this section, upload it with all of the following categories:
[[Category:Noel Vermillion]][[Category:Story]][[Category:BlazBlue: Chrono Phantasma]]
OR make sure the file has the following filled out on its page:
{{Gallery Metadata
|characters=Noel Vermillion
|locations=
|weapons=
|artists=
|section=Story
|sources=BlazBlue: Chrono Phantasma
}}
Load 9 more...

Gallery Section (Cargo)/Q3 4 13 50 Noel Vermillion BlazBlue: Chrono Phantasma Story _pageName

BlazBlue: Central Fiction

ⓘ How to add an image hereTo add an image to this section, upload it with all of the following categories:
[[Category:Noel Vermillion]][[Category:Story]][[Category:BlazBlue: Central Fiction]]
OR make sure the file has the following filled out on its page:
{{Gallery Metadata
|characters=Noel Vermillion OR
|cameos=Noel Vermillion
|locations=
|weapons=
|artists=
|section=Story
|sources=BlazBlue: Central Fiction
}}
Load 7 more...

Gallery Section (Cargo)/Q3 4 11 50 Noel Vermillion BlazBlue: Central Fiction Story _pageName

BlazBlue: Cross Tag Battle

ⓘ How to add an image hereTo add an image to this section, upload it with all of the following categories:
[[Category:Noel Vermillion]][[Category:Story]][[Category:BlazBlue: Cross Tag Battle]]
OR make sure the file has the following filled out on its page:
{{Gallery Metadata
|characters=Noel Vermillion
|locations=
|weapons=
|artists=
|section=Story
|sources=BlazBlue: Cross Tag Battle
}}
Load 1 more...

Gallery Section (Cargo)/Q3 4 5 50 Noel Vermillion BlazBlue: Cross Tag Battle Story _pageName

BlazBlue: Clone Phantasma

ⓘ How to add an image hereTo add an image to this section, upload it with all of the following categories:
[[Category:Noel Vermillion]][[Category:Story]][[Category:BlazBlue: Clone Phantasma]]
OR make sure the file has the following filled out on its page:
{{Gallery Metadata
|characters=Noel Vermillion OR
|cameos=Noel Vermillion
|locations=
|weapons=
|artists=
|section=Story
|sources=BlazBlue: Clone Phantasma
}}

Novels

BlazBlue: Calamity Trigger - Part 1

ⓘ How to add an image hereTo add an image to this section, upload it with all of the following categories:
[[Category:Noel Vermillion]][[Category:BlazBlue: Calamity Trigger - Part 1]]
OR make sure the file has the following filled out on its page:
{{Gallery Metadata
|characters=Noel Vermillion
|locations=
|weapons=
|artists=
|section=
|sources=BlazBlue: Calamity Trigger - Part 1
}}

BlazBlue: Calamity Trigger - Part 2

ⓘ How to add an image hereTo add an image to this section, upload it with all of the following categories:
[[Category:Noel Vermillion]][[Category:BlazBlue: Calamity Trigger - Part 2]]
OR make sure the file has the following filled out on its page:
{{Gallery Metadata
|characters=Noel Vermillion
|locations=
|weapons=
|artists=
|section=
|sources=BlazBlue: Calamity Trigger - Part 2
}}
Load 2 more...

Gallery Section (Cargo)/Q3 4 6 50 Noel Vermillion BlazBlue: Calamity Trigger - Part 2 _pageName

BlazBlue: Continuum Shift - Part 1

ⓘ How to add an image hereTo add an image to this section, upload it with all of the following categories:
[[Category:Noel Vermillion]][[Category:BlazBlue: Continuum Shift - Part 1]]
OR make sure the file has the following filled out on its page:
{{Gallery Metadata
|characters=Noel Vermillion
|locations=
|weapons=
|artists=
|section=
|sources=BlazBlue: Continuum Shift - Part 1
}}

BlazBlue: Continuum Shift - Part 2

ⓘ How to add an image hereTo add an image to this section, upload it with all of the following categories:
[[Category:Noel Vermillion]][[Category:BlazBlue: Continuum Shift - Part 2]]
OR make sure the file has the following filled out on its page:
{{Gallery Metadata
|characters=Noel Vermillion
|locations=
|weapons=
|artists=
|section=
|sources=BlazBlue: Continuum Shift - Part 2
}}

Radio Show

Chibi Portraits

ⓘ How to add an image hereTo add an image to this section, upload it with all of the following categories:
[[Category:Noel Vermillion]][[Category:Chibi Portraits]]
OR make sure the file has the following filled out on its page:
{{Gallery Metadata
|characters=Noel Vermillion
|locations=
|weapons=
|artists=
|section=Chibi Portraits
|sources=
}}
Load 47 more...

Gallery Section (Cargo)/Q3 4 51 50 Noel Vermillion Chibi Portraits _pageName

Blazblue Radio

Load 50 more...

Gallery_Section_(BBRadio)/Q1 4 117 50 Noel Vermillion 1 _pageName 150

Blazblue Radio Continued

Load 50 more...

Gallery_Section_(BBRadio)/Q1 4 151 50 Noel Vermillion 2 _pageName 150

Blazblue Radio Wide

Load 50 more...

Gallery_Section_(BBRadio)/Q1 4 130 50 Noel Vermillion W _pageName 150

Blazblue Radio Hyper

Load 50 more...

Gallery_Section_(BBRadio)/Q1 4 70 50 Noel Vermillion H _pageName 150

Blazblue Radio Ace

Load 50 more...

Gallery_Section_(BBRadio)/Q1 4 57 50 Noel Vermillion A _pageName 150

Blazblue Radio Quick

Load 47 more...

Gallery_Section_(BBRadio)/Q1 4 51 50 Noel Vermillion Q _pageName 150

Blazblue Radio Dynamic

Load 38 more...

Gallery_Section_(BBRadio)/Q1 4 42 50 Noel Vermillion D _pageName 150

Blazblue Radio NEO

Load 33 more...

Gallery_Section_(BBRadio)/Q1 4 37 50 Noel Vermillion NEO _pageName 150

Blazblue Radio Repeat

Load 1 more...

Gallery_Section_(BBRadio)/Q1 4 5 50 Noel Vermillion R _pageName 150

Blazblue Radio Repeat 2

BlazBlue Alternative: Dark War

All Related Files

... further results

Artwork

Promotional

ⓘ How to add an image hereTo add an image to this section, upload it with all of the following categories:
[[Category:Noel Vermillion]][[Category:Promotional Artwork]]
OR make sure the file has the following filled out on its page:
{{Gallery Metadata
|characters=Noel Vermillion
|locations=
|weapons=
|artists=
|section=Promotional Artwork
|sources=
}}
Load 46 more...

Gallery Section (Cargo)/Q3 4 50 50 Noel Vermillion Promotional Artwork _pageName

Birthday Art

ⓘ How to add an image hereTo add an image to this section, upload it with all of the following categories:
[[Category:Noel Vermillion]][[Category:Birthday Art]]
OR make sure the file has the following filled out on its page:
{{Gallery Metadata
|characters=Noel Vermillion OR
|cameos=Noel Vermillion
|locations=
|weapons=
|artists=
|section=Birthday Art
|sources=
}}
Load 7 more...

Gallery Section (Cargo)/Q3 4 11 50 Noel Vermillion Birthday Art _pageName

Load 1 more...

Gallery Section (Cargo)/Q3 4 5 50 Noel Vermillion Birthday Art _pageName

Staff Extras

ⓘ How to add an image hereTo add an image to this section, upload it with all of the following categories:
[[Category:Noel Vermillion]][[Category:Staff Extras]]
OR make sure the file has the following filled out on its page:
{{Gallery Metadata
|characters=Noel Vermillion
|locations=
|weapons=
|artists=
|section=Staff Extras
|sources=
}}
Load 27 more...

Gallery Section (Cargo)/Q3 4 31 50 Noel Vermillion Staff Extras _pageName

Special Artwork

ⓘ How to add an image hereTo add an image to this section, upload it with all of the following categories:
[[Category:Noel Vermillion]][[Category:Special Artwork]]
OR make sure the file has the following filled out on its page:
{{Gallery Metadata
|characters=Noel Vermillion
|locations=
|weapons=
|artists=
|section=Special Artwork
|sources=
}}
Load 10 more...

Gallery Section (Cargo)/Q3 4 14 50 Noel Vermillion Special Artwork _pageName

Pre-order Bonuses

ⓘ How to add an image hereTo add an image to this section, upload it with all of the following categories:
[[Category:Noel Vermillion]][[Category:Pre-order Bonuses]]
OR make sure the file has the following filled out on its page:
{{Gallery Metadata
|characters=Noel Vermillion
|locations=
|weapons=
|artists=
|section=Pre-order Bonuses
|sources=
}}
Load 44 more...

Gallery Section (Cargo)/Q3 4 48 50 Noel Vermillion Pre-order Bonuses _pageName

Wallpapers

ⓘ How to add an image hereTo add an image to this section, upload it with all of the following categories:
[[Category:Noel Vermillion]][[Category:Wallpapers]]
OR make sure the file has the following filled out on its page:
{{Gallery Metadata
|characters=Noel Vermillion
|locations=
|weapons=
|artists=
|section=Wallpapers
|sources=
}}
Load 17 more...

Gallery Section (Cargo)/Q3 4 21 50 Noel Vermillion Wallpapers _pageName

Stickers

ⓘ How to add an image hereTo add an image to this section, upload it with all of the following categories:
[[Category:Noel Vermillion]][[Category:Stickers]]
OR make sure the file has the following filled out on its page:
{{Gallery Metadata
|characters=Noel Vermillion
|locations=
|weapons=
|artists=
|section=Stickers
|sources=
}}
Load 42 more...

Gallery Section (Cargo)/Q3 4 46 50 Noel Vermillion Stickers _pageName

Icons

ⓘ How to add an image hereTo add an image to this section, upload it with all of the following categories:
[[Category:Noel Vermillion]][[Category:Icons]]
OR make sure the file has the following filled out on its page:
{{Gallery Metadata
|characters=Noel Vermillion OR
|cameos=Noel Vermillion
|locations=
|weapons=
|artists=
|section=Icons
|sources=
}}
Load 25 more...

Gallery Section (Cargo)/Q3 4 29 50 Noel Vermillion Icons _pageName

Production Art

Model Sheets

ⓘ How to add an image hereTo add an image to this section, upload it with all of the following categories:
[[Category:Noel Vermillion]][[Category:Model Sheets]]
OR make sure the file has the following filled out on its page:
{{Gallery Metadata
|characters=Noel Vermillion
|locations=
|weapons=
|artists=
|section=Model Sheets
|sources=
}}
Load 11 more...

Gallery Section (Cargo)/Q3 4 15 50 Noel Vermillion Model Sheets _pageName

Early Designs

ⓘ How to add an image hereTo add an image to this section, upload it with all of the following categories:
[[Category:Noel Vermillion]][[Category:Early Designs]]
OR make sure the file has the following filled out on its page:
{{Gallery Metadata
|characters=Noel Vermillion
|locations=
|weapons=
|artists=
|section=Early Designs
|sources=
}}

Storyboards

ⓘ How to add an image hereTo add an image to this section, upload it with all of the following categories:
[[Category:Noel Vermillion]][[Category:Storyboards]]
OR make sure the file has the following filled out on its page:
{{Gallery Metadata
|characters=Noel Vermillion
|locations=
|weapons=
|artists=
|section=Storyboards
|sources=
}}
Load 10 more...

Gallery Section (Cargo)/Q3 4 14 50 Noel Vermillion Storyboards _pageName

Collaborations

Destiny Child

... further results

Girls' Frontline

... further results

Lord of Vermilion Re:2

... further results

Mabinogi Duel

Unlimited VS

... further results

Fantasy War Tactics


--[[
{{#invoke:Sandbox/Chao|GallerySection|character=Noel Vermillion|section=Portraits}}
simulate passing a frame to the function in the console with:
myFrame = { args = { character='Noel Vermillion' } }
=p.main(myFrame)
=p.GallerySection ( myFrame )
=p.testExpandTemplate( myFrame )

--]]

local cargo = mw.ext.cargo

-------------------------------------
-- Gallery Section Class
-------------------------------------

local GalleryTemplate = {}
GalleryTemplate.__index = GalleryTemplate

GalleryTemplate.fields = {
	character = true,
	source = true,
	section = true,
	limit = true,
	widths = true,
	header = true,
	title = true,
	sort = true,
	see_all = true,
	see_cameos = true,
	--Gallery Section (BBRadio)
	season = true,
	episode = true,
	widths = true,
	--Gallery Section
	cat = true,
	cat2 = true,
	--Misc/Shared
	count_all = true,
	count_cameos = true,
	images_in_section = true,
}

GalleryTemplate.templateMethods = {
	['Gallery Section (Cargo)'] = 'makeGallerySectionCargo',
	['Gallery Section (BBRadio)'] = 'makeGallerySectionBBRadio',
	['Gallery Section'] = 'makeGallerySection',
}

function GalleryTemplate.new(frame, templateType, params)
	local self = setmetatable({}, GalleryTemplate)
	self.templateType= templateType
	self.frame = frame
	for field in pairs(GalleryTemplate.fields) do
		self[field] = params[field] or ''
	end

	self.images_in_section = 0
	self.cat = params.category or ''
	if (params.character == nil)
		then self.character = frame.args.character or ''
		else self.character = params.character or ''
	end
	return self
end

function GalleryTemplate:__tostring()
	local method = GalleryTemplate.templateMethods[self.templateType]
	if method then
		return self[method](self)
	end
	return ''
end

function GalleryTemplate.makeGallerySectionCargo(self)
	local expanded_template = nil

	self.character = cargo_escape(self.character)

	self.count_all = GalleryTemplate._countImages_GallerySectionCargo(self,false) or 0
	self.count_cameos = GalleryTemplate._countImages_GallerySectionCargo(self,true) or 0
	local total_images = self.count_all + self.count_cameos
	
	if self.count_all > 0 then
		self.see_all = 'y'
	end
	
	if self.count_cameos > 0 then
		self.see_cameos = 'y'
	end
	
	if total_images > 0 then
		expanded_template = GalleryTemplate._expandTemplate_GallerySectionCargo(self, self.frame)
		--table.insert(t_galleries, expanded_template)
		self.images_in_section = self.images_in_section + total_images
	end

	return expanded_template
end

function GalleryTemplate.makeGallerySectionBBRadio(self)
	self.character = cargo_escape(self.character)
	self.count_all = GalleryTemplate._countImages_GallerySectionBBRadio(self) or 0
	local expanded_template = GalleryTemplate._expandTemplate_GallerySectionBBRadio(self,self.frame)
	--table.insert(t_galleries, expanded_template)
	self.images_in_section = self.images_in_section + self.count_all
	return expanded_template
end

function GalleryTemplate.makeGallerySection(self)
	self.count_all = GalleryTemplate._countImages_GallerySection(self) or 0
	local expanded_template = GalleryTemplate._expandTemplate_GallerySection(self,self.frame)
	--table.insert(t_galleries, expanded_template)
	self.images_in_section = self.images_in_section + self.count_all
	return expanded_template
end

-- counts the number of images with this character (or cameo) for sections using Template:Gallery Section (Cargo)
-- countCameos: boolean
function GalleryTemplate._countImages_GallerySectionCargo(self, countCameos)
	tables = 'Files'
	fields = 'COUNT(Files._pageName)'

	character = self.character or ''
	source = self.source or ''
	section = self.section or ''

	where_clause_parts = {}
	if countCameos then
		table.insert(where_clause_parts, "Files.Cameos HOLDS '" .. character .. "'")
	else
		table.insert(where_clause_parts, "Files.Characters HOLDS '" .. character .. "'")
	end
	
	if source == '' then else table.insert(where_clause_parts, "Files.Source HOLDS '" .. source .. "'")	end
	if section == '' then else table.insert(where_clause_parts, "Files.Gallery_Sections HOLDS '" .. section .. "'")	end
	where_clause = concatvalues(where_clause_parts, " AND ")

	local args = {
		where = where_clause
	}

	result = cargo.query( tables, fields, args )
	count = result[1][fields] or '0'

	return tonumber(count)
end

function GalleryTemplate._countImages_GallerySectionBBRadio(self)
	tables = 'Files,BBRadio_Cuts'
	fields = 'COUNT(Files._pageName)'
	join_on = 'Files._pageName=BBRadio_Cuts._pageName'
	
	mw.log("Count images for " .. self.character .. ' season ' .. self.season)

	where_clause = 'Files.Characters HOLDS "' .. self.character .. '" AND BBRadio_Cuts.Season="' .. self.season .. '"'

	local args = {
		where = where_clause,
		join = join_on
	}

	result = cargo.query( tables, fields, args )
	count = result[1][fields] or '0'

	return tonumber(count)
end

function GalleryTemplate._countImages_GallerySection(self)
	cat1 = self.character or ''
	cat2 = self.cat or ''
	cat3 = self.cat2 or ''

	local query = {}
	if cat1 ~= '' then table.insert(query, '[[Category:' .. cat1 .. ']]') end
	if cat2 ~= '' then table.insert(query, '[[Category:' .. cat2 .. ']]') end
	if cat3 ~= '' then table.insert(query, '[[Category:' .. cat3 .. ']]') end
	
	local result = mw.smw.getQueryResult( query )
	count = result.meta.count or 0

	return count
end

function GalleryTemplate._expandTemplate_GallerySectionCargo(self)
	_limit = tonumber(self.limit) or 4

	if self.frame.expandTemplate == nil then return '' end
	gallery = self.frame:expandTemplate{ title = 'Gallery Section (Cargo)', args = { 
		character = self.character,
		source = self.source,
		section = self.section,
		limit = _limit,
		title = self.title,
		header = self.header,
		see_all = self.see_all,
		see_cameos = self.see_cameos,
		count_all = self.count_all,
		count_cameos = self.count_cameos
	}}

	return gallery
end

function GalleryTemplate._expandTemplate_GallerySectionBBRadio(self)
	_limit = tonumber(self.limit) or 4
	_widths = tonumber(self.widths) or 250

	if self.frame.expandTemplate == nil then return '' end
	gallery = self.frame:expandTemplate { title = 'Gallery Section (BBRadio)', args = {
		self.character,
		self.season,
		self.episode,
		self.header,
		self.title,
		widths = _widths,
		limit = _limit,
		count_all = self.count_all
	}}

	return gallery
end

function GalleryTemplate._expandTemplate_GallerySection(self)
	_limit = tonumber(self.limit) or 4
	_widths = tonumber(self.widths) or 250
	_count_all = self.count_all or 0
	_title = self.title or ''

	if self.frame.expandTemplate == nil then return '' end
	gallery = self.frame:expandTemplate { title = 'Gallery Section', args = {
		self.character,
		self.cat,
		self.cat2,
		self.header,
		self.title,
		widths = _widths,
		limit = _limit,
		count_all = _count_all,
	}}

	return gallery
end

function GalleryTemplate:getNumberOfImages(self)
	return self.images_in_section
end

-------------------------------------
-- Gallery Class
-------------------------------------

local Gallery = {}
Gallery.__index = Gallery

function Gallery.new(data, frame)
	local self = setmetatable({}, Gallery)
	self.galleryData = mw.loadData(data)
	self.ordering = self.galleryData.ordering
	self.sections = self.galleryData.sections
	self.frame = frame
	return self
end

function Gallery:__tostring()
	local frame = self.frame
	text = {}
	_char = frame.args['character'] or ''
	
	for i,v in ipairs (self.ordering) do
		category = v
		local params = self.sections[v] or ''
		
		if params == '' then
		else
			local t_section = {}
			local t_galleries = {}
			local images_in_section = 0
			local images_in_subsection = 0
			local current_subheader = ''
			
			-- add a wrapper div if there's a class to apply to the section
			class = params.class or ''
			if class ~= '' then
				table.insert(t_section, '<div class="' .. class .. '">')
			end

			-- each v2 represents one template call
			for k2,v2 in pairs(params) do
				template = v2.template or ''

				local title = v2.title or ''
				mw.log(template .. ": " .. title)

				if not (template == 'Header') and template ~= '' then
					local g = nil
					local expanded_g = nil

					g = GalleryTemplate.new(frame, template, v2)
					if g ~= nil then
						expanded_g = tostring(g)
						mw.log("imgs: " .. g:getNumberOfImages(g) or 0 )
						if expanded_g ~= nil and expanded_g ~= '' then
							table.insert(t_galleries, expanded_g)
							num_images = tonumber(g:getNumberOfImages(g)) or 0
							images_in_subsection = images_in_subsection  + num_images
							images_in_section = images_in_section + num_images
							mw.log("expanded_g: " .. expanded_g)
						end
						mw.log("t_galleries: " .. table.concat(t_galleries))
					end
				elseif template == 'Header' then
					-- if this is not the first subheader in this section
					if current_subheader ~= '' then
						-- check if the previous subheader's galleries had images in them
						if images_in_subsection > 0 then
							table.insert(t_section, current_subheader)
							g = table.concat(t_galleries)
							if g ~= "" then
								table.insert(t_section, g)
							end
							-- reset galleries and images for the next subsection
							clear_table(t_galleries)
							images_in_subsection = 0
						end
					end
					local header = v2.header or ''
					-- save the new subheader and wait to see if the following galleries have any images in them
					current_subheader = '<' .. header .. '>' .. title .. '</' .. header .. ">\n"
				end
			end

			-- check the number of images in the section
			mw.log("---\n" .. category .. " images_in_section = " .. images_in_section)
			mw.log("t_galleries: " .. table.concat(t_galleries))

			if images_in_section > 0 then
				-- if there is a subheader to insert, then insert it
				if current_subheader ~= "" and images_in_subsection > 0 then
					table.insert(t_section, current_subheader)
				end
			
				-- if there are galleries to insert, then insert them
				g = table.concat(t_galleries)
				table.insert(t_section, g)

				-- close the wrapping div if one was added
				if class ~= "" then
					table.insert(t_section, "</div>")
				end

				-- insert the section, prepended by the section header, to the final text
				s = concatvaluesonly(t_section, '')
				mw.log('t_section ' .. category .. ' ' .. s)
				if s ~= "" then
					table.insert(text, '<h2>' .. category .. '</h2>\n' .. s)
				end
			end

			mw.log("\n")
			clear_table(t_galleries)
			clear_table(t_section)
		end
	end
	
	gallery = table.concat(text)
	return gallery
end

-------------------------------------
-- Main
-------------------------------------
local p = {}

function p.main(frame)
	data = frame.args.data or 'Module:Character Gallery/data'
	gallery = Gallery.new(data, frame)

	--mw.log(dump(tostring(gallery)))
	return tostring(gallery)
end

-------------------------------------
-- Tests
-------------------------------------

function p.testExpandTemplate_1(frame)
	
	v = {
		character = 'Noel Vermillion',
		source = 'BlazBlue: Central Fiction', 
		section = '', 
		limit = 8, 
		title = 'title', 
		header = 'h3', 
		see_all = 'y', 
		see_cameos = 'y', 
		count_all = '7'
	}
	text = p._expandTemplate_GallerySectionCargo(frame, v)
	
	return text
end

function p.testExpandTemplate_2(frame)
	
	v = {
		character = 'Noel Vermillion',
		season = 'NEO', 
		limit = 8, 
		title = 'title', 
		header = 'h3', 
		see_all = 'y', 
		count_all = '7',
	}
	text = p._expandTemplate_GallerySectionBBRadio(frame, v)
	
	return text
end

function p.testOrdering()
	for i,v in ipairs (ordering) do
		section = v
		k = sections[v] or ''

		mw.log('\n' .. i .. ': ' .. section)
		if k == '' then
			mw.log('no parameters found')
		else
			mw.log(k.class)
			for k2,v2 in pairs (k) do
				mw.log(k2)
			end
		end
		
	end
end

-------------------------------------
-- Utility Functions
-------------------------------------

-- clear a table
function clear_table(t)
	for k in pairs (t) do
    	t [k] = nil
	end
end

-- concat all the strings in table s together with the given delimiter
function concatvalues(s,delimiter)
    local t = { }
    for k,v in ipairs(s) do
        t[#t+1] = tostring(v)
    end
    return table.concat(t,delimiter)
end

-- concat all the strings in table s together with the given delimiter
-- skips blank entries (where value v = "")
function concatvaluesonly(s,delimiter)
    local t = { }
    for k,v in ipairs(s) do
    	if not (v == '') then
    		t[#t+1] = tostring(v)
    	end
    end
    return table.concat(t,delimiter)
end

function cargo_escape(s)
	return (string.gsub(s, "[']", {
		["'"] = "",
		['"'] = "",
	}))
end

function quote_escape(s)
	return (string.gsub(s, "[\"']", {
		["\'"] = "\\'",
		['\"'] = '\\"'
	}))
end

function html_escape(s)
    return (string.gsub(s, "[<>\"'/ ,]", {
        ["<"] = "%3C",
        [">"] = "%3E",
        ['"'] = "%22",
        ["'"] = "%27",
        ["/"] = "%2F",
        [" "] = "+",
        [","] = "%2C"
    }))
end

-- helpful for printing tables
function dump(o)
   if type(o) == 'table' then
      local s = '{ '
      for k,v in pairs(o) do
         if type(k) ~= 'number' then k = '"'..k..'"' end
         s = s .. '['..k..'] = ' .. dump(v) .. ','
      end
      return s .. '} '
   else
      return tostring(o)
   end
end

return p