Module:Calendar widget
Appearance
{{Module rating }}
Usage
{{#invoke:Calendar widget|calendar}}
Lua error in package.lua at line 80: module 'Module:No globals' not found.
Parameters
Calendar parameters
|year=
– specifies the year to be used when creating a monthly or yearly calendar; Gregorian calendar only; minimum 1583 for yearly calendar; minimum October 1582 for stand-alone month calendar; when omitted or out of range, uses current year|month=
– specifies the month to be used when creating an stand-alone month calendar in the year specified by|year=
; accepts a variety values:- numbers
1
to12
– defaults to current month when month number is out of range - month names (
January
,March
, etc) – defaults to current month when month name is not recognized - keywords:
current
– display the current monthlast
– display the month that occurs before the current monthnext
– display the month that occurs after the current month
- numbers
|cols=
– yearly calendars only; number of columnsn
to be used for calendar rendering; default is4
; values ofn
less than 1 or greater than 12 ignored|iso=
– accepts the single valueyes
; calendar renders in ISO week format (Monday through Sunday); not needed if|iso_wk=
set|iso_wk=
– accepts the single valueyes
; calendar renders in ISO week format (Monday through Sunday) with ISO week number in the left column; setting|iso_wk=yes
automatically sets|iso=yes
Styling parameters
|float=
– position the rendered calendar; default position is at the left page margin:center
– middle of the pageright
– at the right page margin
|hide_year=
– accepts the single valueyes
; suppresses display of year in calendar headers; alias|show_year=off
|show_today=
– accepts the single valueyes
; highlights the current date in the current-month calendar|today_color=
– set the highlight color used by|show-today=
; alias:|today_colour=
|title_color=
– set background color for the month title bar; overrides|color=
; alias:|title_colour=
|week_color=
– set background color for the day-abbreviations title bar; overrides|color=
; alias:|week_colour=
|color=
– shorthand for both|title_color=
and|week_color=
;|color=
yields to|title_color=
and|week_color=
; alias:|colour=
|wknum_color=
– set background color for ISO week numbers; alias:|wknum_colour=
Linking parameters
|lk=
– various date component linking options:d
– link days in calendar to calendar day of calendar month –[[June 7]]
m
– link month in calendar header to month article –[[June]] 2019
y
– link year in calendar header to year article –June [[2025]]
dm
– link to days and monthdy
– link to days and yearmy
– link to month and yearyes
– individually link all date componentsm&y
– stand-alone month calendars only; link month and year together as a single composite link –[[June 2025]]
dm&y
– stand-alone month calendars only; link to days and composite month/year
Link prefixes and suffixes
These parameters require |lk=
:
|lk_pref=
– prefix for all day, month, and year links enabled by|lk=
; yields to specific|lk_pref_x=
parameters|lk_suff=
– suffix for all day, month, and year links enabled by|lk=
; yields to specific|lk_suff_x=
parameters
These parameters automatically set |lk=
to the appropriate value; override values assigned to |lk_pref=
and |lk_suff=
:
|lk_pref_d=
– prefix for day links|lk_pref_m=
– prefix for month and composite month/year links|lk_pref_y=
– prefix for year links|lk_suff_d=
– suffix for day links|lk_suff_m=
– suffix for month links and composite month/year links|lk_suff_y=
– suffix for year links
For stand-alone month calendars only, links to previous- and next-month targets:
|prevnext=
– accepts the single valueyes
; adds generic << and >> links to month header linked to the preceding and next month articles; automatically set if any of the following parameters are set:|lk_pref_mprev=
– prefix for previous-month link|lk_suff_mprev=
– suffix for previous-month link|lk_pref_mnext=
– prefix for next-month link|lk_suff_mnext=
– suffix for next-month link
Examples
if the current page and section is [[An example page#May]]
and there is a May calendar there, to offer links to the previous month (April) and next month (June) sections set:
|k_pref_mprev=#
– creates link to[[An example page#April]]
|k_pref_mnext=#
– creates link to[[An example page#June]]
if the current page is a subpage [[An example page/May]]
and there is a May calendar there, to offer links to the previous month and next month subpages set:
|k_pref_mprev=../
– creates link to[[An example page/April]]
|k_pref_mnext=../
– creates link to[[An example page/June]]
- in
../
,..
is the parent ([[An example page]]
) and/
is the required path separator; see Uniform Resource Identifier
- in
--[[
Module to create Calendar widget
--]]
require('Module:No globals');
local getArgs = require ('Module:Arguments').getArgs;
local lang_obj = mw.language.getContentLanguage();
local p = {}
local daysinmonth = {
31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
}
local dayname = {
"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"
}
local dayabbr = {}
for i, v in ipairs(dayname) do
dayabbr[i] = v:sub(1, 2)
end
local monthname = {
"January", "February", "March", "April", "May", "June",
"July", "August", "September", "October", "November", "December"
}
local monthabbr = {}
for i, v in ipairs(monthname) do
monthabbr[i] = v:sub(1, 3)
end
local monthnumber = {}
for i, v in ipairs(monthabbr) do
monthnumber[v] = i
end
local thisyear = tonumber( lang_obj:formatDate ("Y") )
local thismonth = tonumber( lang_obj:formatDate ("n") )
local function isleap(year)
return '1' == lang_obj:formatDate ('L', tostring(year));
-- year = tonumber(year) or 1
-- return year % 4 == 0
-- and year % 100 ~= 0
-- or year % 1000 == 0
end
--[[
Sakamoto's method: 1 <= month <= 12; year is Gregorian
dayofweek returns 1 to 7 or nil if bad arguments
--]]
local function dayofweek(year, month, day)
return lang_obj:formatDate ('w', year .. '-' .. month .. '-' .. day) + 1;
-- local y = tonumber(year)
-- local m = tonumber(month)
-- local d = tonumber(day)
-- if not (y and m and d) then return nil end
-- local t = {0, 3, 2, 5, 0, 3, 5, 1, 4, 6, 2, 4}
-- if m < 3 then y = y - 1 end
-- return (y + math.floor(y/4) - math.floor(y/100) + math.floor(y/400) + t[m] + d) % 7 + 1
end
-- year and month both numeric:
local function monthstart(year, month)
return dayofweek(year, month, 1)
end
-- generate the html to display a month calendar
local function displaymonth(props, mnum)
local year = props.year
if isleap(year) then daysinmonth[2] = 29 end
local firstday = monthstart(year, mnum)
local monthcal = {}
local hdr_year = props.show_year and year or '';
table.insert(monthcal, '<table class="mcal">')
table.insert(monthcal, '<tr class="mcalhdr">')
-- table.insert(monthcal, '<th class="mcal" colspan="7">' .. monthname[mnum] .. ' ' .. year .. '</th>')
table.insert(monthcal, '<th class="mcal" colspan="7">' .. monthname[mnum] .. ' ' .. hdr_year .. '</th>')
table.insert(monthcal, '</tr>')
table.insert(monthcal, '<tr class="mcalhdr">')
for c = 1, 7 do
table.insert(monthcal, '<th class="mcal" scope="col">' .. dayabbr[c] .. '</th>')
end
table.insert(monthcal, '</tr>')
local numrows = math.ceil( (firstday + daysinmonth[mnum] - 1) / 7 )
for r = 1, numrows do
table.insert(monthcal, '</tr>')
for c = 1, 7 do
local dom = 7 * (r-1) + c + 1 - firstday
if dom < 1 or dom > daysinmonth[mnum] then dom = " " end
table.insert(monthcal, '<td class="mcal">' .. dom .. '</td>')
end --columns
table.insert(monthcal, '<tr class="mcal">')
end --rows
table.insert(monthcal, '</table>')
return table.concat(monthcal, '\n')
end
local function displayyear(props)
local year = props.year
local rows = props.rows
local cols = props.cols or 4
local mnum;
if rows then
cols = math.ceil(12 / rows)
else
rows = math.ceil(12 / cols)
end
local yearcal = {}
table.insert(yearcal, '<table class="ycal">')
table.insert(yearcal, '<tr class="ycalhdr">')
table.insert(yearcal, '<th class="ycal" colspan="' .. cols .. '>' .. year .. '</th>')
for r = 1, rows do
table.insert(yearcal, '<tr class="ycal" style="vertical-align:top;">')
for c = 1, cols do
mnum = cols * (r - 1) + c
if mnum < 13 then
table.insert(yearcal, '<td class="ycal">' .. displaymonth(props, mnum) .. '</td>')
else
table.insert(yearcal, ' ')
end
end --cols
table.insert(yearcal, '</tr>')
end
table.insert(yearcal, '</table>')
return table.concat(yearcal, '\n')
end
local function calendar(props)
-- local year = args.year or thisyear
-- local year = args.year
local month = props.month
if month then
local mnum = tonumber(month)
-- if not mnum then
-- if month == "current" then
-- mnum = thismonth
-- year = thisyear
-- elseif month == "last" then
-- mnum = thismonth - 1
-- if mnum == 0 then
-- mnum = 12
-- year = thisyear - 1
-- end
-- elseif month == "next" then
-- mnum = thismonth + 1
-- if mnum == 13 then
-- mnum = 1
-- year = thisyear + 1
-- end
-- else
-- mnum = monthnumber[month:sub(1,3)] or thismonth
-- end
-- end
-- args.year = year
if mnum > 0 and mnum <13 then
props.show_year = true; -- show year in individual month calendars
return displaymonth(props, mnum)
else
return displayyear(props)
end
else
-- args.year = year
return displayyear(props)
end
end
--------------------------------------------------
--[[
Sakamoto's method: ISO date
returns day name or nil if bad arguments
--]]
function p.dayofweek(frame)
local isodate = mw.text.trim(frame.args[1] or "")
local y, m, d = isodate:match("(%d+)%p(%d+)%p(%d+)")
local dow = dayofweek(y, m, d)
if not dow then return "" end
return dayname[dow]
end
--[[
isleap returns "leap" if passed a leap year
otherwise returns nothing
]]
function p.isleap(frame)
if isleap(frame.args[1]) then return "leap" end
return ""
end
--[[
Main entry point for widget
--]]
function p.calendar(frame)
-- local args = {}
-- for k, v in pairs(frame:getParent().args) do
-- if v ~= "" then args[k] = v end
-- end
-- for k, v in pairs(frame.args) do
-- if v ~= "" then args[k] = v end
-- end
local args=getArgs (frame);
local cal_props = {}; -- separate calendar properties table to preserve arguments as originally provided
cal_props.year = args.year and tonumber(args.year) or thisyear;
if args.month then
local mnum = tonumber(args.month)
if not mnum then -- month provided as some sort of text string
if args.month == "current" then
-- mnum = thismonth
-- year = thisyear
cal_props.month = thismonth
cal_props.year = thisyear
elseif args.month == "last" then
mnum = thismonth - 1
if mnum == 0 then
-- mnum = 12
-- year = thisyear - 1
cal_props.month = 12 -- december last year
cal_props.year = thisyear - 1 -- last year
else
cal_props.month = mnum; -- previous month
end
elseif args.month == "next" then
mnum = thismonth + 1
if mnum == 13 then
-- mnum = 1
-- year = thisyear + 1
cal_props.month = 1 -- january next year
cal_props.year = thisyear + 1 -- next year
else
cal_props.month = mnum; -- next month
end
else
-- mnum = monthnumber[month:sub(1,3)] or thismonth
local good
good, cal_props.month = pcall (lang_obj.formatDate, lang_obj, 'n', args.month);
if not good then
cal_props.month = thismonth
end
end
else
cal_props.month = mnum; -- month provided as a number
end
end
return calendar(cal_props)
end
return p