| Latest revision |
Your text |
| Line 28: |
Line 28: |
| -- External link via wikitext: [url label] — survives sanitizer | | -- External link via wikitext: [url label] — survives sanitizer |
| local function xlink( frame, url, label ) | | local function xlink( frame, url, label ) |
| return frame:preprocess( '<span class="plainlinks">[' .. url .. ' ' .. (label or url) .. ']</span>' ) | | return frame:preprocess( '[' .. url .. ' ' .. (label or url) .. ']' ) |
| end | | end |
|
| |
|
| Line 63: |
Line 63: |
| end | | end |
|
| |
|
| -- ── welcome() ──────────────────────────────────────────────────── | | -- ── hero() ──────────────────────────────────────────────────────── |
| function p.welcome( frame )
| |
| local articles = mw.site.stats.articles
| |
| local formatted = tostring( articles ):reverse():gsub( '(%d%d%d)', '%1,' ):reverse():gsub( '^,', '' )
| |
| | |
| local logo = frame:preprocess( '[[File:BSG-WIKI SM.png|40px|link=Main Page|alt=Battlestar Wiki]]' )
| |
| | |
| local desc = frame:preprocess(
| |
| "The free, non-corporate encyclopedia on all things " ..
| |
| "''Battlestar Galactica'' \226\128\148 " ..
| |
| formatted .. "\194\160articles and counting."
| |
| )
| |
| | |
| local inner =
| |
| '<div class="bsw-welcome-logo">' .. logo .. '</div>' ..
| |
| '<div class="bsw-welcome-text">' ..
| |
| '<div class="bsw-welcome-title">Battlestar Wiki</div>' ..
| |
| '<div class="bsw-welcome-desc">' .. desc .. '</div>' ..
| |
| '</div>' ..
| |
| '<div class="bsw-welcome-links">' ..
| |
| frame:preprocess( '[[Special:Random|Random article]]' ) ..
| |
| frame:preprocess( '[[Battlestar_Wiki:About|About]]' ) ..
| |
| frame:preprocess( '[[Battlestar_Wiki:Community_portal|Community]]' ) ..
| |
| '</div>'
| |
| | |
| return '<div class="bsw-welcome">' .. inner .. '</div>'
| |
| end
| |
| | |
| | |
| function p.hero( frame ) | | function p.hero( frame ) |
| local args = frame.args | | local args = frame.args |
| Line 244: |
Line 216: |
| -- ── photolab() ──────────────────────────────────────────────────── | | -- ── photolab() ──────────────────────────────────────────────────── |
| function p.photolab( frame ) | | function p.photolab( frame ) |
| local args = frame.args | | local args = frame.args |
| local content = mw.text.trim( args.content or '' ) | | local content = args.content or '' |
| local prev_potd = mw.text.trim( args.prev_url or '' ) | | local prev_url = mw.text.trim( args.prev_url or '' ) |
| local prev_lbl = mw.text.trim( args.prev_label or '‹' ) | | local prev_lbl = mw.text.trim( args.prev_label or '‹' ) |
| local next_potd = mw.text.trim( args.next_url or '' ) | | local caption = mw.text.trim( args.caption or '' ) |
| local next_lbl = mw.text.trim( args.next_label or '›' ) | | local next_url = mw.text.trim( args.next_url or '' ) |
| | | local next_lbl = mw.text.trim( args.next_label or '›' ) |
| local caption_page = mw.text.trim( args.caption_page or '' ) | |
| local caption = ''
| |
| if caption_page ~= '' then
| |
| caption = frame:preprocess( '{{' .. caption_page .. '}}' )
| |
| else
| |
| caption = args.caption or ''
| |
| end
| |
|
| |
|
| -- Hide if today's PotD subpage doesn't exist yet | | -- Hide if today's PotD subpage doesn't exist yet |
| if isRedlink( content ) then return '' end | | if isRedlink( content ) then return '' end |
|
| |
| -- The Potd: subpage stores just the bare filename without "File:" prefix.
| |
| local rendered_content = content
| |
| if content ~= '' and not content:match( '%[%[' ) and not content:match( '<' ) then
| |
| local filename = mw.text.trim( content )
| |
| if filename ~= '' then
| |
| -- Use thumb syntax suppressed via frameless|none to avoid
| |
| -- MW adding figure wrapper with extra margins
| |
| rendered_content = frame:preprocess(
| |
| '[[File:' .. filename .. '|center|frameless|upright=1.5]]'
| |
| )
| |
| end
| |
| end
| |
|
| |
| -- Resolve a Potd:MM-DD subpage to its bare filename,
| |
| -- then build a [[File:filename|label]] link from it.
| |
| local function potdFileLink( potd_page, label )
| |
| if potd_page == '' then return label end
| |
| local t = mw.title.new( potd_page )
| |
| if t and t.exists then
| |
| local fn = mw.text.trim( t:getContent() or '' )
| |
| if fn ~= '' and not fn:match( '%[%[' ) then
| |
| -- Use [[:File:...]] (colon prefix) to link TO the file page
| |
| -- rather than [[File:...]] which would transclude/embed the image
| |
| return frame:preprocess( '[[:File:' .. fn .. '|' .. label .. ']]' )
| |
| end
| |
| end
| |
| return frame:preprocess( '[[' .. potd_page .. '|' .. label .. ']]' )
| |
| end
| |
|
| |
|
| local hd = | | local hd = |
| Line 295: |
Line 231: |
| frame:preprocess( '[[BW:Potd|View project →]]' ) .. | | frame:preprocess( '[[BW:Potd|View project →]]' ) .. |
| '</div>' | | '</div>' |
| | |
| | local prev_link = prev_url ~= '' and frame:preprocess( '[[' .. prev_url:gsub('^/','') .. '|' .. prev_lbl .. ']]' ) or prev_lbl |
| | local next_link = next_url ~= '' and frame:preprocess( '[[' .. next_url:gsub('^/','') .. '|' .. next_lbl .. ']]' ) or next_lbl |
|
| |
|
| local nav = | | local nav = |
| '<div class="bsw-photo-nav">' .. | | '<div class="bsw-photo-nav">' .. |
| potdFileLink( prev_potd, prev_lbl ) .. | | prev_link .. |
| '<span class="bsw-photo-caption">' .. caption .. '</span>' .. | | '<span class="bsw-photo-caption">' .. e(caption) .. '</span>' .. |
| potdFileLink( next_potd, next_lbl ) .. | | next_link .. |
| '</div>' | | '</div>' |
|
| |
|
| return '<div class="bsw-card">' .. hd .. rendered_content .. nav .. '</div>' | | return '<div class="bsw-card">' .. hd .. content .. nav .. '</div>' |
| end | | end |
|
| |
|
| Line 343: |
Line 282: |
| -- ── recenttabs() ────────────────────────────────────────────────── | | -- ── recenttabs() ────────────────────────────────────────────────── |
| function p.recenttabs( frame ) | | function p.recenttabs( frame ) |
| local tabs = { {'All','all'}, {'EN','en'}, {'DE','de'}, {'FR','fr'}, {'Media','media'} } | | local tabs = { {'All','all'}, {'EN','en'}, {'DE','de'}, {'Media','media'} } |
| local html = '<div class="bsw-wiki-tabs">' | | local html = '<div class="bsw-wiki-tabs">' |
| for i, t in ipairs(tabs) do | | for i, t in ipairs(tabs) do |
| Line 385: |
Line 324: |
| end | | end |
|
| |
|
| -- ── newestarticle() ────────────────────────────────────────────── | | -- ── sisterprojects() ────────────────────────────────────────────── |
| -- Shell card populated by JS from Special:NewPages API.
| |
| function p.newestarticle( frame )
| |
| return
| |
| '<div class="bsw-card" id="bsw-newest-card">' ..
| |
| '<div class="bsw-card-hd">Newest article' ..
| |
| frame:preprocess( '[[Special:NewPages|All new pages →]]' ) ..
| |
| '</div>' ..
| |
| '<div class="bsw-card-body">' ..
| |
| '<div id="bsw-newest-inner">' ..
| |
| '<div class="bsw-loading"><div class="bsw-spinner"></div>Loading…</div>' ..
| |
| '</div>' ..
| |
| '</div>' ..
| |
| '</div>'
| |
| end
| |
| | |
| | |
| -- Dedicated card for sister wiki links. | | -- Dedicated card for sister wiki links. |
| -- Uses numbered params: |1_label, |1_url, |2_label, |2_url ... | | -- Uses numbered params: |1_label, |1_url, |2_label, |2_url ... |
| Line 424: |
Line 347: |
| '<div class="bsw-card-hd">Sister projects</div>' .. | | '<div class="bsw-card-hd">Sister projects</div>' .. |
| '<div class="bsw-card-body">' .. body .. '</div>' .. | | '<div class="bsw-card-body">' .. body .. '</div>' .. |
| '</div>'
| |
| end
| |
|
| |
| -- ── votd() ────────────────────────────────────────────────────────
| |
| function p.votd( frame )
| |
| local today = os.date( '%Y-%m-%d' )
| |
|
| |
| -- Check for manual override subpage server-side.
| |
| -- Rather than putting the token in a data attribute (which can
| |
| -- trigger Citizen skin hook warnings), we embed it in a hidden
| |
| -- <span> inside the container that the JS reads instead.
| |
| local override_page = 'Battlestar Wiki:Video of the Day/' .. today
| |
| local override_title = mw.title.new( override_page )
| |
| local override_token = ''
| |
| if override_title and override_title.exists then
| |
| local content = override_title:getContent()
| |
| if content then
| |
| override_token = mw.text.trim( content )
| |
| end
| |
| end
| |
|
| |
| local override_span = ''
| |
| if override_token ~= '' then
| |
| override_span =
| |
| '<span id="bsw-votd-override" style="display:none">' ..
| |
| mw.text.nowiki( override_token ) ..
| |
| '</span>'
| |
| end
| |
|
| |
| -- Header bar
| |
| local hd =
| |
| '<div class="bsw-votd-hd">' ..
| |
| '<span class="bsw-votd-hd-inner">' ..
| |
| '<span class="bsw-votd-hd-dot"></span>' ..
| |
| '\226\136\158 Video of the Day' ..
| |
| '</span>' ..
| |
| frame:preprocess( '<span class="plainlinks">[https://battlestarpegasus.com battlestarpegasus.com \226\134\151]</span>' ) ..
| |
| '</div>'
| |
|
| |
| -- Inner grid: player + info panel, both populated by JS
| |
| local inner =
| |
| '<div class="bsw-votd-inner">' ..
| |
| '<div class="bsw-votd-player">' ..
| |
| '<div class="bsw-loading"><div class="bsw-spinner"></div>' ..
| |
| 'Loading today\226\128\153s video\226\128\166</div>' ..
| |
| '</div>' ..
| |
| '<div class="bsw-votd-info" id="bsw-votd-info" style="display:none"></div>' ..
| |
| '</div>'
| |
|
| |
| return
| |
| '<div class="bsw-votd-band" id="bsw-votd-container"' ..
| |
| ' data-date="' .. today .. '">' ..
| |
| override_span ..
| |
| hd .. inner ..
| |
| '</div>' | | '</div>' |
| end | | end |
|
| |
|
| return p | | return p |