Drupal studio · Diego Suarez, Madagascar
Est. 2025 · 12°16′ S

Species External Entity

A Drupal module that turns a species name or Catalogue of Life ID into a live entity: taxonomy, photographs, conservation status and ecological data drawn from public biodiversity APIs and mirrored locally for speed.

What it is

Species External Entity, machine name species_ext, turns a species name or a Catalogue of Life taxon ID into a full Drupal entity. Its taxonomy, description, photographs, conservation status and ecological relationships are gathered live from public biodiversity APIs and then mirrored locally so pages stay fast.

It ships as two modules: species_ext, the data engine, and the optional species_ext_map, a presentation layer that turns the resolved fields into maps, charts and a photo gallery. The data engine runs in production on Biodiversa, Museo Avellonia and the Quercus Project. On the Quercus Project, its species data also feeds MADDev's Ecosystems viewer.

At a glance

Modules
species_ext, the data engine: source plugins, resolvers, the local mirror and the species_x entity's field types; species_ext_map, an optional presentation layer for maps, charts and a gallery
Drupal core
10 or 11
Requires
entities_ext, dynamic_mirror_base, key and Drupal core's Link module; species_ext_map additionally needs the Leaflet contrib module
Entity type
species_x, keyed by the Catalogue of Life taxon ID
Rendering
Standard, BigPipe or progressive loading, so critical fields appear at once and enrichment fields stream in without blocking the page
Status
Live in production on Biodiversa, Museo Avellonia and the Quercus Project

What visitors and curators see

On sites that install the optional species_ext_map submodule, a species page adds a year by year GBIF occurrence density map drawn with Leaflet, a phenology histogram, a population trend chart, a photo gallery, and a lookup and search widget; it presents only what species_ext has already resolved and makes no data calls of its own. It runs on Museo Avellonia and the Quercus Project. On the Quercus Project, species pages also carry SEO markup and a pretty /species/{name} URL rather than the entity's internal path.

A curator can mark a species featured and add their own photographs through a small local entity that sits alongside the resolved data. Those additions are never overwritten by the monthly refresh from upstream.

What it adds to a Drupal site

Entity type

species_x: an external entity keyed by the Catalogue of Life taxon ID, with fields, view modes and Manage display like any other Drupal entity, even though nobody types its content in by hand.

Source plugins

One @SpeciesSource plugin per upstream, walked by weight until one resolves: a local Catalogue of Life checklist with no network call, the Catalogue of Life API, Wikipedia, GBIF, iNaturalist, the IUCN Red List, EOL and GloBI.

Routes

/admin/config/services/species-ext: enable or disable each source, set the IUCN API key and choose the rendering mode. /species-ext/lookup: a POST endpoint for autocomplete and taxon lookup. A disambiguation route handles a name that matches more than one taxon.

Drush commands

species-ext:warm, to warm one or more species immediately; species-ext:warm-queue, to drain the warming queue immediately.

Field locking

A SpeciesDmbAdapter connects species_x fields to dynamic_mirror_base, so an editor can lock a resolved field or override it locally, through the same workflow as MADDev's other external entity modules.

Data sources and licences

  • Catalogue of Life: taxonomy, the accepted name, authorship and synonyms; a local checklist table also answers common lookups with no network call
  • Wikipedia: a plain-language description
  • GBIF: occurrence records, distribution, phenology data and a map bounding box; for species_ext_map, a pre-rendered occurrence density tile layer that needs no GBIF key and downloads no raw occurrence data to the server
  • iNaturalist: a common name, a taxon summary, photographs, observation counts and recent sightings
  • IUCN Red List: conservation status, population trend, threats and habitat
  • EOL (Encyclopedia of Life): a description when Wikipedia has none
  • GloBI (Global Biotic Interactions): the interaction web, what a species eats, is eaten by, and lives on

A species is resolved once, the first time it is featured, and materialises into a local mirror table so pages stay fast; a cron job refreshes it monthly. Outbound calls are batched and de-duplicated through the shared request_bus, and a source that times out never blanks a value already stored. GBIF, iNaturalist and IUCN Red List keys are optional, held in the key module rather than in code; without an IUCN key the module degrades cleanly rather than failing.

Design decisions

  • Field-level source resolution. Each field is resolved independently from whichever upstream supplies it, rather than one API being authoritative for the whole record.
  • Weighted fallback identity. Source plugins are walked by weight and the first that resolves wins. The Catalogue of Life covers just over 80% of known species, so a species missing from it still gets an identity from Wikipedia's article title, an iNaturalist ID or a GBIF taxon key.
  • Materialise once, refresh monthly. A species is stored in a local mirror the first time it is featured, rather than the page firing up to seven live API calls on every view, and is then kept current by cron rather than on demand.
  • Curator edits are never clobbered. A featured flag and curator photographs are stored locally and survive every upstream refresh.
  • Built to be reusable. Nothing in species_ext is specific to one site; a site's own concerns stay in that project's own module.

Start a project.

Tell us about the species or biodiversity data your Drupal site needs to show.