Modul:Sports results
This Lua-based module is meant to build match result tables. Note that this module is used extensively, so test potential changes rigorously in the sandbox and please ensure consensus exists before implementing major changes. Also note that the module is called from Module:Sportstabel and check for potential issues there as well after making changes. The rest of this documentation explains how to use this module in an article or template, check the table of contents for specific items.
Usage redigér
The template can be used as follows:
What you type | {{#invoke:Sports results|main |update=1 January 1900 |source=[https://en.wikipedia.org/wiki/Main_Page Wikipedia] |showteam=CCC |team1=FDT |team2=BBB |team3=CCC |team4=DDD |team5=EEE |name_FDT=[[FIFA World Cup Dream Team]] |short_FDT=[[FIFA World Cup Dream Team|FDT]] |name_BBB=Team 2 |short_BBB=T2 |name_CCC=Team 3 |short_CCC=T3 |name_DDD=DDD F.C. |short_DDD=DDD |name_EEE={{fb-rt|GIB}} |short_EEE={{flagicon|Gibraltar}} |match_FDT_BBB=1–0 |match_FDT_CCC=0–1 |match_FDT_DDD=<small>16 Nov '14</small> |match_FDT_EEE=<small>3 Sep '15</small> |match_BBB_FDT=B–F |match_BBB_CCC=<small>3 Sep '15</small> |match_BBB_DDD=B–D |match_BBB_EEE=<small>3 Sep '15</small> |match_CCC_FDT=<small>16 Nov '14</small> |match_CCC_BBB=C–B |match_CCC_DDD=<small>16 Nov '14</small> |match_CCC_EEE=C–E |match_DDD_FDT=D–F |match_DDD_BBB=<small>3 Sep '15</small> |match_DDD_CCC=D–C |match_DDD_EEE=<small>3 Sep '15</small> |match_EEE_FDT=E–F |match_EEE_BBB=9–5 |match_EEE_CCC=<small>16 Nov '14</small> |match_EEE_DDD=E–D |match_FDT_BBB_note=Match awarded to FIFA World Cup Dream Team with a 1–0 score. }} | ||||||||||||||||||||||||||||||||||||
What it looks like |
Opdateret indtil kampe spillet den 1 January 1900. Kilde: Wikipedia Notes:
|
The main command is {{#invoke:Sports results|main}}, which calls the module and sets the basic structure up. Then you list the order in which the teams are listed as |team1=
, |team2=
, etc for however many teams you need in the table. If you set |showteam=
to a team, then that team's results are highlighted as in the example. The display of team names for team TTT is now governed by |name_TTT=
and |short_TTT=
for the row and column headers respectively. The results for the game TTT vs. SSS can now be input by |match_TTT_SSS=
. The table is build this way, future games can be listed with their date or they can be left blank.
The source is controlled by |source=
. The update date can be set by |update=date
when the season is active; can be removed after the season with |update=complete
and can be set for a future start date by using |update=future
and setting the start date with |start_date=
.
The width of the columns can be set by |match_col_width=
.
A note can be added to a result using |match_TTT_SSS_note=
.
Another example is:
What you type | {{#invoke:Sports results|main |team1=CZE |team2=ISL |team3=KAZ |team4=LVA |team5=NED |team6=TUR |name_CZE={{fb-rt|CZE}} |short_CZE={{flagicon|CZE}} |name_ISL={{fb-rt|ISL}} |short_ISL={{flagicon|ISL}} |name_KAZ={{fb-rt|KAZ}} |short_KAZ={{flagicon|KAZ}} |name_LVA={{fb-rt|LVA}} |short_LVA={{flagicon|LVA}} |name_NED={{fb-rt|NED}} |short_NED={{flagicon|NED}} |name_TUR={{fb-rt|TUR}} |short_TUR={{flagicon|TUR}} |match_CZE_ISL=[[UEFA Euro 2016 qualifying Group A#Czech Republic v Iceland|<small>16 Nov '14</small>]] |match_CZE_KAZ=[[UEFA Euro 2016 qualifying Group A#Czech Republic v Kazakhstan|<small>3 Sep '15</small>]] |match_CZE_LVA=[[UEFA Euro 2016 qualifying Group A#Czech Republic v Latvia|<small>28 Mar '15</small>]] |match_CZE_NED=[[UEFA Euro 2016 qualifying Group A#Czech Republic v Netherlands|2–1]] |match_CZE_TUR=[[UEFA Euro 2016 qualifying Group A#Czech Republic v Turkey|<small>10 Oct '15</small>]] |match_ISL_CZE=[[UEFA Euro 2016 qualifying Group A#Iceland v Czech Republic|<small>12 Jun '15</small>]] |match_ISL_KAZ=[[UEFA Euro 2016 qualifying Group A#Iceland v Kazakhstan|<small>6 Sep '15</small>]] |match_ISL_LVA=[[UEFA Euro 2016 qualifying Group A#Iceland v Latvia|<small>10 Oct '15</small>]] |match_ISL_NED=[[UEFA Euro 2016 qualifying Group A#Iceland v Netherlands|2–0]] |match_ISL_TUR=[[UEFA Euro 2016 qualifying Group A#Iceland v Turkey|3–0]] |match_KAZ_CZE=[[UEFA Euro 2016 qualifying Group A#Kazakhstan v Czech Republic|2–4]] |match_KAZ_ISL=[[UEFA Euro 2016 qualifying Group A#Kazakhstan v Iceland|<small>28 Mar '15</small>]] |match_KAZ_LVA=[[UEFA Euro 2016 qualifying Group A#Kazakhstan v Latvia|0–0]] |match_KAZ_NED=[[UEFA Euro 2016 qualifying Group A#Kazakhstan v Netherlands|<small>10 Oct '15</small>]] |match_KAZ_TUR=[[UEFA Euro 2016 qualifying Group A#Kazakhstan v Turkey|<small>12 Jun '15</small>]] |match_LVA_CZE=[[UEFA Euro 2016 qualifying Group A#Latvia v Czech Republic|<small>6 Sep '15</small>]] |match_LVA_ISL=[[UEFA Euro 2016 qualifying Group A#Latvia v Iceland|0–3]] |match_LVA_KAZ=[[UEFA Euro 2016 qualifying Group A#Latvia v Kazakhstan|<small>13 Oct '15</small>]] |match_LVA_NED=[[UEFA Euro 2016 qualifying Group A#Latvia v Netherlands|<small>12 Jun '15</small>]] |match_LVA_TUR=[[UEFA Euro 2016 qualifying Group A#Latvia v Turkey|1–1]] |match_NED_CZE=[[UEFA Euro 2016 qualifying Group A#Netherlands v Czech Republic|<small>13 Oct '15</small>]] |match_NED_ISL=[[UEFA Euro 2016 qualifying Group A#Netherlands v Iceland|<small>3 Sep '15</small>]] |match_NED_KAZ=[[UEFA Euro 2016 qualifying Group A#Netherlands v Kazakhstan|3–1]] |match_NED_LVA=[[UEFA Euro 2016 qualifying Group A#Netherlands v Latvia|<small>16 Nov '14</small>]] |match_NED_TUR=[[UEFA Euro 2016 qualifying Group A#Netherlands v Turkey|<small>28 Mar '15</small>]] |match_TUR_CZE=[[UEFA Euro 2016 qualifying Group A#Turkey v Czech Republic|1–2]] |match_TUR_ISL=[[UEFA Euro 2016 qualifying Group A#Turkey v Iceland|<small>13 Oct '15</small>]] |match_TUR_KAZ=[[UEFA Euro 2016 qualifying Group A#Turkey v Kazakhstan|<small>16 Nov '14</small>]] |match_TUR_LVA=[[UEFA Euro 2016 qualifying Group A#Turkey v Latvia|<small>3 Sep '15</small>]] |match_TUR_NED=[[UEFA Euro 2016 qualifying Group A#Turkey v Netherlands|<small>6 Sep '15</small>]] }} |
What it looks like |
Opdateret indtil kampe spillet den unknown. Kilde: [kilde mangler]
|
Win/Draw/Loss colour redigér
The colour of win/draw/loss colour can be set by |matches_style=FBR
.
What you type | {{#invoke:sports results|main |source = |update=22. april 2018 |matches_style = FBR |team1=CER |team2=DAV |team3=GLC |team4=JPV |team5=KAY |team6=STA |name_CER=[[Ceres–Negros F.C.|Ceres–Negros]] |name_DAV=[[Davao Aguilas F.C.|Davao Aguilas]] |name_GLC=[[Global Cebu F.C.|Global Cebu]] |name_JPV=[[JPV Marikina F.C.|JPV Marikina]] |name_KAY=[[Kaya F.C.|Kaya–Iloilo]] |name_STA={{nowrap|[[Stallion Laguna F.C.|Stallion Laguna]]}} |match_CER_DAV={{small|{{small|23 May}}}} |match_CER_GLC={{small|{{small|30 May}}}} |match_CER_JPV={{small|{{small|20 Jun}}}} |match_CER_KAY=2–1 |match_CER_STA={{small|{{small|2 Jun}}}} |match_DAV_CER={{small|{{small|2 May}}}} |match_DAV_GLC={{small|{{small|20 Jun}}}} |match_DAV_JPV=3–2 |match_DAV_KAY=2–2 |match_DAV_STA={{small|{{small|6 May}}}} |match_GLC_CER=0–2 |match_GLC_DAV=2–2 |match_GLC_JPV={{small|{{small|27 May}}}} |match_GLC_KAY={{small|{{small|23 May}}}} |match_GLC_STA=1–2 |match_JPV_CER=0–3 |match_JPV_DAV={{small|{{small|9 Jun}}}} |match_JPV_GLC=2–1 |match_JPV_KAY={{small|{{small|5 May}}}} |match_JPV_STA={{small|{{small|19 May}}}} |match_KAY_CER={{small|{{small|12 May}}}} |match_KAY_DAV={{small|{{small|20 May}}}} |match_KAY_GLC={{small|{{small|2 May}}}} |match_KAY_JPV=1–0 |match_KAY_STA=4–1 |match_STA_CER={{small|{{small|26 May}}}} |match_STA_DAV=0–1 |match_STA_GLC={{small|{{small|12 May}}}} |match_STA_JPV=1–2 |match_STA_KAY=3–1 }} | |||||||||||||||||||||||||||||||||||||||||||||||||
What it looks like |
Opdateret indtil kampe spillet den 22. april 2018. Kilde:
Colours: Blue = home team win; Yellow = draw; Red = away team win. |
Team header redigér
To change the default Home \ Away
team header, use |team_header=
.
Two legs redigér
For two matches per team pair, use |legs=2
and |match1_AAA_BBB=
/ |match2_AAA_BBB=
instead of |match_AAA_BBB=
.
Generating a blank table redigér
To generate a blank table, use
{{subst:#invoke:Sports results/blank|main | team1 = AAA | team2 = BBB | ... }}
where |team1=
, |team2=
, ... are the abbreviations for the team names in the order you wish them to appear. You may include |name_...=
and other parameters as well, and they should be included in the result.
Dokumentationen ovenfor er transkluderet fra Modul:Sports results/dok. (redigér | historik) Brugere kan eksperimentere i dette moduls undersider sandkasse (opret | kopiér) og testcases (opret). Undersider til dette modul. |
-- Module to build results cross-tables for standings in Sports
-- See documentation for details
require('Module:No globals')
local p = {}
-- Main function
function p.main(frame)
-- Declare locals
local Args = frame.args
local N_teams = 0
local t = {}
local t_footer = {}
local t_return = {}
local team_list = {}
local notes_exist = false
local ii, ii_fw, bg_col, team_name, team_code_ii
-- Optional custom team header
local team_header = Args['team_header'] or 'Home \\ Away'
-- Number of legs
local legs = tonumber(Args['legs']) or 1
-- Edit links if requested
local template_name = Args['template_name'] or ''
local edit_links = template_name == '' and ''
or frame:expandTemplate{ title = 'navbar',
args = { mini=1, style='float:right', template_name} }
-- Load some other modules
local p_sub = require('Module:Sports table/sub')
-- Read in number of consecutive teams (ignore entries after skipping a spot)
while Args['team'..N_teams+1] ~= nil do
N_teams = N_teams+1
-- Sneakily add it twice to the team_list parameter, once for the actual
-- ranking, the second for position lookup in sub-tables
-- This is possible because Lua allows both numbers and strings as indices.
team_list[N_teams] = Args['team'..N_teams] -- i^th entry is team X
team_list[Args['team'..N_teams]] = N_teams -- team X entry is position i
end
-- Get team to show
local ii_show = team_list[Args['showteam']] -- nil if non-existant
-- Set the font size
local font_size=Args['font_size'] or '100%'
-- Create header
-- Open table
table.insert(t,'{|class="wikitable plainrowheaders" style="text-align:center;font-size:'..font_size..';"\n')
-- First column
t_return.count = 0 -- Dummy parameter, using subfunction call seems best at this point because both module are intertwined
t_return.tab_text = t -- Actual text
t_return = p_sub.colhead(t_return,'auto', edit_links .. ' Hjemme \\ Ude')
-- Other columns passed to subfunction
t_return = p.header(t_return,Args,p_sub,N_teams,team_list,legs)
t = t_return.tab_text
-- Random value used for uniqueness
math.randomseed( os.clock() * 10^8 )
local rand_val = math.random()
local note_string, note_id
local note_id_list = {}
-- Now create individual rows
for ii=1,N_teams do
-- Get team info
team_code_ii = team_list[ii]
team_name = Args['name_'..team_code_ii] or team_code_ii
local ii_style = 'text-align:right;'
.. (ii and ii == ii_show and 'font-weight:bold;' or '')
-- Team names
table.insert(t,'|- \n') -- New row
table.insert(t,'! scope="row" style="'
.. ii_style ..'"| '..team_name..'\n') -- Position number
-- Now include note to match results if needed
for jj=1,N_teams do
local team_code_jj = team_list[jj]
if ii == jj then
-- Nothing
else
for l=1,legs do
local m = (legs == 1) and 'match_' or 'match' .. l .. '_'
local match_note = Args[m ..team_code_ii..'_'..team_code_jj..'_note']
if match_note then
notes_exist = true
-- Only when it exist
-- First check for existence of reference for note
if not (Args['note_'..match_note] or Args[m ..match_note..'_note']) then
-- It's the entry
-- Add random end for unique ID if more tables are present on article (which might otherwise share an ID)
note_id = '"table_note_'..team_code_ii..'_'..team_code_jj..rand_val..'"'
note_id_list[team_code_ii..'_'..team_code_jj] = note_id
note_string = frame:expandTemplate{ title = 'efn',
args = { group='Table_notes', name=note_id, match_note} }
else
-- Check for existence elsewhere
note_local_num = team_list[match_note] or ii_end + 1
if note_id_list[match_note] or ((note_local_num >= ii_start) and (note_local_num <= ii_end)) then
-- It exists
note_id = '"table_note_'..match_note..rand_val..'"' -- Identifier
note_string = frame:extensionTag{ name = 'ref',
args = { group = 'lower-alpha', name = note_id} }
else
-- Now define the identifier for this
-- Add random end for unique ID
note_id = '"table_note_'..match_note..rand_val..'"'
note_id_list[match_note] = note_id
-- Call refn template
note_string = frame:expandTemplate{ title = 'efn',
args = { group='Table_notes', name=note_id, Args['note_'..match_note]} }
end
end
-- Now append this to the match result string
Args[m..team_code_ii..'_'..team_code_jj] = Args[m..team_code_ii..'_'..team_code_jj]..note_string
end
end
end
end
-- Then individual results
t = p.row(t,Args,N_teams,team_list,ii,ii_show,legs)
end
-- Close table
table.insert(t, '|}\n')
-- Get info for footer
local update = Args['update']
or 'unknown'
local start_date = Args['start_date']
or 'unknown'
local source = Args['source']
or frame:expandTemplate{ title = 'Kilde mangler',
args = { aarsag='No source parameter defined', dato=string.lower(os.date('%B %Y')) } }
-- Create footer text
-- Date updating
if string.lower(update)=='complete' then
-- Do nothing
elseif update=='' then
-- Empty parameter
table.insert(t_footer,'Opdateret indtil kampe spillet den ? ')
elseif string.lower(update)=='future' then
-- Future start date
table.insert(t_footer,'Første kampe vil blive spillet den '..start_date..'. ')
else
table.insert(t_footer,'Opdateret indtil kampe spillet den '..update..'. ')
end
table.insert(t_footer,'Kilde: '..source)
if (Args['matches_style'] or '') == 'FBR' then
table.insert(t_footer, Args['team_header']
and '<br />Colours: Blue = left column team win; Yellow = draw; Red = top row team win.'
or '<br />Colours: Blue = home team win; Yellow = draw; Red = away team win.')
elseif (Args['matches_style'] or '') == 'BSR' then
table.insert(t_footer, Args['team_header']
and '<br />Colours: Blue = left column team win; Red = top row team win.'
or '<br />Colours: Blue = home team win; Red = away team win.')
end
if (Args['a_note'] or '') ~= '' then
table.insert(t_footer, '<br />For upcoming matches, an "a" indicates there is an article about the match.')
end
if (Args['ot_note'] or '') ~= '' then
table.insert(t_footer, '<br />Matches with background in a lighter colour were decided after overtime.')
end
-- Add notes (if applicable)
if notes_exist then
table.insert(t_footer,'<br>Notes:')
-- As reflist size text
t_footer = '<div class="reflist">'..table.concat(t_footer)..'</div>'
t_footer = t_footer..frame:expandTemplate{ title = 'notelist', args = { group='Table_notes'} }
else
-- As reflist size text
t_footer = '<div class="reflist">'..table.concat(t_footer)..'</div>'
end
-- Add footer to main text table
table.insert(t,t_footer)
return table.concat(t)
end
-- Other functions
local function get_short_name(s, t, n)
-- return short name if defined
if s and s ~= '' then
return s
end
-- replace link text in name with team abbr if possible
if n and t and n:match('(%[%[[^%[%]]*%]%])') then
n = mw.ustring.gsub(n, '(%[%[[^%|%]]*%|)[^%|%]]*(%]%])', '%1' .. t .. '%2')
n = mw.ustring.gsub(n, '(%[%[[^%|%]]*)(%]%])', '%1|' .. t .. '%2')
return n
end
-- nothing worked, so just return the unlinked team abbr
return t or ''
end
local function get_score_background(s, c)
local s1, s2
-- Define the colouring
local wc, lc, tc
if c == 'level2' then
wc, lc, tc = '#CCF9FF', '#FCC', '#FFC' -- blue2, red2, yellow2
elseif c == 'level3' then
wc, lc, tc = '#DDFCFF', '#FDD', '#FFD' -- blue3, red3, yellow3
elseif c == 'level4' then
wc, lc, tc = '#EEFFFF', '#FEE', '#FFE' -- blue4, red4, yellow4
else
wc, lc, tc = '#BBF3FF', '#FBB', '#FFB' -- blue1, red1, yellow1
end
-- delink if necessary
if s:match('^%s*%[%[[^%[%]]*%|([^%[%]]*)%]%]') then
s = s:match('^%s*%[%[[^%[%]]*%|([^%[%]]*)%]%]')
end
-- get the scores
s1 = tonumber(mw.ustring.gsub( s or '',
'^%s*([%d][%d]*)%s*–%s*([%d][%d]*).*', '%1' ) or '') or ''
s2 = tonumber(mw.ustring.gsub( s or '',
'^%s*([%d][%d]*)%s*–%s*([%d][%d]*).*', '%2' ) or '') or ''
-- return colouring if possible
if s1 ~= '' and s2 ~= '' then
return (s1 > s2) and wc or ((s2 > s1) and lc or tc)
else
return 'transparent'
end
end
local function format_score(s)
s = mw.ustring.gsub(s or '', '^%s*([%d]+)%s*[–−—%-]%s*([%d]+)', '%1–%2')
s = mw.ustring.gsub(s, '^%s*([%d]+)%s*&[MmNn][Dd][Aa][Ss][Hh];%s*([%d]+)', '%1–%2')
s = mw.ustring.gsub(s, '^%s*(%[%[[^%[%]]*%|[%d]+)%s*%-%s*([%d]+)', '%1–%2')
s = mw.ustring.gsub(s, '^%s*(%[%[[^%[%]]*%|[%d]+)%s*&[MmNn][Dd][Aa][Ss][Hh];%s*([%d]+)', '%1–%2')
return s
end
function p.header(tt,Args,p_sub,N_teams,team_list,legs)
local ii, team_code_ii, short_name
legs = legs or 1
-- Set match column width
local col_width = Args['match_col_width'] or '28'
-- Get some default values in case it doesn't start at 1
local top_pos = tonumber(Args['highest_pos']) or 1
for l=1,legs do
for ii=top_pos,N_teams do
team_code_ii = team_list[ii]
short_name = get_short_name(Args['short_'..team_code_ii],
team_code_ii, Args['name_'..team_code_ii])
local bl = legs > 1 and ii == top_pos and ' style="border-left:2px solid #aaa;"' or ''
tt = p_sub.colhead(tt,col_width .. bl,short_name)
end
end
return tt
end
function p.row(tt,Args,N_teams,team_list,ii,ii_show,legs)
-- Note ii is the row number being shown
local jj, fw, bg, result, result_extra, team_code_ii, team_code_jj
legs = legs or 1
-- Set score cell style
local matches_style = Args['matches_style'] or ''
team_code_ii = team_list[ii]
-- Get some default values in case it doesn't start at 1
local top_pos = tonumber(Args['highest_pos']) or 1
for l=1,legs do
for jj=top_pos,N_teams do
team_code_jj = team_list[jj]
local m = (legs == 1) and 'match_' or 'match' .. l .. '_'
result = Args[m..team_code_ii..'_'..team_code_jj] or ''
result_extra = Args['result_'..team_code_ii..'_'..team_code_jj] or ''
local bl = legs > 1 and jj == top_pos and 'border-left:2px solid #aaa;' or ''
if ii == jj or result == 'null' then
-- Solid cell
fw = 'font-weight:' .. (ii==ii_show and 'bold' or 'normal') .. ';'
bg = 'background:transparent;'
-- Grey background color for solid cell
if Args['solid_cell'] == 'grey' then
table.insert(tt,'| style="'..fw..bl..'background:#bbb;" |\n')
else
table.insert(tt,'| style="'..fw..bl..bg..'" | —\n')
end
else
-- Content cell
-- Set bolding and background
fw = 'font-weight:' .. ((ii==ii_show or jj == ii_show) and 'bold' or 'normal') .. ';'
bg = 'background:transparent;'
-- Reformat dashes
if result ~= '' then
result = format_score(result)
end
-- Background coloring if enabled
if matches_style == 'FBR' and result ~= '' then
if result_extra == 'OT' then
bg = 'background:' .. get_score_background(result,'level2') .. ';'
elseif result_extra == 'PK' then
bg = 'background:' .. get_score_background(result,'level3') .. ';'
else
bg = 'background:' .. get_score_background(result,'') .. ';'
end
elseif matches_style == 'BSR' and result ~= '' then
if result_extra == 'OT' then
bg = 'background:' .. get_score_background(result,'level3') .. ';'
else
bg = 'background:' .. get_score_background(result,'') .. ';'
end
end
table.insert(tt,'| style="white-space:nowrap;'..fw..bl..bg..'" |'..result..'\n')
end
end
end
return tt
end
return p