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

From Soyjak Wiki, the free ensoyclopedia
Jump to navigationJump to search

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:

  1. 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

In Module:News/config:

  • pages.draft : The draft subpage's name
  • preload, redirectIntro: Pages used by the start and replace links.
  • icons.<icon>: Icons used by this module
  • startPage and replaceRedirect labels: 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