Jump to content
Toggle menu
  • 12,3 E szócikkek
  • 21,5 E fájlok
  • 4 felhasználók
  • 63,9 E szerkesztések
SCWIKI
Toggle preferences menu
Toggle personal menu
Nem vagy bejelentkezve
Your IP address will be publicly visible if you make any edits.
Module documentation[view][edit][history][purge]
This documentation is transcluded from Modul:Mainpage/doc. Changes can be proposed in the talk page.
Function list
L 76 — stylesheets
L 95 — band
L 118 — footer
L 133 — p.render
L 159 — p.main
L 169 — p.hero

Renders the main page: hero, highlights, featured article, on this day, the editing invitation, the two community cards, the directory at the foot, and a foot row linking the page an editor changes.

Reached through {{Mainpage}}, which is one line and takes no parameters:

{{Mainpage}}

The page needs nothing else: the module emits its own TemplateStyles and the tracking category that loads the gadget. One dependency does live outside it — MediaWiki:Citizen.css drops the body container's gutter for the main page, which is what lets the bands paint full bleed. Anywhere else the bands sit inside the skin's normal gutter.

Changing what the page shows

Everything an editor changes is in one file, Module:Mainpage/settings.json, linked from the foot of the rendered page. It carries its own guidance in a _readme at the top; what follows is the reference.

Section Holds
featured page and text — the article in the featured card and the line beside its title. The picture is the article's own Page Image, so the page name is all there is to set; without one it falls back to a placeholder. With no page at all the card falls back to Star Citizen — deliberately not the main page itself, which would render as a self-link and silently kill the whole-card link.
event name, page, text, starts, ends, and one of banner or image — see below. Clearing name removes the whole card; clearing ends keeps the card and drops its countdown.
patches One object per build chip: channel, name, page, highlights. Channel LIVE takes the filled marker and also fills the "this patch" card. Adding a chip is adding an object.
hero image, lede, ledeDetail, searchTails.
chips The row of links under the hero.
directory The groups of links at the foot.

A link entry is { "page": …, "label": … } for somewhere on this wiki or { "url": …, "label": … } for somewhere else; label is optional on a wiki link. How many columns the directory shows is not configured anywhere: it reflows to fit.

The event card's two designs

The picture chooses the design, because the picture is the thing that actually differs. Set one key, not both; with both, banner wins.

Key Design
banner One of the 1080×83 strips in Category:Main page banner images. It runs across the top of the card at the height it was drawn, so the card shows a centred slice of it rather than a shrunken whole: about two thirds at the full measure, about a quarter in the narrowest column. What to check before setting one is not its height, which is fixed, but whether its logo survives a centre crop; a banner with its mark out at an edge loses it on a phone.
image An ordinary screenshot. It stands in a column beside the text on a wide card and across the top on a narrow one, so its subject wants to be near the middle. A banner strip set here comes out a smear; a portrait column is the one shape a 13:1 frieze cannot be cropped to.

Naming the asset names the layout, so no editor can pair a design with a picture it cannot show. Switching between them is a settings edit, never a module edit.

Why JSON and not a #switch template. Three things that matter to the people editing it: MediaWiki refuses to save invalid JSON, so the page cannot be left broken; a list is a real array, so nothing has to be escaped or separated; and the build chips are a list of objects rather than patch1type / patch2type / patch3type flattened into numbered keys. The cost, paid deliberately, is that JSON has no comments — so the guidance that used to sit inline lives in the file's own _readme and here.

A malformed value never takes the page down. An event date the clock cannot read costs the clock and nothing else; a settings page that has been moved or deleted costs only what it feeds. Dates are accepted as YYYY-MM-DD, optionally with HH:MM or HH:MM:SS, and a trailing UTC is tolerated; anything else is treated as unset.

Structure

Submodule Renders
Module:Mainpage/Config Loads the settings file; normalises it into plain Lua and resolves which build is live
Module:Mainpage/Nav Turns a link entry into wikitext
Module:Mainpage/Hero The hero band
Module:Mainpage/Highlights The event and patch cards
Module:Mainpage/Featured The featured card
Module:Mainpage/OnThisDay Today's date page, as a tabber
Module:Mainpage/Editing The editing invitation and recent-changes list
Module:Mainpage/Community The funding and Discord cards
Module:Mainpage/Directory The directory at the foot

The foot row is small enough to live in Module:Mainpage itself rather than take a submodule of its own.

