Introducing: Representatives. swedishwin.com, chud.win, and soyzellig.party positions are vacant.
The new Community missions system is now live! Where anyone can propose a task, discuss nominations, or join the current mission. Community missions give editors a place to turn requests from the Janny noticeboard into focused projects. No mission can be too small
Module:News/status
| This module is rated as ready for general use. It is considered stable and may be used wherever appropriate. Improvements should be developed and tested in a sandbox before changing the live module. |
| This module depends on the following other modules: |
This module shows how far each upcoming Soy Chronicle issue has got: one colored row per issue with its state, last edit, and the five-step checklist. The newsroom lists every issue in progress with it, and drafts show the same state at the top of the page, below the nameplate.
Usage
Do not invoke it directly. Call it through {{News/status}}, which also loads the stylesheets.
{{News/status|list}}
One row for a given page:
{{News/status|page=<page>}}
List mode
list draws, in order:
- One row for each issue that is recorded but embargoed, soonest release first.
/# One row for the draft at Soyjak Wiki:The Soy Chronicle/Draft. If it does not exist, the row says "Not started" with a "Start it" link that creates it from Template:News/preload.
This module requires no manual handling. Released issues drop off on their own.
Steps
{{News/issue nameplate
|price= (not relevant to this module)
|articles=no
|headlines=no
|images=no
|layout=no
|proofreading=no
}}
A step is done when its value is yes. Anything else, including blank or missing, counts as a no. Approval is not a step': an issue is approved when its record is added to Module:News/data (read more about releases in the newsroom guide).
States
| State | color | when |
|---|---|---|
| Released | Green | The issue is recorded and its release date has come |
| Scheduled | purple | Embargoed, all five steps are done |
| Scheduled, not ready | purple, warning icon | Embargoed, steps left. Shows release date |
| Overdue | Red, warning icon | The schedule deadline has passed and the issue has no record |
| Not started | gray | The page does not exist |
| Ready for approval | blue | All five steps are done, no record yet |
| In progress | tan | Steps left, no record |
When the deadline is schedule.warn day(s) away or less (1), unrecorded issues also get the warning icon and a line telling the writers to give the issue an embargo if its far from done. The deadline and warning come from the same check as {{News/schedule}}.
A page whose issue is dated after the deadline is a future issue and is never warned or marked overdue. This only matters for page rows of dated pages, as the draft is always dated the deadline.
Rows
Each row has a page link and the state on the left. On the right:
- The release date or the warning, when there is one,
- Last edited (date) by (user) - (size) bytes,
- the checklist.
If the page is a redirect, for example one left behind when the last draft was moved to its release title, it counts as not started, even though the draft page exists. Its link will say "Replace the redirect to start" and opens the page with Template:News/redirect intro to provide instructions on how to proceed.
Drafts
On a draft, {{News/issue nameplate}} shows a strip under the draft notice with the same state, warning, and checklist on the newsroom, through this module. An overdue draft is considered an error and is placed in Category:Newspaper pages with errors. Rows on the Newsroom do not add categories.
Settings
pages.draft: The draft subpage's name
preload,redirectIntro: Pages used by the start and replace links.
icons.<icon>: Icons used by this module
startPageandreplaceRedirectlabels: all the text.
Notes
Styles comes from Template:News/styles.css (state colors and checklist) and Template:News/newsroom.css (rows), loaded by {{News/status}}. Invoking this module will not load the stylesheets. This module is rather expensive, costing around 4 calls per row.
local p = {}
local getArgs = require('Module:Arguments').getArgs
local News = require('Module:News')
local TPV = require('Module:Template parameter value')
local yesno = require('Module:Yesno')
local cfg = News.cfg
local steps = { 'Articles', 'Headlines', 'Images', 'Layout', 'Proofreading' } -- cant be put in config
local function icon(state, kind)
return '[[File:'
.. News.need('icons.' .. kind)
.. '|14px|link=|alt='
.. News.text(state, 'icon' .. kind:sub(1, 1):upper() .. kind:sub(2))
.. ']]'
end
function p.checklist(state, values)
local list = mw.html.create('ul'):addClass('sn-news-checklist')
local count = 0
for _, step in ipairs(steps) do
local value = values[step:lower()]
local done = yesno(value) == true
if done then count = count + 1 end
list:tag('li')
:addClass(done and 'sn-news-checklist-done' or 'sn-news-checklist-todo')
:wikitext(icon(state, done and 'done' or 'todo') .. ' ' .. News.text(state, 'step' .. step))
end
return tostring(list), count == #steps, count, #steps
end
function p.read(name)
local ok, call = TPV.getTemplate(name, 'News/issue nameplate')
if ok then return TPV.getParameters(call) end
return {}
end
function p.decide(issue, s, done, exists)
local warn = s.phase == 'warn'
if issue and issue.state == 'listed' then return 'released', false end
if issue and issue.state == 'embargoed' then return done and 'scheduled' or 'notReady', not done end
if issue and issue.date and s.deadline and issue.date > s.deadline then
warn = false
elseif s.phase == 'overdue' then
return 'overdue', true
end
if not exists then return 'notStarted', warn end
if done then return 'ready', warn end
return 'progress', warn
end
local function stateLabel(state, key, warn)
return (warn and icon(state, 'warn') .. ' ' or '')
.. News.text(state, 'state' .. key:sub(1, 1):upper() .. key:sub(2))
end
local function warning(state, key, s)
if key == 'overdue' then
return News.text(state, 'warnOverdue', { date = News.formatDate(News.need('shortDateFormat'), s.deadline) })
end
return News.text(state, 'warnSoon', { date = News.formatDate(News.need('shortDateFormat'), s.deadline) })
end
function p.notice(state, issue, values, today)
local s = News.schedule(today)
local list, done = p.checklist(state, values)
local key, warn = p.decide(issue, s, done, true)
if key == 'overdue' then News.addCategory(state, 'errors') end
local box = mw.html.create('div'):addClass('sn-news-progress'):addClass('sn-news-status-' .. key)
box:tag('div'):addClass('sn-news-progress-state'):wikitext(stateLabel(state, key, warn))
if warn and key ~= 'notReady' then
box:tag('div'):addClass('sn-news-progress-warning'):wikitext(warning(state, key, s))
end
box:wikitext(list)
return tostring(box)
end
local function row(frame, state, s, today, title, known)
local name = title.prefixedText
local redirect = title.isRedirect
local exists = title.exists and not redirect
local values = exists and p.read(name) or {}
local id = values.issue ~= '' and values.issue or News.idFromTitle(title)
local issue = known or (id and News.issue(id, today))
local list, done = p.checklist(state, values)
local key, warn = p.decide(issue, s, done, exists)
local box = mw.html.create('div'):addClass('sn-news-status plainlinks'):addClass('sn-news-status-' .. key)
local head = box:tag('div'):addClass('sn-news-status-page')
head:tag('div'):addClass('sn-news-status-link'):wikitext(News.link(name, title.subpageText))
head:tag('div'):addClass('sn-news-status-state'):wikitext(stateLabel(state, key, warn))
local body = box:tag('div'):addClass('sn-news-status-body')
if key == 'scheduled' or key == 'notReady' then
body:tag('div'):addClass('sn-news-status-release'):wikitext(
News.text(state, 'releaseLine', { date = News.formatDate(News.need('shortDateFormat'), issue.rec.embargo) })
)
elseif warn then
body:tag('div'):addClass('sn-news-status-warning'):wikitext(warning(state, key, s))
end
if not exists then
local query = redirect and { action = 'edit', editintro = News.need('redirectIntro') }
or { action = 'edit', preload = News.need('preload') }
body:tag('div'):wikitext(
'[' .. title:fullUrl(query) .. ' ' .. News.text(state, redirect and 'replaceRedirect' or 'startPage') .. ']'
)
return tostring(box)
end
local info = frame:preprocess(
'{{REVISIONTIMESTAMP:' .. name .. '}}|{{REVISIONUSER:' .. name .. '}}|{{PAGESIZE:' .. name .. '}}' -- expensive
)
local stamp, user, size = info:match('^(.-)|(.-)|(.*)$')
local date = stamp
and stamp:match('^%d%d%d%d%d%d%d%d')
and stamp:sub(1, 4) .. '-' .. stamp:sub(5, 6) .. '-' .. stamp:sub(7, 8)
body:tag('div'):addClass('sn-news-status-line'):wikitext(News.text(state, 'statusLine', {
date = News.formatDate(News.need('shortDateFormat'), date),
user = user,
size = size,
}))
body:wikitext(list)
return tostring(box)
end
function p.main(frame)
local args = getArgs(frame, { wrappers = cfg.wrappers })
local state = News.newState()
local today = News.today(frame)
local s = News.schedule(today)
if args[1] == 'list' then
local rows = {}
for _, issue in ipairs(s.embargoed) do
local title = mw.title.new(issue.page)
if title then table.insert(rows, row(frame, state, s, today, title, issue)) end
end
local draft = mw.title.new(News.need('pages.base') .. '/' .. News.need('pages.draft'))
if draft then table.insert(rows, row(frame, state, s, today, draft)) end
return News.finish(state, table.concat(rows))
end
local title = args.page and mw.title.new(args.page)
if not title then return '' end
return News.finish(state, row(frame, state, s, today, title))
end
return p
