---- This module implements --local getArgs = require('Module:Arguments').getArgslocal TableTools = require('Module:TableTools')local p =
function addTemplates(frame, data, args) -- adds additional template to the top of the page, above the infobox local page_template -- local tmplt_args = local template_div = mw.html.create('div') for k,v in pairs(data.templates) do -- if there is a matching arg, and it has a table of template possibilities if (args[k] and string.len(args[k]) > 0 and type(data.templates[k])
true then template_div :cssText("") :wikitext(frame:expandTemplate) --status is special casing. need to pass generic arg keys :done break elseif (stringToLowerCase(args[k])
"string" and stringToLowerCase(args[k])
end end end page_template = tostring(template_div) return page_templateend
function addCategories(data, args, open_roles) -- will also look for numbered categories local cat_list = local base_cat = data.categories.base -- table.insert(cat_list, base_cat) --always need a base category -- -- adding role categories if data.categories.default then table.insert(cat_list, data.categories.default) end if data.categories.roles then role_cat = data.categories.roles for k,v in pairs(open_roles) do table.insert(cat_list, base_cat .. k:gsub("^%l", string.upper) .. role_cat) end end for k,v in pairs(data.categories) do -- if there is a matching arg, and it has a table of category possibilities if (args[k] and string.len(args[k]) > 0) then --convert args to lowercase before checking them against cats if type(data.categories[k])
cat_key then --convert args to lowercase and subs spaces for underscores before checking them against cats table.insert(cat_list, base_cat .. cat_val) break end end elseif type(data.categories[k])
function makeTextField(field, field_div) -- makes a formatted text field for output, based on parameter -- values or on default values provided for that field -- type in the stylesheet field_div:cssText(field.style) if field.vtype2
"title" then field_div :tag('span') :cssText(field.style3) :wikitext(field.values[1]) :done elseif field.vtype2
function makeImageField(field, field_div) -- makes a formatted image field for output, based on parameter values -- provided in the calling template or its parent template, or on default -- values provided in the stylesheet field_div:cssText(field.style) field_div :tag('span') :cssText(field.style3) if field.vtype2
"link" then field_div :wikitext("" .. field.alignment .. "|" .. field.width .."|link=" .. field.link .. "") elseif field.vtype2
"ui_button" then field_div :addClass(field.class) :wikitext(field.title) :done end field_div:done return field_div end
function makeParticipantField(field, ftype) local field_div = mw.html.create('div') local title_span if field.icon then title_span = "left" .. "|18px " .. field.title else title_span = field.title end field_div :cssText(field.style) :tag('span') :cssText(field.style2) :wikitext(title_span) :done if ftype
"username" then v = "• " .. "" .. v .. "" elseif field.vtype2
function makeSectionDiv(sec_fields, sec_style) local sec_div = mw.html.create('div'):cssText(sec_style) sec_fields = TableTools.compressSparseArray(sec_fields) for findex, sec_field in ipairs(sec_fields) do -- should put this at the end of the function, and just append the other stuff sec_div:node(sec_field) end return sec_divend
function makeParticipantsSection(frame, args, data, filled_role_data, open_roles) local filled_role_fields = for role, val_table in pairs(filled_role_data) do local field = data.fields[role] field.title = mw.text.trim(frame:expandTemplate) field.values = for val_num, val_text in ipairs(filled_role_data[role]) do field.values[#field.values + 1] = val_text end local filled_field_div = makeParticipantField(field, "filled") filled_role_fields[field.rank] = filled_field_div end local sec_div = makeSectionDiv(filled_role_fields, data.styles.section["participants"]) if (data.fields.more_participants and args.more_participants and stringToLowerCase(args.more_participants))
"Idealab" or args.portal
"Patterns" then -- sec_div:tag('span'):cssText("font-style:italic; color: #888888"):wikitext("a learning pattern for..."):done-- else for role, val in pairs(open_roles) do -- should make these ordered using compressSparseArray, as above local field = data.fields[role] field.title = mw.text.trim(frame:expandTemplate) if field.icon then field.icon = field.icon_inactive end local open_field_div = makeParticipantField(field, "open") sec_div:node(open_field_div) end end sec_div:allDone return sec_divend
function makeSectionFields(args, field) -- ui button is separate local field_div = mw.html.create('div'):cssText(field.style) --why declare this here? if field.vtype
true or (args[field.arg] and string.len(args[field.arg]) > 0)) then --should move this up, may not just apply to images field_div = makeImageField(field, field_div) end elseif field.vtype
function makeSection(frame, args, data, box_sec) -- return a div for a section of the box including child divs -- for each content field in that section -- local sec_div = mw.html.create('div'):cssText(data.styles.section[box_sec]) local sec_fields = for k,v in pairs(data.fields) do if data.fields[k].section
true then -- special casing to make IEG status=SELECTED to display in lowercase field.values[1] = stringToLowerCase(field.values[1]) end local field_div = makeSectionFields(args, field) sec_fields[field.rank] = field_div elseif field.isRequired
"text" then field.values[1] = mw.text.trim(frame:expandTemplate) else field.values[1] = field.default end local field_div = makeSectionFields(args, field) sec_fields[field.rank] = field_div else --don't make a section for this field end end end local sec_div = makeSectionDiv(sec_fields, data.styles.section[box_sec]) return sec_divend
function makeInfobox(frame, args, data, filled_role_data, open_roles) -- builds the infobox. Some content sections are required, others -- are optional. Optional sections are defined in the stylesheet. local box = mw.html.create('div'):cssText(data.styles.box.outer) local inner_box = mw.html.create('div'):cssText(data.styles.box.inner) if data.sections.above
true then local sec_nav = makeSection(frame, args, data, "nav") box:node(sec_nav) end local sec_head = makeSection(frame, args, data, "head") inner_box:node(sec_head) local sec_main = makeSection(frame, args, data, "main") inner_box:node(sec_main) if data.sections.participants
true then local sec_cta = makeSection(frame, args, data, "cta") inner_box:node(sec_cta) inner_box:tag('div'):cssText("clear:both"):done --clears buttons in the cta sections end inner_box:allDone box:node(inner_box) if data.sections.below
function orderStringtoNumber(array, val, num) if num > table.getn(array) then array[#array+1] = val else table.insert(array, num, val) end return arrayend function isJoinable(args, data) if args.more_participants
function deepCopyTable(data) -- the deep copy is a workaround step to avoid the restrictions placed on -- tables imported through loadData if type(data) ~= 'table' then return data end local res = for k,v in pairs(data) do if type(v)
function string.starts(String,Start) return string.sub(String,1,string.len(Start))
function stringToLowerCase(value) return mw.ustring.lower(value)end function stringSpacesToUnderscores(value) return mw.ustring.gsub(value, " ", "_")end
function stringFirstCharToUpper(str) return (str:gsub("^%l", string.upper))end
function TCTlookup(args) local tct_path = tostring(args.translations) --mw.log(mw.title.getCurrentTitle.subpageText) local tct_subpage = mw.title.getCurrentTitle.subpageText if tct_subpage
function getRoleArgs(args, available_roles) -- returns: -- 1) a table of ordered values for valid role params, -- even if numbered nonsequentially -- 2) a table of all roles with at least 1 empty param, -- plus the default volunteer role local filled_role_data = local open_roles = if available_roles.default then -- some boxes have default role to join open_roles[available_roles.default] = true end for rd_key, rd_val in pairs(available_roles) do for a_key, a_val in pairs(args) do if string.starts(a_key, rd_key) then if string.len(a_val)
function p.main(frame) local args = getArgs(frame,) local data = getPortalData(args) data = isJoinable(args, data) if not (args.translations and mw.title.new("Template:" .. args.translations).exists) then args.translations = "Probox/Default/Content" end -- mw.log(args.translations) -- if the TCT content index is under translation, check for translations in the subpage language if mw.title.new("Template:" .. args.translations .. "/en").exists then args.translations = TCTlookup(args) end if data.sections.cta
return p