Module:Mainpage/Config is the only thing that touches mw.loadJsonData. It copies the result into a plain table on the way through, which confines the read-only metatable — the one that breaks # and next() — to a single function, and drops blank strings so clearing a value behaves the same as deleting its line. It also answers which build is live, in one place, so the chip that gets the filled marker and the card that says "New in …" can never name different builds.

Buttons come from Module:ButtonLua, the badge from Module:BadgeLua and the clock from Module:Countdown, so each keeps its own look and this module supplies only content and placement.

The two highlight cards are Module:CardLua media cards. The other five are built here with .t-card on a plain div, because they are not media cards — the featured card puts its body over the picture under a scrim, and the rest carry no picture at all. Module:CardLua/styles.css is therefore loaded explicitly by this module; leaving it to arrive with a CardLua call would strip the card chrome off the page whenever the highlights band is empty.

The grid

Every band is .home-band (full-bleed ground) wrapping .home-band__inner (the measured column). A band of cards puts .home-grid on the inner element. All bands share one twelve-column grid so a card edge in one lands on the same line as a card edge in the next; a band that sets its own column ratios breaks that alignment for the whole page.

Spans go on the card itself: .home-card--read (8), .home-card--aside (4), .home-card--tall (8, spanning two rows). They are placement properties, so unlike a class that sets display they cannot collide with CardLua's own .t-card. Never put a class that sets display on the same element as t-card.

Between 640 and 900 every card becomes span 6, which keeps two columns without changing the arrangement. Below 640 the page is a single column in DOM order.

Styles

Page Holds
Module:Mainpage/styles.css The hero, the bands, the grid, and the responsive stages
Module:Mainpage/cards.css The individual cards, the directory, and the foot
Module:Mainpage/ground.css The graduation tapes and the dot lattice behind the page

The gadget

MediaWiki:Gadget-mainpage.js enhances the rendered page: it loads the hero artwork after page load, rolls the stat digits and the search label's tail, drives the clock, and refreshes the activity list — which matters because DPL forces a one-hour parser cache on any page that calls it.

It reads its context from data-gadget-mainpage-* attributes on the elements it enhances, so grep gadget-mainpage- finds every emitter and the gadget that consumes them. The page renders and reads correctly with the gadget absent.

Previewing

