Jump to content

Module:Probox and Module:Probox/sandbox: Difference between pages

(Difference between pages)
Page 1
Page 2
Content deleted Content added
Update from master using Synchronizer #synchronizer
 
Create sandbox version of Module:Probox
 
Line 6: Line 6:
local p = {}
local p = {}


function addTemplates(frame, data, args)
--function GetPageLang (frame) local pagelang = frame:callParserFunction{ name = '#translation:'} if pagelang == nil then pagelang = "/en" end return pagelang end

local function stringStarts(String,Start)
return string.sub(String,1,string.len(Start))==Start
end

local function stringToLowerCase(value)
return mw.ustring.lower(value)
end
local function stringSpacesToUnderscores(value)
return mw.ustring.gsub(value, " ", "_")
end

local function stringFirstCharToUpper(str)
return (str:gsub("^%l", string.upper))
end

local function addTemplates(frame, data, args)
-- adds additional template to the top of the page, above the infobox
-- adds additional template to the top of the page, above the infobox
local page_template
local page_template
-- local tmplt_args = {}
-- local tmplt_args = {}
local template_div = mw.html.create('div')
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
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]) == "table") then --convert args to lowercase before checking them against cats
if (args[k] and string.len(args[k]) > 0 and type(data.templates[k]) == "table") then --convert args to lowercase before checking them against cats
Line 37: Line 19:
:wikitext(frame:expandTemplate{title=data.templates[k][tmplt_key], args={status = stringFirstCharToUpper(args[k])}}) --status is special casing. need to pass generic arg keys
:wikitext(frame:expandTemplate{title=data.templates[k][tmplt_key], args={status = stringFirstCharToUpper(args[k])}}) --status is special casing. need to pass generic arg keys
:done()
:done()
break
break
elseif (stringToLowerCase(args[k]) == tmplt_key and mw.title.new("Template:" .. tmplt_val).exists) then
elseif (stringToLowerCase(args[k]) == tmplt_key and mw.title.new("Template:" .. tmplt_val).exists) then
template_div
template_div
Line 48: Line 30:
-- if (type(tmplt_val) == "string" and stringToLowerCase(args[k]) == tmplt_key and mw.title.new("Template:" .. tmplt_val).exists) then
-- if (type(tmplt_val) == "string" and stringToLowerCase(args[k]) == tmplt_key and mw.title.new("Template:" .. tmplt_val).exists) then


end
end
end
end
end
end
page_template = tostring(template_div)
page_template = tostring(template_div)
return page_template
return page_template
end
end


local function addCategories(frame, data, args, open_roles)
function addCategories(data, args, open_roles)
-- will also look for numbered categories
-- will also look for numbered categories
local cat_list = {}
local cat_list = {}
Line 63: Line 45:
if data.categories.default then
if data.categories.default then
table.insert(cat_list, data.categories.default)
table.insert(cat_list, data.categories.default)
end
end
if data.categories.roles then
if data.categories.roles then
role_cat = data.categories.roles
role_cat = data.categories.roles
Line 83: Line 65:
end
end
end
end
end
end
local page_categories = " [[" .. tostring(table.concat(cat_list, "]] [[")) .. "]]"
local page_categories = ""
-- testing
local pagelang = mw.text.trim(frame:callParserFunction{name='#translation', args="1"})
-- local pagelang = "/" .. mw.text.trim(frame:expandTemplate{title='CURRENTCONTENTLANGUAGE'})

if #cat_list > 0 then
if pagelang == nil then
page_categories = "[[" .. tostring(table.concat(cat_list, "]] [[")) .. "]]"
else
page_categories = "[[" .. tostring(table.concat(cat_list, pagelang .. "]] [[")) .. pagelang .. "]]"
end
end
if(args["status"] == "selected" or args["status"] == "SELECTED") then
maintainer = args["grantee"] or args["organization"] or args["creator"] or args["grantee1"] or args["grantee2"]
--if username is given as wikilink, extract clean username
maintainer = mw.ustring.match(maintainer, "%[%[[Uu]ser:(.+)|") or maintainer
page_categories = page_categories.. "[[Category:WMF grant reports by grantee|"..maintainer.."]]"
category_per_grantee = mw.title.new("Category:"..maintainer)
if category_per_grantee.exists then page_categories = page_categories.. "[[Category:"..maintainer.."]]" end
end
return page_categories
return page_categories
end
end


