Module:Archives
From BoyWiki
Documentation for this module may be created at Module:Archives/doc
p = {} local cfg = mw.loadData('Module:Archives/config') local function is_filled(var) return var and var ~= '' end -- simple helper for simple cases local function var_or_default(var, default) if is_filled(var) then return var else return default end end local function wikilink(link, display) if display then return '[[' .. link .. '|' .. display .. ']]' else return '[[' .. link .. ']]' end end local function talk_other(demospace, talk) if is_filled(demospace) then return demospace end if mw.title.getCurrentTitle().isTalkPage then return talk end return nil -- just return nil rather than 'other' since we have no need end local function add_image(image) if image.image and (image.image == 'none' or image.image == '') then return nil end return mw.html.create('div'):addClass('archives-image'):wikitext( require('Module:InfoboxImage/sandbox')._InfoboxImage({ [cfg.img_mod.image] = var_or_default(image.image, cfg.image), [cfg.img_mod.alt] = var_or_default(image.alt, cfg.img_mod.alt_none), [cfg.img_mod.link] = var_or_default(image.link, cfg.img_mod.link_none), [cfg.img_mod.size] = var_or_default(image.size, nil), [cfg.img_mod.sizedefault] = cfg.image_size }) ) end local function auto_list(list_root, is_banner, list_auto, list_prefix) local list_args = {} if list_root then list_args.root = list_root else list_args.DISABLE1 = list_root end if is_banner then list_args.nobr = 'yes' list_args.DISABLE2 = list_auto or 'long' else list_args.nobr = 'no' list_args.auto = list_auto or 'long' end if list_prefix then list_args.prefix = list_prefix else list_args.DISABLE3 = list_prefix end return require('Module:Archive list').main(list_args) end local function make_title(is_banner, title) end local function search_box(frame, is_banner, root, search) if search.search and search.search == cfg.search_no then return nil end local prefix = '' if is_filled(search.prefix) then prefix = search.prefix -- this double-check elseif may move out to code-proper elseif is_filled(root) then prefix = root else prefix = mw.title.getCurrentTitle().prefixedText .. '/' end -- break local sbreak if search.sbreak and (search.sbreak == 'yes' or search.sbreak == 'no') then sbreak = search.sbreak end -- set sbreak's default if not sbreak then if is_banner then sbreak = 'no' else sbreak = 'yes' end end -- width local width = '' if not is_banner then width = var_or_default(search.width, cfg.search_width) end -- label local label = var_or_default(search.label, cfg.search_label) local inputbox_options = { ['bgcolor'] = 'transparent', ['type'] = 'fulltext', ['prefix'] = prefix, ['break'] = sbreak, ['width'] = width, ['searchbuttonlabel'] = label } local inputbox_content = {} for k, v in pairs(inputbox_options) do table.insert(inputbox_content, k .. '=' .. v) end return mw.html.create('div'):addClass('archives-search'):wikitext(frame:extensionTag{ name = 'inputbox', content = table.concat(inputbox_content, '\n') }) end local function note_auto(frame, auto) if not is_filled(auto.age) and not is_filled(auto.target) then return nil end local age = var_or_default(auto.age, nil) local target = var_or_default(auto.target, nil) local target_text = '' if target then target_text = mw.ustring.format( cfg.has_archives, frame:callParserFunction( '#rel2abs', target ), age and ' ' or '' ) end local age_text = '' if age then local units = var_or_default(auto.units, cfg.units) -- there's probably a friendlier l10n way to do this check on units... -- TODO make it friendlier. maybe split it to a separate function? -- (borrowed from Module:String.endswith in the meantime) if age ~= '1' and mw.ustring.sub(units, -1, -1) ~= 's' then units = units .. 's' end -- TODO localize local age_with_units = age .. ' ' .. units local has_bot = is_filled(auto.bot) local has_minthreads = is_filled(auto.minthreads) if has_bot and has_minthreads then age_text = mw.ustring.format( cfg.age_bot_threads, age_with_units, wikilink('User:' .. auto.bot, auto.bot), var_or_default(auto.minthreads, cfg.min_threads) ) elseif has_bot then age_text = mw.ustring.format( cfg.age_bot, age_with_units, wikilink('User:' .. auto.bot, auto.bot) ) elseif has_minthreads then age_text = mw.ustring.format( cfg.age_threads, age_with_units, var_or_default(auto.minthreads, cfg.min_threads) ) else age_text = mw.ustring.format( cfg.age, age_with_units ) end end return mw.html.create('div'):addClass('archives-auto'):wikitext(target_text .. age_text) end local function edit_list(frame, auto, list1, archive_list, archive_list_exists, editbox) local has_editbox = not editbox or (editbox and (editbox == '' or editbox == 'yes')) if not (archive_list_exists and has_editbox and not auto and list1) then return nil end return mw.html.create('div'):addClass('archives-edit'):wikitext(mw.ustring.format( cfg.edit_this_box, archive_list.fullUrl('action=edit' .. cfg.pre_load) )) end local function render_list(root, auto, list1, archive_list_title, archive_list_exists, list, index, prefix) -- this logic is seriously fucking screwy -- only hope is for the test cases to catch the insanity local auto_default = true if list1 then auto_default = false end local is_foreign = true if (auto and auto == 'no') or (not auto and not auto_default) then is_foreign = false end local foreign_archive_list = '' local list = var_or_default(content.list, nil) if not list and is_foreign then local index_page = frame:callParserFunction( '#rel2abs', var_or_default(content.index, './Archive index') ) local index_link = '' if mw.title.new(index_page).exists then index_link = wikilink(index_page, 'Index') end local prefix = var_or_default(content.prefix, nil) if archive_list_exists then foreign_archive_list = frame:expandTemplate{ title = archive_list_name} else foreign_archive_list = auto_list(root, is_banner, auto, prefix) end foreign_archive_list = index_link .. foreign_archive_list end local local_archive_list = '' if list or list1 then local_archive_list = '\n' .. (list or list1) end return foreign_archive_list .. local_archive_list end local function add_main_content(frame, is_banner, content) local is_collapsible = false local is_collapsed = false if content.collapsible and content.collapsible == 'yes' then is_collapsible = true end if content.collapsed and content.collapsed == 'yes' then is_collapsed = true is_collapsible = true end local root = var_or_default(content.root, nil) local auto = var_or_default(content.auto, nil) local list1 = var_or_default(content.list1, nil) local archive_list_name = frame:callParserFunction( '#rel2abs', var_or_default(content.archive_list, cfg.archive_list) ) local archive_list_title = mw.title.new(archive_list_name) local archive_list_exists = archive_list_title.exists local all_lists = render_list( root, auto, list1, archive_list_title, archive_list_exists, content.list, content.index, content.prefix ) local main_content = mw.html.create() main_content :tag('div') :addClass('archives-flex-child') :wikitext(all_lists) :node(search_box(frame, is_banner, root, content.search)) :node(note_auto(frame, content.auto_explanation)) :node(edit_list( frame, auto, list1, archive_list_title, archive_list_exists, content.editbox )) return main_content end --[[ pass the frame down for a minute because we do a lot of work with a frame ]] function p._main(args, frame) local is_banner = false if (args[cfg.arg.banner] and args[cfg.arg.banner] == cfg.banner_yes) or (args[cfg.arg.large] and args[cfg.arg.large] == cfg.banner_yes) then is_banner = true end local archives = mw.html.create() archives :tag('div') :addClass('archives plainlinks') -- banner is roughly mbox, small is roughly mbox-small :addClass(is_banner and 'archives-banner' or 'archives-small') -- archives-talk has same-ish styles as tmbox tmbox-notice -- base styles are same-ish as ombox ombox-notice :addClass(talk_other( var_or_default(args[cfg.arg.demospace], nil), 'archives-talk' )) :css('width', var_or_default(args[cfg.arg.box_width], nil)) :cssText(var_or_default(args[cfg.arg.style], nil)) :node(add_image({ image = args[cfg.arg.image], alt = args[cfg.arg.alt], link = args[cfg.arg.link], size = args[cfg.arg.image_size] })) :node(add_main_content(frame, is_banner, { archive_list = args[cfg.arg.archive_list], auto = args[cfg.arg.auto], collapsible = args[cfg.arg.collapsible], collapsed = args[cfg.arg.collapsed], edit_box = args[cfg.arg.edit_box], index = args[cfg.arg.index], list = args[cfg.arg.list], list1 = args[cfg.arg.list1], prefix = args[cfg.arg.prefix], root = args[cfg.arg.root], title = args[cfg.arg.title], search = { search = args[cfg.arg.search], prefix = args[cfg.arg.search_prefix], width = args[cfg.arg.search_width], sbreak = args[cfg.arg.search_break], label = args[cfg.arg.search_button_label] }, auto_explanation = { age = args[cfg.arg.age], target = args[cfg.arg.target], units = args[cfg.arg.units], bot = args[cfg.arg.bot], minthreads = args[cfg.arg.minthreads] } })) return frame:extensionTag{ name = 'templatestyles', args = { src = cfg.templatestyles } } .. tostring(archives) end function p.main(frame) return p._main(require('Module:Arguments').getArgs(frame), frame) end return p