{{#invoke:Mainpage|hero}}              — the hero on its own
{{#invoke:Mainpage|hero|noscript=yes}} — as a reader with no JavaScript sees it

require('strict')

--- @module Mainpage
--- Renders the main page.
---
--- Everything editors change — the featured article, the running event, the
--- build chips, the hero, and both link lists — lives in
--- [[Module:Mainpage/settings.json]]. Nothing on this page needs a module edit
--- to keep it current, and the foot links straight to it.
---
--- LAYOUT CONTRACT. Every band is `.home-band` for its full-bleed ground and
--- `.home-band__inner` for the measured column inside it, and every band of
--- cards puts `.home-grid` on that inner element. One twelve-column grid is
--- shared by all of them, so a card edge in one band lands on the same line as
--- a card edge in the next. A band that sets its own column ratios breaks that
--- alignment for every band on the page.
---
--- Card spans go on the card itself (`.home-card--read`, `--aside`, `--tall`)
--- because `grid-column` is a placement property and cannot collide with
--- Module:CardLua's own `display` on `.t-card`. A class that sets `display`
--- must never share an element with `t-card`.
---
--- Structure:
---
---   hero          full bleed, gadget-loaded artwork
---   highlights    [ event 8 ][ patch 4 ]
---   band 1        [ featured 8 ][ on this day 4 ]
---   band 2        [ editing 8, two rows ][ support 4 ]
---                                        [ discussion 4 ]
---   directory     six groups, no card
---   foot          where to edit what the page says

local community = require('Module:Mainpage/Community')
local directory = require('Module:Mainpage/Directory')
local editing = require('Module:Mainpage/Editing')
local featured = require('Module:Mainpage/Featured')
local hero = require('Module:Mainpage/Hero')
local highlights = require('Module:Mainpage/Highlights')
local onThisDay = require('Module:Mainpage/OnThisDay')

--- Loaded in this order: the card primitive first, then the grid and hero, then
--- the components that sit on the grid, then the ground behind both.
---
--- CardLua's sheet is listed EXPLICITLY rather than left to arrive with a
--- CardLua call. Five of the seven cards are built here with `.t-card` on a
--- plain div, so the card surface, border and radius would otherwise depend on
--- the highlights band happening to render — and that band is empty whenever
--- both its settings keys are blank.
local STYLESHEETS = {
	'Module:CardLua/styles.css',
	'Module:Mainpage/styles.css',
	'Module:Mainpage/cards.css',
	'Module:Mainpage/ground.css',
}

--- Where to go to change what the page says, linked at the foot.
---
--- NOT "edit this page". The page is a single transclusion, so an edit link on
--- it lands an editor in a file with nothing in it to change. This is the one
--- surface that holds content, and it covers everything an editor can change
--- without touching Lua.
local EDIT_TARGETS = {
	{ page = 'Module:Mainpage/settings.json', label = 'Settings' },
}

--- What loads [[MediaWiki:Gadget-mainpage.js]]. Emitted by the module so the
--- invocation is self-sufficient: a page that renders this and does not carry
--- the category gets no lazy artwork, no rolling digits and a clock that never
--- starts, with nothing on the page to say why.
local GADGET_CATEGORY = 'Pages using main page gadget'

local p = {}

--- @param frame mw.frame
--- @return string
local function stylesheets(frame)
	local tags = {}
	for _, src in ipairs(STYLESHEETS) do
		tags[#tags + 1] = frame:extensionTag({
			name = 'templatestyles',
			args = { src = src },
		})
	end
	return table.concat(tags)
end

--- One band of cards on the shared grid.
---
--- Varargs and not a table: a table would be walked with ipairs, which stops at
--- the first nil, so a card that declined to render would silently take every
--- card after it with it. select('#') counts the nils.
---
--- @param ... string|nil
--- @return string
local function band(...)
	local root = mw.html.create('div'):addClass('home-band'):addClass('home-wiki')

	local inner = root:tag('div'):addClass('home-band__inner'):addClass('home-grid')

	for i = 1, select('#', ...) do
		inner:wikitext((select(i, ...)))
	end

	return tostring(root)
end

--- The maintenance affordance at the foot of the page.
---
--- External-link syntax because an internal link cannot carry a query string,
--- and `plainlinks` because the destinations are on this wiki and the arrow
--- icon would say otherwise.
---
--- mw.uri.fullUrl and NOT callParserFunction: `fullurl` is a colon magic word,
--- registered under the name `fullurl:`, and callParserFunction resolves it as
--- `fullurl`, which does not exist. mw.uri is the addressable API for this.
---
--- @return string
local function footer()
	local root = mw.html.create('div'):addClass('home-band'):addClass('home-wiki')

	local inner = root:tag('div'):addClass('home-band__inner'):addClass('home-foot'):addClass('plainlinks')

	for _, target in ipairs(EDIT_TARGETS) do
		inner
			:tag('span')
			:wikitext(string.format('[%s %s]', tostring(mw.uri.fullUrl(target.page, 'action=edit')), target.label))
	end

	return tostring(root)
end

--- @return string
function p.render()
	local frame = mw.getCurrentFrame()

	local root = mw.html.create('div'):addClass('home-page')

	-- Both are empty and painted entirely in CSS: the dot lattice outside the
	-- tapes, and the tapes themselves. The tape is `position: fixed` and the
	-- dots are not, so the instrument holds still while the page scrolls past.
	root:tag('div'):addClass('home-sky')
	root:tag('div'):addClass('home-tape')

	root:wikitext(hero.render({}))
	root:wikitext(highlights.render())
	root:wikitext(band(featured.render(), onThisDay.render()))
	root:wikitext(band(editing.render(), community.renderSupport(), community.renderDiscussion()))
	root:wikitext(directory.render())
	root:wikitext(footer())

	return stylesheets(frame) .. tostring(root) .. string.format('[[Category:%s]]', GADGET_CATEGORY)
end

--- Wikitext entry point. Reached through [[Template:Mainpage]] rather than
--- invoked directly, so the page that carries it stays one transclusion.
---
--- @param frame mw.frame
--- @return string
function p.main(frame)
	return p.render()
end

--- The hero on its own, for previewing it outside the page. `noscript=yes`
--- renders it without the gadget's artwork hook, which is what a reader with
--- scripts off or Save-Data on receives.
---
--- @param frame mw.frame
--- @return string
function p.hero(frame)
	local args = require('Module:Arguments').getArgs(frame)
	local yesno = require('Module:Yesno')

	return stylesheets(frame)
		.. tostring(
			mw.html
				.create('div')
				:addClass('home-page')
				:wikitext(hero.render({ lazyArt = yesno(args.noscript, false) ~= true }))
		)
end

return p
Tartalomjegyzék