Module:Biota infobox/core
Documentation for this module may be created at Module:Biota infobox/core/doc
require('Module:No globals') local p = {} local templateArgs = {} local info = {} local paramData = require( 'Module:Biota infobox/data' ) -- contains the taxon ranks in order local autotaxa = require("Module:Autotaxobox") local parameters = require( 'Module:Biota infobox/param' ) --[[ ##################### CORE FUNCTIONS ################################### this core function emulates Template:Taxobox/core it is followed by functions handling the different type of entry ]] p.main = function(frame) -- this function emulates Template:Taxobox/core when called from taxobox feeder templates -- i.e. Taxobox, Automatic taxobox, Speciesbox, etc parameters.getArgs(frame) templateArgs['image_upright'] = templateArgs['upright'] or 1 templateArgs['image2_upright'] = templateArgs['upright2'] or 1 info.headerColor = templateArgs['colour'] return p._core --TODO check it works end -- this is the core function, called either from main() or auto() p.core = function(frame, args, localinfo) templateArgs = args info = localinfo return p._core(frame) end p._core = function(frame) -- TODO use mw.title.getCurrentTitle().basePageTitle info.name = templateArgs['name'] or tostring( mw.title.getCurrentTitle() ) --.rootPageTitle ) info.headerColor = p.getTaxoboxColor(frame) -- so only transverse taxobox heirarchy once --[[ create table (two versions) 1. use mwhtml library to build table in taxoboxTable 2. use wikitest to build table in wikitextTable ]] local taxoboxTable = mw.html.create('table'):addClass('infobox'):addClass('biota') :addClass('biota-infobox') local wikitextTable = '\n{| class="infobox biota biota-infobox" ' info.subheader = '' if templateArgs['subheader'] and templateArgs['subheader'] ~= '' then info.subheader='<div style="font-weight:normal;font-size:smaller;">'..templateArgs['subheader']..'</div>' end --TODO do we need additional handling to check {{geological range}} templete -- or handle oldest_fossil and youngest_fossil (these don't seem to be used now) -- Note: taxobox/core uses temporal_range local temporalRange = '' if templateArgs['temporal_range'] then temporalRange = '<div><small>Temporal range: ' .. templateArgs['temporal_range'] .. '</small></div>' -- use <div> rather than <br/> end local rowHeader = taxoboxTable:tag('tr'):tag('th'):attr('colspan', '2'):addClass('section-header') :cssText('background:' .. info.headerColor .. ';') :wikitext(info.name .. info.subheader .. temporalRange) wikitextTable = wikitextTable .. '\n|-\n! colspan="2" class="section-header" style="background:' .. info.headerColor .. ';" ' .. '|' .. info.name .. info.subheader .. temporalRange -- add images wikitextTable = wikitextTable .. p.addImageSection(frame, taxoboxTable, 'image') .. p.addImageSection(frame, taxoboxTable, 'image2') --add conservation status wikitextTable = wikitextTable .. p.addStatusSection(frame, taxoboxTable, 'status') .. p.addStatusSection(frame, taxoboxTable, 'status2') -- add taxonomy table (uses entered parameters or automatic taxonomy system) wikitextTable = wikitextTable .. p.addTaxonomySection(frame, taxoboxTable) -- add sections with binomial, trinomial, type species/genus (with authorities) wikitextTable = wikitextTable .. p.addTaxonSection(frame, taxoboxTable, 'binomial', 'Bionomial name') .. p.addTaxonSection(frame, taxoboxTable, 'trinomial', 'Trionomial name') .. p.addTaxonSection(frame, taxoboxTable, 'type_genus', 'Type genus') --TODO type_ichnogenus, type_oogenus .. p.addTaxonSection(frame, taxoboxTable, 'type_species', 'Type species') --TODO type_ichnospecies, type_oospecies .. p.addTaxonSection(frame, taxoboxTable, 'type_strain', 'Type strain') -- add sections showing subdivisions (i.e. child taxa) wikitextTable = wikitextTable .. p.addListSection(frame, taxoboxTable, 'subdivision', templateArgs['subdivision_ranks'] or 'Subdivisions') .. p.addListSection(frame, taxoboxTable, 'possible_subdivision', templateArgs['possible_subdivision_ranks'] or 'Possible subdivisions') -- diversity section (TODO consider how best to handle) wikitextTable = wikitextTable .. p.addTaxonSection(frame, taxoboxTable, 'diversity', 'Diversity') -- show included groups (accepts 'included' or 'includes') [used for paraphyletic taxa] wikitextTable = wikitextTable .. p.addListSection(frame, taxoboxTable, 'includes', 'Groups included') --p.addListSection(frame, taxoboxTable, 'included', 'Groups included') -- use alias --add range map (should this be below binomial/trinomial?) wikitextTable = wikitextTable .. p.addImageSection(frame, taxoboxTable, 'range_map') -- show excluded groups (accepts 'excluded' or 'excludes') [used for paraphyletic taxa] local excludedHeaderText = '[[Cladistics|Cladistically]] included but traditionally excluded taxa' wikitextTable = wikitextTable .. p.addListSection(frame, taxoboxTable, 'excludes', excludedHeaderText) -- add addition binomials, trinomial and range maps wikitextTable = wikitextTable .. p.addTaxonSection(frame, taxoboxTable, 'binomial2', 'Bionomial name (2)') --p.addTaxonSection(frame, taxoboxTable, 'trinomial2', 'Trionomial name (2)') .. p.addImageSection(frame, taxoboxTable, 'range_map2') .. p.addTaxonSection(frame, taxoboxTable, 'binomial3', 'Bionomial name (3)') --p.addTaxonSection(frame, taxoboxTable, 'trinomial3', 'Trionomial name (3)') .. p.addImageSection(frame, taxoboxTable, 'range_map3') .. p.addTaxonSection(frame, taxoboxTable, 'binomial4', 'Bionomial name (4)') --p.addTaxonSection(frame, taxoboxTable, 'trinomial4', 'Trionomial name (4)') .. p.addImageSection(frame, taxoboxTable, 'range_map4') -- add synonyms section wikitextTable = wikitextTable .. p.addListSection(frame, taxoboxTable, 'synonyms', '[[Synonym (taxonomy)|Synonyms]]') -- add debug/tracking info section if info.debug then wikitextTable = wikitextTable ..p.addListSection(frame, taxoboxTable, 'debug', 'Debug/tracking info') end ------------------add templateSyles and return taxobox table--------------------------- local src = "Template:Biota infobox/styles.css" -- TemplateStyles file wikitextTable = wikitextTable .. '\n|}' local output = wikitextTable -- output the wikitext table --local output = tostring(taxoboxTable) -- output the mw.html table return p.templateStyle( frame, src ) .. output .. info.parameterCategory -- .. (info.parameterCategory or "") end -- End the main function. --[[ ==================================================================================== function to add conservation sections uses template {{taxobox/species|{{{status_system|}}}|{{{status|}}}|{{{status_ref|}}}|extinct={{{extinct|}}} }} }} --]] function p.addStatusSection(frame, taxoboxTable, status) -- must use table container to handle template output -- don't use header or content cells; the 'taxobox/species' template handles it -- just need to add background colour on the row local wikiText = "" if templateArgs[status] and templateArgs[status] ~= "" then local status = frame:expandTemplate{ title = 'taxobox/species', args = {templateArgs[status..'_system'] or '', templateArgs[status] or '', templateArgs[status..'_ref'] or '', extinct=templateArgs['extinct'] or '' } } local row = taxoboxTable:tag('tr') --:cssText('background:' .. p.getTaxoboxColor(frame) .. ';') local cell = row:tag('td'):attr('colspan', '2') :wikitext('\n{|\n|- style="background:' .. info.headerColor .. ';"') :wikitext('\n'..tostring(status)) :wikitext('\n|}') wikiText = '\n|- colspan="2" style="background:' .. info.headerColor .. ';" ' .. '\n' ..tostring(status) end return wikiText end --[[ ============================================================================== function to add sections for taxonomic information with authorities ('_authority' suffix) e.g. binomial, trinomial, type_species, type_genus; diversity also handled here --]] function p.addTaxonSection(frame, taxoboxTable, target, headerText) local wikiText = "" -- return if we don't have value if not templateArgs[target] or templateArgs[target] == '' then return "" end local bold = "" -- variable for bolding binomial and trinomial (type genus/species etc are not bolded) local showHeader = true local listHeader = (templateArgs[target..'_text'] or headerText) -- custom processing section --if target == 'binomial' or target == 'binomial2' or target == 'binomial3' or target == 'binomial4' then if target == 'binomial' then headerText = '[[Binomial nomenclature|' .. listHeader .. ']]' bold ="'''" --elseif target == 'trinomial' or target == 'trinomial2' or target == 'trinomial3' or target == 'trinomial4' then elseif target == 'trinomial' then local trinomenLink = "Trinomen" -- for zoological or default if info.auto == "infraspeciesbox" then trinomenLink = "Infraspecific name (botany)" end -- regnum contains plant/fung/Archaeplastida" headerText = '[['.. trinomenLink .. '|' .. headerText .. ']]' bold ="'''" elseif target == 'binomial2' or target == 'binomial3' or target == 'binomial4' or target == 'trinomial2' or target == 'trinomial3' or target == 'trinomial4' then showHeader = false bold ="'''" elseif target == 'diversity' then headerText = '[[Biodiversity|' .. headerText .. ']]' else --TODO is any handling needed for other option headerText = '[[' .. headerText .. ']]' end if templateArgs[target..'_ref'] then headerText = headerText .. templateArgs[target..'_ref'] .. '\n' end local contentString = '' -- content for the content cell if target == 'diversity' and templateArgs['diversity'] ~= "" then if templateArgs[target..'_link'] and templateArgs[target..'_link'] ~= "" then contentString = '\n[[' .. templateArgs[target..'_link'] .. '|' .. templateArgs[target] .. ']]\n' else contentString = '\n' .. templateArgs[target] .. '\n' end else -- taxon name and authority (binomial, type species, etc) local authorityString = '' if templateArgs[target..'_authority'] then authorityString = '<br/><small>' .. templateArgs[target..'_authority'] .. '</small>' -- \n' end contentString = bold .. templateArgs[target] .. bold .. authorityString .. '\n' --contentString = '\n' .. bold .. templateArgs[target] .. bold .. authorityString .. '\n' -- extra <p> inserted end -- add table rows if templateArgs[target] and templateArgs[target] ~= '' then if showHeader then local rowHeader = taxoboxTable:tag('tr') rowHeader :tag('th') :attr('colspan', '2') :addClass('section-header') :cssText('background:' .. info.headerColor .. ';') :wikitext( headerText ) wikiText = wikiText .. '\n|- \n! colspan="2" class="section-header" style="background:' .. info.headerColor .. ';" ' .. '|' .. headerText end local rowList = taxoboxTable:tag('tr') rowList :tag('td') :attr('colspan', '2') --:addClass('section-content') :addClass('taxon-section') --:cssText('text-align:center;') --font-weight:bold;') :wikitext( contentString ) wikiText = wikiText .. '\n|- \n| colspan="2" class="taxon-section" |' .. contentString end return wikiText end --[[ ==================================================================================== function to produce sections for included taxa (subdivisions), synonyms, etc - each consists of two rows containing a header and the content - for paraphyletic groups it has include(d|s) and exclude(d|s) groups - for general taxobox it has subdivision and possible subdivision (disabled here) - any can be modified for other purposes (e.g. sisters) by changing the header taxt with a -text parameter ]] function p.addListSection(frame, taxoboxTable, target, headerText) if not templateArgs[target] or templateArgs[target] == "" then return "" end -- redundant for now local wikiText = "" local refString = '' if templateArgs[target..'_ref'] then --add '_ref' option for 'synonym_ref' (the rest get it as a bonus) TODO check example refString = templateArgs[target..'_ref'] --.. '\n' end local listHeader = (templateArgs[target..'_text'] or headerText) .. refString -- add table rows if templateArgs[target] and templateArgs[target] ~= ''then local rowHeader = taxoboxTable:tag('tr') rowHeader :tag('th') :attr('colspan', '2') :addClass('section-header') :cssText('background:' .. info.headerColor .. ';') :wikitext(listHeader) wikiText = wikiText .. '\n|- \n! colspan="2" class="section-header" style="background:' .. info.headerColor .. ';" ' .. '|' .. listHeader local rowList = taxoboxTable:tag('tr') rowList :tag('td') :attr('colspan', '2') :addClass('section-content') :wikitext('\n' .. templateArgs[target] .. '\n' ) wikiText = wikiText .. '\n|- \n| colspan="2" class="section-content" ' .. '|' .. '\n' .. templateArgs[target] .. '\n' end return wikiText end ----------------------------------------------------------------------------------------------- --[[ ============================================================================ function to add image sections - used for illustrative images at top and for range maps --]] function p.addImageSection(frame, taxoboxTable, target) local wikiText = "" if templateArgs[target] and templateArgs[target] ~= '' then local imageWidth = '' local imageCaptionString = '' if templateArgs[target..'_caption'] then --imageCaptionString = '<br /><small><div style="text-align:center">' .. templateArgs[target .. '_caption'] .. '</div></small>' --imageCaptionString = '<br /><div>' .. templateArgs[target .. '_caption'] .. '</div>' imageCaptionString = templateArgs[target .. '_caption'] end local imageAltString = '' if templateArgs[target..'_alt'] then imageAltString = templateArgs[target..'_alt'] elseif templateArgs[target..'_caption'] then imageAltString = templateArgs[target..'_caption'] -- use caption for alt text if none provided end local upright = templateArgs['image_upright'] or 1 local InfoboxImage = require( 'Module:InfoboxImage' ) --, parent.args[target] ) local params = { args = { image = templateArgs[target], size = templateArgs[target..'_width'], sizedefault = 'frameless', alt = imageAltString, upright = templateArgs[target..'_upright'] or upright } } local image = InfoboxImage.InfoboxImage( params ) --local rowImage = taxoboxTable:tag('tr') local rowImage = mw.html.create('tr') rowImage:tag('td') :attr('colspan', '2') :addClass("image-section") :wikitext(image) --:wikitext(imageCaptionString) taxoboxTable:node(rowImage) wikiText= wikiText .. '\n|- \n|colspan="2" class="image-section" |' .. image if imageCaptionString ~= "" then -- only insert row if caption string local rowImageCaption = mw.html.create('tr') rowImageCaption:tag('td') :attr('colspan', '2') :addClass("image-section") --:wikitext(image) :wikitext(imageCaptionString) taxoboxTable:node(rowImageCaption) wikiText = wikiText .. '\n|- \n|colspan="2" class="image-section" |' .. imageCaptionString end end -- TODO handle upright return wikiText end --[[ ============================ TAXONOMY SECTION ======================================= adds a table showing the taxonomy - uses either manual parameters or the automatic taxonomy system - currently adds a table inside a cell (like paraphyletic group) rather than just adding rows (core taxobox system) --]] function p.addTaxonomySection(frame, taxoboxTable) local wikiText = "" local taxonomyHeader = "[[Taxonomy_(biology)|Scientific classification]]" if templateArgs['virus_group'] then taxonomyHeader = "[[Virus classification]]" elseif templateArgs['ichnos'] then taxonomyHeader = "[[Trace fossil classification]]" elseif templateArgs['veterovata'] then taxonomyHeader = "[[Veterovata|Eggshell classification]]" else -- TODO add other options (DONE but not verified ichnos or veterovata) -- ! colspan=2 style="min-width:15em; text-align: center{{#if:{{{colour|}}}|{{;}} background-color{{COLON}} {{{colour}}} }}" | -- {{#if:{{{virus_group|{{{virus|}}}}}}|[[Virus classification]] -- |{{#if:{{{ichnos|}}}|[[Trace fossil classification]] -- |{{#if:{{{veterovata|}}}|[[Veterovata|Eggshell classification]] -- |[[Taxonomy (biology)|Scientific classification]]}} }} }} -- {{#if:{{{edit link|}}}|{{edit taxonomy|{{{parent|}}} | {{{edit link}}} }} -- {{#if: {{{classification_status|}}} | <br>({{{classification_status}}}) | }} }} -- handle |classification_status=disputed (add ref) end -- add symbol and link to taxonomy editor local editLink = '' if info.auto then local tooltip = templateArgs['edit link'] or "Edit this classification" editLink = '<span class="plainlinks" style="font-size:smaller; float:right; padding-right:0.4em; margin-left:-3em;">' .. '[[File:Red Pencil Icon.png|link=Template:Taxonomy/' .. templateArgs['parent'] .. '|' .. tooltip .. ']]</span>' end local status = "" if templateArgs['classification_status'] then status = '<div style="font-weight:normal;" >(' .. templateArgs['classification_status'] .. ')' if templateArgs['classification_ref'] then status = status .. templateArgs['classification_ref'] end status = status .. '</div>' end local rowTaxonomyHeader = taxoboxTable:tag('tr') rowTaxonomyHeader:tag('th') :attr('colspan', '2') :addClass('section-header') :cssText('background:' .. info.headerColor .. ';') :wikitext(taxonomyHeader) :wikitext(editLink) :wikitext(status) wikiText = wikiText .. '\n|- \n! colspan="2" class="section-header" style="background:' .. info.headerColor .. ';" ' .. '|' .. taxonomyHeader .. editLink .. status -- get taxonomy list, either using automatic taxobox system or manual system if info.auto then --[[ get automatic taxonomy hierarchy (three different variants) 1) direct call to taxoboxList() - preferred if issues with setting frame arguments can be resolved 2) experimental version of taxoboxList() 3) [ET] using Template:Ttaxobox/taxonomy ]] wikiText = wikiText ..'\n|-|\n|' .. p.addAutomaticTaxonomy(frame, taxoboxTable) -- use #invoke of module -- use manual taxobox for genus, subgenus,species, subspecies, variety local taxonRanks = { 'subgenus', 'species', 'hybrid', 'subspecies', 'variety' } wikiText = wikiText .. p.addManualTaxonomy(frame, taxoboxTable, taxonRanks) else wikiText = wikiText .. p.addManualTaxonomy(frame, taxoboxTable, paramData.taxonRanks) -- just add rows end return wikiText end -------------------------------------------------AUTOMATIC TAXONOMY (using invoke of module function) ----------- function p.addAutomaticTaxonomy(frame, taxoboxTable) -- use invoke of module function --emulate template: {{taxobox/taxonomy}} --which uses {{#invoke:Autotaxobox|taxoboxList local bold_first = 'bold' if templateArgs['species'] or templateArgs['hybrid'] then bold_first = 'link' end if templateArgs['link_parent'] then bold_first = 'link' end local args = { templateArgs['parent'], -- or tostring( mw.title.getCurrentTitle() ), display_taxa = templateArgs['display_taxa'] or 1, offset = templateArgs['offset'] or 0, authority = templateArgs['authority'], parent_authority = templateArgs['parent_authority'], gparent_authority = templateArgs['grandparent_authority'], ggparent_authority = templateArgs['greatgrandparent_authority'], gggparent_authority = templateArgs['greatgreatgrandparent_authority'], virus=templateArgs['virus'], bold_first = bold_first } frame.args = args -- templateArgs['debug'] = mw.dumpObject(frame) local autoTaxonomy = autotaxa.taxoboxList(frame) if (1==1) then return autoTaxonomy end local row = taxoboxTable:tag('tr') -- incompatible with the templates called :wikitext('\n|rank ||taxon name ') :wikitext('\n'.. autoTaxonomy ) -- autoTaxonomy ends with a new row (|-)at end :wikitext('\n|x ||y ') -- so add blank cells to complete extra row -- this and affects spacing in taxonomy rows --:wikitext('\n') -- spacing fine, newline for table wikitext --[[ note: the output of {{taxobox/showtaxon}} [used by invoke:Autotaxobox|taxoboxList] ends with a newline token this and affects spacing in taxonomy rows leaving the empty row results in spurious paragraphs above the table ]] return end ----------------------------------------MANUAL TAXONOMY-------------------------------- function p.addManualTaxonomy(frame,taxoboxTable, taxonRanks) --local parent = mw.getCurrentFrame():getParent() --local taxonRanks = data.taxonRanks -- following {{Paraphyletic group, a table is add to the cell in the classification row --local taxonomyTable = mw.html.create('table'):addClass('taxonomy') -- an alternative is to dispense with the extra table and just add the rows (like taxobox/core), -- which would need colspan=2 on other rows (DONE) local taxonomyTable = taxoboxTable local wikiText = "" for k,v in pairs(taxonRanks) do if templateArgs[v] then local taxonName = templateArgs[v] local taxonRank = frame:expandTemplate{ title = "anglicise rank", args = {taxonRanks[k]} } if taxonRanks[k] == "virus_group" then taxonName = frame:expandTemplate{ title = "Virus group", args = {templateArgs[v]} } -- taxonRank = "Group" -- handled by anglicise rank template end local authorityString = '' if templateArgs[taxonRanks[k]..'_authority'] then authorityString = '<br /><small>'..templateArgs[taxonRanks[k]..'_authority']..'</small>' end local taxonString = '<span class="'.. taxonRanks[k] ..'">'..taxonName..'</span>'..authorityString local row = taxonomyTable:tag('tr') row:tag('td'):wikitext(taxonRank..':') row:tag('td'):wikitext(taxonString) --:wikitext('<br /><small>'..parent.args[taxonRanks[k]..'_authority']..'</small>') wikiText = wikiText .. '\n|- \n|' .. taxonRank..': \n|' .. taxonString end end -- end for loop --return tostring(taxonomyTable) return wikiText end --[[ ########################### UTILITY FUNCTIONS ############################################### -----------------------------------------TAXOBOX COLOUR-------------------------------------- -- gets colour for headers using manual or automatic taxobox schemes ]] function p.getTaxoboxColor(frame) local colorAs = templateArgs['color_as'] or nil if info.auto and not templateArgs['virus_group'] then --[[(1) if color_as|colour_as|color as|colour as set, use template {{Taxobox colour|color_as}} (2) else use the auto taxonnomy tree to find colour: {{#invoke:Autotaxobox|taxoboxColour| }} {{#invoke:Autotaxobox|taxoboxColour|{{{parent|{{{genus|{{first word|{{{taxon|{{PAGENAME}} }} --]] --[[if (templateArgs['color_as'] and templateArgs['color_as'] ~= "") or (templateArgs['colour_as'] and templateArgs['colour_as'] ~= "") or (templateArgs['color as'] and templateArgs['color as'] ~= "") or (templateArgs['colour as'] and templateArgs['colour as'] ~= "") then local colorAs = "" if templateArgs['color_as'] then colorAs = templateArgs['color_as'] end if templateArgs['colour_as'] then colorAs = templateArgs['colour_as'] end if templateArgs['color as'] then colorAs = templateArgs['color as'] end if templateArgs['colour as'] then colorAs = templateArgs['colour as'] end]] if colorAs then -- templateArgs['color_as'] and templateArgs['color_as'] ~= "" then return frame:expandTemplate{ title = 'Taxobox colour', args = {colorAs} } else -- us #invoke:Autotaxobox|taxoboxColour|{{{parent}}} [parent should be set] frame.args[1] = templateArgs['parent'] return autotaxa.taxoboxColour(frame) --return "palegreen" end else -- use manual taxobox colours --{{Taxobox colour|{{{regnum|{{{virus_group|{{{unranked_phylum|{{{phylum|''[[Incertae sedis]]''}}}}}}}}}}}}}} if not colorAs then --templateArgs['color_as'] then local group ='' if templateArgs['regnum'] then group = templateArgs['regnum'] elseif templateArgs['virus_group'] then group = templateArgs['virus_group'] elseif templateArgs['unranked_phylum'] then group = templateArgs['unranked_phylum'] elseif templateArgs['phylum'] then group = templateArgs['phylum'] else group = "''[[Incertae sedis]]''" -- TODO check if this is what was desired end colorAs = group end return frame:expandTemplate{ title = 'Taxobox colour', args = {colorAs} } end end ------------------------------------------------------------------- function p.templateStyle( frame, src ) return frame:extensionTag( 'templatestyles', '', { src = src } ); end function p.test(frame) return info.auto end return p