Module:ResearchMetaLandingPage

From Meta, a Wikimedia project coordination wiki
Module documentation
local p = {}
local args = {}
local origArgs = {}
local root

local function getArgNums(prefix)
   -- Returns a table containing the numbers of the arguments that exist
   -- for the specified prefix. For example, if the prefix was 'data', and
   -- 'data1', 'data2', and 'data5' exist, it would return {1, 2, 5}.
   local nums = {}
   for k, v in pairs(args) do
      local num = tostring(k):match('^' .. prefix .. '([1-9]%d*)$')
      if num then table.insert(nums, tonumber(num)) end
   end
   table.sort(nums)
   return nums
end


local function preprocessSingleArg(argName)
   -- If the argument exists and isn't blank, add it to the argument table.
   -- Blank arguments are treated as nil to match the behaviour of ParserFunctions.
   if origArgs[argName] and origArgs[argName] ~= '' then
      args[argName] = origArgs[argName]
   end
end


local function parseDataParameters()
   preprocessSingleArg('archive')
   preprocessSingleArg('projectUnder')
   preprocessSingleArg('title')
   preprocessSingleArg('subtitle')
   preprocessSingleArg('image')
   -- Up to 20 navlink are allowed.
   for i = 1, 20 do
      preprocessSingleArg('navlink' .. tostring(i))
   end
   -- Up to 20 description paragraphs are allowed.
   for i = 1, 20 do
      preprocessSingleArg('description_paragraph' .. tostring(i))
   end
   -- Up to 20 projects are allowed.
   for i = 1, 20 do
      preprocessSingleArg('project_title' .. tostring(i))
      preprocessSingleArg('project_description' .. tostring(i))
      preprocessSingleArg('project_link' .. tostring(i))
   end
end

local function renderHeader(parent)
   local header = parent:tag('div'):attr('id', 'rp_header'):tag('div')
   local el = header:attr('id', 'rp_title'):attr('class', 'rp_meta_title')

   if args.archive then
      el:tag('div'):attr('class', 'rp_status'):wikitext('Archived')
   end

   if args.projectUnder then
      local li = el:tag('div'):attr('id', 'rp_top_nav'):tag('ul'):tag('li')
      li:tag('span'):wikitext('A project under' ..  mw.text.decode( " " ) )
      li:wikitext(args.projectUnder)
   end

   if args.title then
      el
         :tag('h1'):attr('class', 'rp_title'):wikitext(args.title)
         :tag('i'):attr('class', 'rp_clear')
   end

   if args.subtitle then
      el:tag('h1'):attr('class', 'rp_subtitle'):wikitext(args.subtitle)
   end

   if args.image then
      el = header:tag('div'):attr('id', 'rp_title_image'):wikitext(args.image)
   end
end

local function renderNav(parent)
   local nav = parent
      :tag('div'):attr('id', 'rp_nav')
      :tag('div'):attr('id', 'rp_main_nav'):attr('class', 'rp_section rp_menu')
   local ul = nav:tag('ul')
   for k, num in ipairs(getArgNums('navlink')) do
      ul:tag('li'):wikitext(args['navlink' .. tostring(num)])
   end
end

local function renderDescription(parent)
   local description = parent
      :tag('div'):attr('id', 'rp_description'):attr('class', 'rp_padded--top')
   local el = description
      :tag('div'):attr('class', 'rp_content')
      :tag('div'):attr('class', 'rp_description')
   for k, num in ipairs(getArgNums('description_paragraph')) do
      el:tag('p'):wikitext(args['description_paragraph' .. tostring(num)])
   end
   description:tag('i'):attr('class', 'rp_clear')
end

local function renderProjects(parent)
   local el = parent
      :tag('div'):attr('id', 'rp_projects')

   el
      :tag('div'):attr('class', 'rp_meta_title rp_padded--bottom')
      :tag('h2'):attr('class', 'rp_title'):wikitext('Featured Projects')
   local projects = el
      :tag('div'):attr('class', 'rp_projects')
   for k, num in ipairs(getArgNums('project_title')) do
      -- TODO: in design 'rp_project_card_in' is 'a'
      local project = projects
         :tag('div'):attr('class', 'rp_project_card')
         :tag('div'):attr('class', 'rp_project_card_in')
      local texts = project
         :tag('div'):attr('class', 'rp_texts')
      local texts_in = texts
         :tag('div'):attr('class', 'rp_texts_in')
      texts_in
         :tag('h3'):attr('class', 'rp_title')
         :wikitext(args['project_title' .. tostring(num)])
      texts_in
         :tag('div'):attr('class', 'rp_description')
         :tag('p'):wikitext(args['project_description' .. tostring(num)])
      texts
         :tag('div'):attr('class', 'rp_more')
         :wikitext(
            string.format(
               '[[%s|Read more]]',args['project_link' .. tostring(num)]))
      project
         :tag('i'):attr('class', 'rp_clear')
   end
end

local function _landingPage()
   root = mw.html.create()

   local content = root
      :tag('div'):attr('id', 'rp_container')
      :tag('div'):attr('id', 'rp_content')

   renderHeader(content)
   renderNav(content)
   renderDescription(content)
   renderProjects(content)
   content:tag('i'):attr('class', 'rp_clear')

   return tostring(root)
end



function p.landingPage(frame)
   -- If called via #invoke, use the args passed into the invoking template.
   -- Otherwise, for testing purposes, assume args are being passed directly in.
   if frame == mw.getCurrentFrame() then
      origArgs = frame:getParent().args
   else
      origArgs = frame
   end

   parseDataParameters()

   return _landingPage()
end

return p