local function makeTextField(field, field_div)
function makeTextField(field, field_div)
-- makes a formatted text field for output, based on parameter
-- makes a formatted text field for output, based on parameter
-- values or on default values provided for that field
-- values or on default values provided for that field
Line 123: Line 79:
:tag('span')
:tag('span')
:cssText(field.style2)--inconsistent use of styles 2/3 here
:cssText(field.style2)--inconsistent use of styles 2/3 here
:wikitext(field.title)--we probably aren't using this for most things now, after Heather's redesign
:wikitext(field.title)--we probably aren't using this for most things now, after Heather's redesign
:done()
:done()
:tag('span')
:tag('span')
:cssText(field.style3)
:cssText(field.style3)
:wikitext(field.values[1])
:wikitext(field.values[1])
:done()
:done()
elseif field.vtype2 == "title" then
elseif field.vtype2 == "title" then
field_div
field_div
Line 134: Line 90:
:cssText(field.style3)
:cssText(field.style3)
:wikitext(field.values[1])
:wikitext(field.values[1])
:done()
:done()
elseif field.vtype2 == "link" then
elseif field.vtype2 == "link" then
field_div
field_div
:tag('span')
:tag('span')
:cssText(field.style3)
:cssText(field.style3)
:wikitext("[[" .. field.values[1] .. "|<span style='" .. field.style2 .. "'>" .. field.title .."</span>]]")
:wikitext("[[" .. field.values[1] .. "|<span style='" .. field.style2 .. "'>" .. field.title .."</span>]]")
:done()
:done()
Line 144: Line 100:
field_div:done()
field_div:done()
return field_div
return field_div
end
end


local function makeImageField(field, field_div)
function makeImageField(field, field_div)
-- makes a formatted image field for output, based on parameter values
-- makes a formatted image field for output, based on parameter values
-- provided in the calling template or its parent template, or on default
-- provided in the calling template or its parent template, or on default
Line 154: Line 110:
:tag('span')
:tag('span')
:cssText(field.style3)
:cssText(field.style3)
if field.vtype2 == "thumb" then
if field.vtype2 == "thumb" then
field_div
field_div
:wikitext("[[" .. field.values[1] .. "|right|" .. field.width .."]]")
:wikitext("[[" .. field.values[1] .. "|right|" .. field.width .."]]")
elseif field.vtype2 == "thumb2" then
field_div
:wikitext("[[" .. field.values[1] .. "|center|" .. field.width .."]]")
elseif field.vtype2 == "link" then
elseif field.vtype2 == "link" then
field_div
field_div
Line 167: Line 120:
field_div
field_div
:wikitext("[[" .. field.icon .. "|" .. field.alignment .. "|" .. field.width .."|link=" .. field.values[1] .. "]] " .. "[" .. field.values[1] .. " " .. field.title .. "]")
:wikitext("[[" .. field.icon .. "|" .. field.alignment .. "|" .. field.width .."|link=" .. field.values[1] .. "]] " .. "[" .. field.values[1] .. " " .. field.title .. "]")
end
end
elseif field.vtype2 == "ui_button" then
elseif field.vtype2 == "ui_button" then
field_div
field_div
:addClass(field.class)
:addClass(field.class)
:wikitext(field.title)
:wikitext(field.title)
:done()
:done()
end
end
field_div:done()
field_div:done()
return field_div
return field_div
end
end


local function makeParticipantField(field, ftype)
function makeParticipantField(field, ftype)
local field_div = mw.html.create('div')
local field_div = mw.html.create('div')
local title_span
local title_span
Line 185: Line 138:
else
else
title_span = field.title
title_span = field.title
end
end
field_div
field_div
:cssText(field.style)
:cssText(field.style)
Line 206: Line 159:
else
else
v = "• " .. "[[User:" .. v .. "|" .. v .. "]]"
v = "• " .. "[[User:" .. v .. "|" .. v .. "]]"
end
end
field_div
field_div
:tag('span')
:tag('span')
:cssText(field.style3)
:cssText(field.style3)
:wikitext(v)
:wikitext(v)
-- :wikitext("• " .. "[[User:" .. v .. "|" .. v .. "]]")
-- :wikitext("• " .. "[[User:" .. v .. "|" .. v .. "]]")
:done()
:done()
i = i + 1
i = i + 1
end
end
end
end
field_div:allDone()
field_div:allDone()
return field_div
return field_div
end
end


