-- HELPER FUNCTIONS --
local function notblank(v) return (v or '' ) ~= '' end
local function ifblank(v, alt) return notblank(v) and v or alt end
local function red(v) return '<span style="color: red;">' .. v .. '</span>' end
local function getContent(page) return mw.ustring.gsub(mw.title.new(page).content, '^Date,"[^"]+"', '') end
local function diffDays(dargs)
return require('Module:diff days')['diff_days'](
mw.getCurrentFrame():newChild{ title = 'Template:Diff_days', args = dargs }
)
end
-- EXPORTED CONSTANTS --
local p = {
gSTALE = function() return 30 end, --global for representing the age in days after which a pageviews file, and any chart based on it, becomes stale and no longer appropriate for display on a Talk page. Stale pages should have their pageviews file updated.
gCOUNT = function() return 75 end, --global for representing the default number of days to display in the chart; overridable with param {{para|ct}}.
}
function p._xviews(args) -- {{xviews}}
local page = ifblank(args[1], mw.title.getCurrentTitle().fullText .. '/pageviews')
if mw.title.new(page).exists then
local stale = ifblank(args.stale, p.gSTALE())
if p._age(page) > stale then --stale:
return red(mw.ustring.format(
'The pageviews file [[%s]] is more than %d days old; please see [[Template:Xviews#Instructions|Instructions]].',
page, stale
))
else --not stale:
return p._xvmain(page, ifblank(args.days, ifblank(args.ct, p.gCOUNT()))) ..
((notblank(args.log) or notblank(args.mode)) and p._xAxis(page) or '')
end
else
return red('Missing required pageviews file.') ..
' See [[Template:Xviews#Instructions|Instructions]].'
end
end
function p.xviews(frame)
return p._xviews(frame.args)
end
function p._age(page) -- {{xviews/age}}
local nthview = p._nthView(page, p._viewCount(page))
nthview = mw.text.split(nthview, ':', true)[1]
return diffDays({nthview, mw.getContentLanguage():formatDate('j F Y'), precision=0})
end
function p.age(frame)
return p._age(ifblank(frame.args[1] or 'Talk:Liberation of France/pageviews'))
end
function p._nthView(page, number) -- {{xviews/nth view}}
local views = mw.ustring.gsub(getContent(page), '.?(202%d%-%d%d%-%d%d)%,?(%d+)', '%1:%2,')
return mw.text.split(views, ',', true)[tonumber(number)]
end
function p.nthView(frame)
return p._nthView(
ifblank(frame.args[1] or 'Talk:Liberation of France/pageviews'),
ifblank(frame.args[2] or 3)
)
end
function p._viewCount(page) -- {{xviews/view count}}
local str = mw.ustring.gsub(getContent(page), '.?202%d%-%d%d%-%d%d', '')
str = mw.ustring.gsub(str, ',', '', 1)
-- Remove leading and trailing delimiters (along with any surrounding whitespace)
str = str:gsub("^%s*,%s*", ""):gsub("%s*,%s*$", "")
-- Normalize internal consecutive delimiters to a single delimiter (replace ",," with ",")
str = str:gsub("%s*,%s*,%s*", ',')
return select(2, str:gsub(',', '')) + 1
end
function p.viewCount(frame)
return p._viewCount(ifblank(frame.args[1] or 'Talk:Liberation of France/pageviews'))
end
function p._xvmain(page, xargs) -- {{xviews/xvmain}}
-- xargs contains ct, log, mode, and debug
local output = {}
local stop = p.viewCount(page)
local start = stop - math.min(152, ifblank(xargs.ct, 93)) + 1
local iargs = {
page = page,
max = p._maxViews(page),
log = xargs.log, -- logarithmic scale (not implemented yet)
mode = xargs.mode, -- bar display orientation (mode=vert not implemented yet)
debug = xargs.debug, -- set to non-empty for loop debug output emitted by p._itemBar()
}
for n = start, stop do
iargs.n = n
table.insert(output, p.itemBar(iargs))
end
return table.concat(output)
end
function p.xvmain(frame)
xargs = frame.args
xargs.ct = ifblank(xargs.ct, 93)
return p._xvmain(ifblank(xargs[1], 'Talk:Liberation of France/pageviews'), xargs)
end
function p._itemBar(iargs) -- {{xviews/item bar}}
-- iargs contains n, page, max, log, mode, and debug
if iargs.debug then
return mw.ustring.format("page=%s, n=%s, label=%s",
ifblank(iargs.page, 'missing'),
ifblank(iargs.n, 'missing'),
ifblank(iargs.label, 'missing')
)
end
local nthview = p._nthView(iargs.page, ifblank(iargs.n, 1))
local val = mw.text.split(nthview, ':', true)[2] or 0
local width = val * 100 * 0.88 / p._maxViews(page)
width = tonumber(string.format("%.2f", width))
local label = p._xlabel(mw.text.split(nthview, ':', true)[1], 'y')
return p._vbar(width, val, {label = label})
end
function p.itemBar(frame)
iargs = frame.args
iargs.page = ifblank(iargs.page, 'Talk:House of the Dragon/pageviews')
iargs.n = ifblank(iargs.n, 1)
return p._itemBar(iargs)
end
function p._vbar(width, val, vargs) -- {{xviews/vbar}}
-- vargs contains label, label-style, thick, style, val, and val-style
local ts = mw.getCurrentFrame():extensionTag{
name = 'templatestyles',
args = {src = 'Template:Xviews/vbar/styles.css'}
}
local div = mw.html.create('div'):attr('class', 'vbar')
if notblank(vargs.label) then
div:tag('span')
:attr('class', 'vbar-labelh')
:cssText(ifblank(vargs['label-style']))
:wikitext(vargs.label)
end
div:tag('span')
:attr('class', 'vbar-h')
:attr('alt', 'Page views for (date) = (views).')
:css('height', ifblank(vargs['thick']))
:css('width', width .. '%')
:cssText(ifblank(vargs.style))
if notblank(val) then
div:tag('span')
:attr('class', 'vbar-valh')
:cssText(ifblank(vargs['val-style']))
:wikitext(val)
end
return ts .. tostring(div)
end
function p.vbar(frame)
vargs = frame.args
return p._vbar(ifblank(vargs[1], 75), ifblank(vargs[2], ifblank(vargs.val, 2136)), vargs)
end
function p._xlabel(date, bold01) -- {{xviews/xlabel}}
end
function p._maxViews(page) -- {{xviews/max views}}
return 1
end
function p._xAxis(page) -- {{xviews/x-axis}}
end
return p