The body of a table can be made by using the main() function:
{{#invoke:COVID-19 data|main|columns=columns|sort=column to sort by}}
This only generates table contents (the body). Headers and titles can be customised independent of the module, to allow for styling.
Please use the following reference (preferably in the table title), to avoid duplicate references and have automatically updating access date and authors:
localp={}localdata_title=mw.title.new('Template:COVID-19 data/data')localdata_content=data_title:getContent()localdata=mw.text.jsonDecode(data_content)localfunctionformat_num(number)ifnotnumberthenreturn''endlocal_,_,minus,int,_=tostring(number):find('([-]?)(%d+)([.]?%d*)')int=int:reverse():gsub("(%d%d%d)","%1,")int=int:reverse():gsub("^,","")int=minus..intreturnintendfunctionp.main()localout=''localdata_s={}localhas_notelist=falselocalcount_row=0localcount_col=0-- Build new tablelocallocations={}ifmw.getCurrentFrame().args['locations']thenforlocationinstring.gmatch(mw.getCurrentFrame().args['locations'],'([^,]+)')dolocations[location]=trueendelselocations=nilendforkey,valueinpairs(data)dolocalindexifmw.getCurrentFrame().args['sort']thenifvalue[mw.getCurrentFrame().args['sort']]thenindex=value[mw.getCurrentFrame().args['sort']]elseindex=0endelseifvalue.casesthenindex=value.caseselseifvalue.deathsthenindex=value.deathselseifvalue.vaccine_dosesthenindex=value.vaccine_doseselseifvalue.total_vaccinatedthenindex=value.total_vaccinatedelseifvalue.fully_vaccinatedthenindex=value.fully_vaccinatedelseindex=0endendif(notlocations)orlocations[key]thendata_s[#data_s+1]=valuedata_s[#data_s]['_index']=indexdata_s[#data_s]['_code']=keyendend-- Sort the new tabletable.sort(data_s,function(x,y)ifx._code=='XW'thenreturntrueelseify._code=='XW'thenreturnfalseelsereturn(x._index>y._index)endend)-- Get columnslocalcolumns={cases=false,deaths=false,total_vaccinated=false,vaccine_doses=false,fully_vaccinated=false,percent_vaccinated=false,percent_fully_vaccinated=false,deaths_per_million=false,population=false}localcolumns_index={}ifmw.getCurrentFrame().args['columns']thenforcolumninstring.gmatch(mw.getCurrentFrame().args['columns'],'([^,]+)')docolumns[column]=truecolumns_index[#columns_index+1]=columnendelsecolumns={cases=true,deaths=true,total_vaccinated=true,vaccine_doses=true,fully_vaccinated=true,percent_vaccinated=false,percent_fully_vaccinated=false,deaths_per_million=false,population=false}columns_index={'cases','deaths','total_vaccinated','vaccine_doses','fully_vaccinated','percent_vaccinated','percent_fully_vaccinated','deaths_per_million','population'}end-- Check if should show note_vaccinationlocalshow_note_vaccination=falseifcolumns['total_vaccinated']orcolumns['vaccine_doses']orcolumns['fully_vaccinated']orcolumns['percent_vaccinated']orcolumns['percent_fully_vaccinated']thenshow_note_vaccination=trueend-- Generate wikitext contentfor_,rowinipairs(data_s)do-- Test for empty rowslocalhas_data=falsefor_,columninpairs(columns_index)doifcolumns[column]androw[column]thenhas_data=trueendendifhas_datathen-- Only add row if it has datacount_row=count_row+1out=out..'\n|-'ifrow._code=='XW'thenout=out..'class="sorttop static-row-header"'end-- Add the flagifnotmw.getCurrentFrame().args['noflag']thenifcount_row==1thencount_col=count_col+1endout=out..'\n| style="text-align: center;" data-sort-value="'..row.name..'" | 'ifrow._code=='XW'thenout=out..'[[File:OOjs UI icon globe.svg|16px|alt=|link=]]'elseflag_params={row.name}-- So that it's not too largeifrow.name=='New Caledonia'thenflag_params[2]='merged'endout=out..mw.getCurrentFrame():expandTemplate{title='Flagicon',args=flag_params}endend-- Add country nameifcount_row==1thencount_col=count_col+1endifmw.getCurrentFrame().args['noflag']thenout=out..'\n! scope="row" style="background-color: inherit;" data-sort-value="'..row.name..'" | 'elseout=out..'\n! scope="row" style="background-color: inherit;" |'endifrow._code=='XW'thenout=out..'[[COVID-19 pandemic|'..row.name..']]'elseifrow._code=='GE'thenout=out..'[[COVID-19 pandemic in Georgia (country)'..'|'..row.name..']]'elseifrow._code=='IM'thenout=out..'[[COVID-19 pandemic in the '..row.name..'|'..row.name..']]'elseout=out..'[[COVID-19 pandemic in '..row.name..'|'..row.name..']]'end-- Add notesifrow.notethenhas_notelist=trueout=out..mw.getCurrentFrame():expandTemplate{title='Efn',args={row.note}}endifrow.note_vaccinationandshow_note_vaccinationthenhas_notelist=trueout=out..mw.getCurrentFrame():expandTemplate{title='Efn',args={'Vaccination note: '..row.note_vaccination}}end-- Fill out columnsfor_,columninipairs(columns_index)doifcolumns[column]thenifcount_row==1thencount_col=count_col+1endifrow[column]thenout=out..'\n| data-sort-value='..tostring(row[column])..'|'ifcolumn:find('^percent')thenout=out..string.format('%.2f',row[column])..'%'elseout=out..format_num(row[column])endelseout=out..'\n| data-sort-value=0 | —'endendendendendifhas_notelistthenout=out..'\n|- class="sortbottom static-row-header" style="text-align: left;"'..'\n| colspan="'..count_col..'" style="width: 0;" |'..mw.getCurrentFrame():expandTemplate{title='Notelist'}endreturnoutendfunctionp.vac()localout=''localdata_s={}localhas_country_num_doses=falselocalhas_country_num_fully=falselocalcount_row=0localcount_col=0-- Build new tableforkey,valueinpairs(data)doifvalue.total_vaccinatedthendata_s[#data_s+1]=valuedata_s[#data_s]['index']=value.total_vaccinatedelseifvalue.vaccine_dosesthendata_s[#data_s+1]=valuedata_s[#data_s]['index']=value.vaccine_doseselseifvalue.fully_vaccinatedthendata_s[#data_s+1]=valuedata_s[#data_s]['index']=value.fully_vaccinatedendend-- Sort the new tabletable.sort(data_s,function(x,y)return(x.index>y.index)end)-- Generate wikitext contentfor_,rowinpairs(data_s)docount_row=count_row+1out=out..'\n|-'-- Add the flagifcount_row==1thencount_col=count_col+2endifrow.name=='World'thenout=out..'class="sorttop static-row-header"'..'\n| style="text-align: center;" data-sort-value="'..row.name..'" | '..'[[File:OOjs UI icon globe.svg|16px|alt=|link=]]'..'\n! scope="row" style="background-color: inherit;" data-sort-value="'..row.name..'" | '..'[[Deployment of COVID-19 vaccines|World]]'elseflag_params={row.name}-- So that it's not too largeifrow.name=='New Caledonia'thenflag_params[2]='merged'endout=out..'\n| style="text-align: center;" data-sort-value="'..row.name..'" | '..mw.getCurrentFrame():expandTemplate{title='Flagicon',args=flag_params}..'\n! scope="row" style="background-color: inherit;" data-sort-value="'..row.name..'" | '..'[[COVID-19 vaccination in '..row.name..'|'..row.name..']]'end-- Add noteifrow.note_vaccinationthenout=out..mw.getCurrentFrame():expandTemplate{title='Efn',args={row.note_vaccination}}end-- Add the numberifcount_row==1thencount_col=count_col+1endifrow.total_vaccinatedthenout=out..'\n| data-sort-value='..tostring(row.total_vaccinated)..'|'..format_num(row.total_vaccinated)elseifrow.vaccine_dosesthenhas_country_num_doses=trueout=out..'\n| data-sort-value='..tostring(row.vaccine_doses)..'|'..mw.getCurrentFrame():expandTemplate{title='Font color',args={'darkred',format_num(row.vaccine_doses)}}..mw.getCurrentFrame():expandTemplate{title='Efn',args={name='country_num_doses'}}elseifrow.fully_vaccinatedthenhas_country_num_fully=trueout=out..'\n| data-sort-value='..tostring(row.fully_vaccinated)..'|'..mw.getCurrentFrame():expandTemplate{title='Font color',args={'darkorange',format_num(row.fully_vaccinated)}}..mw.getCurrentFrame():expandTemplate{title='Efn',args={name='country_num_fully'}}end-- Add the percentageifcount_row==1thencount_col=count_col+1endifrow.percent_vaccinatedthenout=out..'\n| data-sort-value='..tostring(row.percent_vaccinated)..'|'..string.format("%.1f",row.percent_vaccinated)..'%'elseout=out..'\n| data-sort-value=0 | —'endendifhas_country_num_dosesorhas_country_num_fullythennotelist_refs=''ifhas_country_num_dosesthennotelist_refs=notelist_refs..mw.getCurrentFrame():expandTemplate{title='Efn',args={name='country_num_doses','This country\'s data are the '..mw.getCurrentFrame():expandTemplate{title='Font color',args={'darkred','number of vaccine doses administered'}}..', not the first dose only.'}}endifhas_country_num_fullythennotelist_refs=notelist_refs..mw.getCurrentFrame():expandTemplate{title='Efn',args={name='country_num_fully','This country\'s data are the '..mw.getCurrentFrame():expandTemplate{title='Font color',args={'darkorange','number of people fully vaccinated'}}..', not the number of people '..'who have received at least one dose.'}}endout=out..'\n|- class="sortbottom static-row-header" style="text-align: left;"'..'\n| colspan="'..count_col..'" style="width: 0;" |'..mw.getCurrentFrame():expandTemplate{title='Notelist',args={refs=notelist_refs}}endreturnoutendfunctionp.text()locallocation=mw.getCurrentFrame().args['location']localcolumn=mw.getCurrentFrame().args['column']returndata[location][column]endreturnp