local function makeSectionDiv(sec_fields, sec_style)
function makeSectionDiv(sec_fields, sec_style)
local sec_div = mw.html.create('div'):cssText(sec_style)
local sec_div = mw.html.create('div'):cssText(sec_style)
sec_fields = TableTools.compressSparseArray(sec_fields)
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
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)
sec_div:node(sec_field)
end
end
return sec_div
return sec_div
end
end


local function makeParticipantsSection(frame, args, data, filled_role_data, open_roles)
function makeParticipantsSection(frame, args, data, filled_role_data, open_roles)
local filled_role_fields = {}
local filled_role_fields = {}
for role, val_table in pairs(filled_role_data) do
for role, val_table in pairs(filled_role_data) do
local field = data.fields[role]
local field = data.fields[role]
field.title = mw.text.trim(frame:expandTemplate{title=args.translations, args={field.key}})
field.title = mw.text.trim(frame:expandTemplate{title=args.translations, args={field.key}})
field.values = {}
field.values = {}
for val_num, val_text in ipairs(filled_role_data[role]) do
for val_num, val_text in ipairs(filled_role_data[role]) do
field.values[#field.values + 1] = val_text
field.values[#field.values + 1] = val_text
end
end
local filled_field_div = makeParticipantField(field, "filled")
local filled_field_div = makeParticipantField(field, "filled")
filled_role_fields[field.rank] = filled_field_div
filled_role_fields[field.rank] = filled_field_div
end
end
local sec_div = makeSectionDiv(filled_role_fields, data.styles.section["participants"])
local sec_div = makeSectionDiv(filled_role_fields, data.styles.section["participants"])
Line 245: Line 198:
-- if (args.portal == "Idealab" or args.portal == "Research") then -- beware, exceptions everywhere
-- if (args.portal == "Idealab" or args.portal == "Research") then -- beware, exceptions everywhere
sec_div:tag('span'):cssText("font-style:italic; color: #888888"):wikitext(mw.text.trim(frame:expandTemplate{title=args.translations, args={data.fields.more_participants.key}})):done()
sec_div:tag('span'):cssText("font-style:italic; color: #888888"):wikitext(mw.text.trim(frame:expandTemplate{title=args.translations, args={data.fields.more_participants.key}})):done()
-- elseif args.portal == "Patterns" then
-- elseif args.portal == "Patterns" then
-- sec_div:tag('span'):cssText("font-style:italic; color: #888888"):wikitext("a learning pattern for..."):done()
-- sec_div:tag('span'):cssText("font-style:italic; color: #888888"):wikitext("a learning pattern for..."):done()
-- else
-- else
for role, val in pairs(open_roles) do -- should make these ordered using compressSparseArray, as above
for role, val in pairs(open_roles) do -- should make these ordered using compressSparseArray, as above
local field = data.fields[role]
local field = data.fields[role]
Line 253: Line 206:
if field.icon then
if field.icon then
field.icon = field.icon_inactive
field.icon = field.icon_inactive
end
end
local open_field_div = makeParticipantField(field, "open")
local open_field_div = makeParticipantField(field, "open")
sec_div:node(open_field_div)
sec_div:node(open_field_div)
end
end
end
end
sec_div:allDone()
sec_div:allDone()
return sec_div
return sec_div
end
end


local function makeSectionFields(args, field)
function makeSectionFields(args, field)
-- ui button is separate
-- ui button is separate
local field_div = mw.html.create('div'):cssText(field.style) --why declare this here?
local field_div = mw.html.create('div'):cssText(field.style) --why declare this here?
Line 268: Line 221:
if (field.isRequired == true or (args[field.arg] and string.len(args[field.arg]) > 0)) then --should move this up, may not just apply to images
if (field.isRequired == 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)
field_div = makeImageField(field, field_div)
end
end
elseif field.vtype == "text" then
elseif field.vtype == "text" then
field_div = makeTextField(field, field_div)
field_div = makeTextField(field, field_div)
else
else
end
end
return field_div -- make sure div is 'done'
return field_div -- make sure div is 'done'
end
end


local function makeSection(frame, args, data, box_sec)
function makeSection(frame, args, data, box_sec)
-- return a div for a section of the box including child divs
-- return a div for a section of the box including child divs
-- for each content field in that section
-- for each content field in that section
-- local sec_div = mw.html.create('div'):cssText(data.styles.section[box_sec])
-- local sec_div = mw.html.create('div'):cssText(data.styles.section[box_sec])
local sec_fields = {}
local sec_fields = {}
for k,v in pairs(data.fields) do
for k,v in pairs(data.fields) do
Line 290: Line 243:
if field.toLowerCase == true then -- special casing to make IEG status=SELECTED to display in lowercase
if field.toLowerCase == true then -- special casing to make IEG status=SELECTED to display in lowercase
field.values[1] = stringToLowerCase(field.values[1])
field.values[1] = stringToLowerCase(field.values[1])
end
end
local field_div = makeSectionFields(args, field)
local field_div = makeSectionFields(args, field)
sec_fields[field.rank] = field_div
sec_fields[field.rank] = field_div
elseif field.isRequired == true then
elseif field.isRequired == true then
if field.vtype == "text" then
if field.vtype == "text" then
Line 300: Line 253:
end
end
local field_div = makeSectionFields(args, field)
local field_div = makeSectionFields(args, field)
sec_fields[field.rank] = field_div
sec_fields[field.rank] = field_div
else
else
--don't make a section for this field
--don't make a section for this field
Line 308: Line 261:
local sec_div = makeSectionDiv(sec_fields, data.styles.section[box_sec])
local sec_div = makeSectionDiv(sec_fields, data.styles.section[box_sec])
return sec_div
return sec_div
end
end


local function makeInfobox(frame, args, data, filled_role_data, open_roles)
function makeInfobox(frame, args, data, filled_role_data, open_roles)
-- builds the infobox. Some content sections are required, others
-- builds the infobox. Some content sections are required, others
-- are optional. Optional sections are defined in the stylesheet.
-- are optional. Optional sections are defined in the stylesheet.
Line 318: Line 271:
local sec_top = makeSection(frame, args, data, "above")
local sec_top = makeSection(frame, args, data, "above")
box:node(sec_top)
box:node(sec_top)
end
end
if data.sections.nav == true then
if data.sections.nav == true then
local sec_nav = makeSection(frame, args, data, "nav")
local sec_nav = makeSection(frame, args, data, "nav")
box:node(sec_nav)
box:node(sec_nav)
end
end
local sec_head = makeSection(frame, args, data, "head")
local sec_head = makeSection(frame, args, data, "head")
inner_box:node(sec_head)
inner_box:node(sec_head)
Line 333: Line 286:
if data.sections.cta == true then
if data.sections.cta == true then
local sec_cta = makeSection(frame, args, data, "cta")
local sec_cta = makeSection(frame, args, data, "cta")
sec_cta:addClass("noprint") -- no much use in print outs
inner_box:node(sec_cta)
inner_box:node(sec_cta)
inner_box:tag('div'):cssText("clear:both;"):done() --clears buttons in the cta sections
inner_box:tag('div'):cssText("clear:both"):done() --clears buttons in the cta sections
end
end
inner_box:allDone()
inner_box:allDone()
box:node(inner_box)
box:node(inner_box)
Line 342: Line 294:
local sec_bottom = makeSection(frame, args, data, "below")
local sec_bottom = makeSection(frame, args, data, "below")
box:node(sec_bottom)
box:node(sec_bottom)
end
end
box:allDone()
box:allDone()
return box
return box
end
end


local function orderStringtoNumber(array, val, num)
function orderStringtoNumber(array, val, num)
if num > table.getn(array) then
if num > table.getn(array) then
array[#array+1] = val
array[#array+1] = val
else
else
table.insert(array, num, val)
table.insert(array, num, val)
end
end
return array
return array
end
end
local function isJoinable(args, data)
function isJoinable(args, data)
if args.more_participants == "NO" then
if args.more_participants == "NO" then
data.fields.join = nil
data.fields.join = nil
if data.fields.endorse then
data.fields.endorse.style = "display:inline; float:right;"
end
data.fields.endorse.style = "display:inline; float:right;"
end
end
return data
return data
end
end


local function deepCopyTable(data)
function deepCopyTable(data)
-- the deep copy is a workaround step to avoid the restrictions placed on
-- the deep copy is a workaround step to avoid the restrictions placed on
-- tables imported through loadData
-- tables imported through loadData
Line 380: Line 330:
end
end
local function getPortalData(args)
function getPortalData(args)
-- loads the relevant stylesheet, if a sub-template was called with a portal
-- loads the relevant stylesheet, if a sub-template was called with a portal
-- argument and a stylesheet exists with the same name. For example, calling
-- argument and a stylesheet exists with the same name. For example, calling
-- {{#invoke:Probox|main|portal=Idealab}} would load the Module:Probox/Idealab
-- {{#invoke:Probox/Idealab|main|portal=Idealab}} would load the
-- Module:Probox/Idealab stylesheet
-- stylesheet.
local data_readOnly = {}
local data_readOnly = {}
local data_writable = {}
local data_writable = {}
Line 391: Line 341:
else
else
data_readOnly = mw.loadData("Module:Probox/Default")
data_readOnly = mw.loadData("Module:Probox/Default")
end
end
-- data_writable = TableTools.shallowClone(data_readOnly)
-- data_writable = TableTools.shallowClone(data_readOnly)
data_writable = deepCopyTable(data_readOnly)
data_writable = deepCopyTable(data_readOnly)
Line 397: Line 347:
end
end


local function TCTlookup(args)
function string.starts(String,Start)
return string.sub(String,1,string.len(Start))==Start
end

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)
local tct_path = tostring(args.translations)
--mw.log(mw.title.getCurrentTitle().subpageText)
--mw.log(mw.title.getCurrentTitle().subpageText)
Line 410: Line 376:
-- mw.log(tct_path)
-- mw.log(tct_path)
return tct_path
return tct_path
end
end


local function getRoleArgs(args, available_roles)
function getRoleArgs(args, available_roles)
-- returns:
-- returns:
-- 1) a table of ordered values for valid role params,
-- 1) a table of ordered values for valid role params,
Line 422: Line 388:
if available_roles.default then -- some boxes have default role to join
if available_roles.default then -- some boxes have default role to join
open_roles[available_roles.default] = true
open_roles[available_roles.default] = true
end
end
for rd_key, rd_val in pairs(available_roles) do
for rd_key, rd_val in pairs(available_roles) do
for a_key, a_val in pairs(args) do
for a_key, a_val in pairs(args) do
if stringStarts(a_key, rd_key) then
if string.starts(a_key, rd_key) then
if string.len(a_val) == 0 then
if string.len(a_val) == 0 then
open_roles[rd_key] = true
open_roles[rd_key] = true
Line 434: Line 400:
filled_role_data[rd_key] = orderStringtoNumber(filled_role_data[rd_key], a_val, arg_num)
filled_role_data[rd_key] = orderStringtoNumber(filled_role_data[rd_key], a_val, arg_num)
else
else
table.insert(filled_role_data[rd_key], 1, a_val)
table.insert(filled_role_data[rd_key], 1, a_val)
end
end
end
end
end
end
end
end
end
end
return filled_role_data, open_roles
return filled_role_data, open_roles
end
end


function p.main(frame)
function p.main(frame)
Line 452: Line 418:
-- mw.log(args.translations)
-- mw.log(args.translations)
-- if the TCT content index is under translation, check for translations in the subpage language
-- 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
if mw.title.new("Template:" .. args.translations .. "/en").exists then
args.translations = TCTlookup(args)
args.translations = TCTlookup(args)
end
end
if data.sections.cta == true then
if data.sections.cta == true then
args.talk = tostring(mw.title.getCurrentTitle().talkPageTitle) -- expensive
args.talk = tostring(mw.title.getCurrentTitle().talkPageTitle) -- expensive
end
end
local filled_role_data, open_roles = getRoleArgs(args, data.roles)
local filled_role_data, open_roles = getRoleArgs(args, data.roles)
local box = makeInfobox(frame, args, data, filled_role_data, open_roles)
local box = makeInfobox(frame, args, data, filled_role_data, open_roles)
local infobox = tostring(box)
local infobox = tostring(box)
-- only add cats if not in Template or User or Meta namespace
-- only add cats if not in Template or User ns
if (data.categories and (mw.title.getCurrentTitle().nsText ~= "Template" and mw.title.getCurrentTitle().nsText ~= "User" and mw.title.getCurrentTitle().nsText ~= "Meta") and not args.noindex) then
if (data.categories and (mw.title.getCurrentTitle().nsText ~= "Template" and mw.title.getCurrentTitle().nsText ~= "User" and mw.title.getCurrentTitle().nsText ~= "Meta") and not args.noindex) then
-- FIXME specify namespace in config, so that categories only appear if template is translcuded in that namespace
-- FIXME specify namespace in config, so that categories only appear if template is translcuded in that namespace
local page_categories = addCategories(frame, data, args, open_roles)
page_categories = addCategories(data, args, open_roles)
infobox = infobox .. page_categories
infobox = infobox .. page_categories
end
end
if data.templates then
if data.templates then
local top_template = addTemplates(frame, data, args)
local top_template = addTemplates(frame, data, args)
infobox = top_template .. infobox
infobox = top_template .. infobox
end
end
return infobox
return infobox
end
end