Contents of static websites generated by a Site.
Note
Parts of this page are specific to the BAS Catalogue.
An OpenAPI definition describes the majority of the site structure. It is available as:
- a JSON document (using the OAS 3.1 schema) at:
/static/json/openapi.json - interactive documentation built from this JSON document at:
/guides/api/index.html
Additional static content such as CSS, JS, fonts and images managed by the Site Resources Output are not listed in this definition.
The static site includes some supporting pages for legal policies, guides, etc. They are generated by the Site Pages output using Site Templates and Static Site Page Metadata to set HTML Metadata and Item Previews.
These pages are included in the OpenAPI definition.
This diagram shows the external services and resources the static site depends on and links out to.
HTML metadata elements are included by the html_head Site Macro for:
viewport- for enabling Responsive designgeneratorandversion- for reporting the application name and version (for troubleshooting)generated- when a page was generated (for troubleshooting)store-ref- optional commit associated with the site build's Store (for troubleshooting)description- page summary (for SEO)
All pages inheriting from the Base Layout will include primary navigation links shown in either the site header or footer (for desktop and mobile respectively).
These links always included:
- the catalogue root
- the BAS Public Website
Additional links MAY be included in the Site Macros primary_nav_items variable.
Note
A high bar SHOULD apply items included in the primary navigation.
All pages inheriting from the Base Layout will include secondary navigation links shown in the footer.
Links are defined in the secondary_nav_items variable within the Site Macros and MAY include:
- significant sections of the site, such as the BAS Maps Catalogue
- relevant external and internal resources, such as data access and publishing guides
A fixed set of links to legal policies and the BAS Public Website as a copyright holder are always included.
Tailwind is used as a base CSS framework, extended to:
- use colours and fonts from the 2015 and 2025 BAS Style Kit
- use the Tailwind typography plugin to style user generated content in Records (such as abstracts)
- use the Tailwind forms plugin to apply base styles to the Contact Form
The pytailwindcss package is used to manage a standalone
Tailwind CLI install to avoid needing Node.js.
As per the BAS Style Kit, and wider UK Government guidance, the Catalogue site MUST be designed with accessibility in mind.
We maintain a basic accessibility check in src/lantern/resources/templates/_views/legal/accessibility.html.j2, which
SHOULD be reviewed and revised on a regular basis.
As per the BAS Style Kit, the Catalogue site MUST use Responsive design.
This means designing for the smallest (mobile) viewport by default with Tailwind's modifiers used for larger viewports. For example, stacking content in a single column by default and two or more where the viewport allows.
Note
Whilst mobiles aren't expected to be the primary device type for this site, designing responsively to avoid common pitfalls (such as overflowing content) also helps with accessibility and so MUST be considered.
Ratio based sizing SHOULD be used over fixed sizes (e.g. w-1/2).
A consistent, and constrained, spacing scale SHOULD be used wherever possible:
- small:
-2 - medium:
-4 - large:
-8
Exceptions to this scale MAY and will be made for specific use cases.
Tailwind's space-x-* and space-y-* classes SHOULD be used for spacing between elements for consistency. Padding
SHOULD be used over margins where possible to limit `the number of classes.
Tip
Run the css-audit Development Task to check currently used classes in templates.
Consideration SHOULD be given the user's colour preference by providing a dark mode using the Tailwind dark: modifier.
A Colour Audit and reference is manually maintained to coordinate and constrain the range of colours used across the site. Update this document if changing or adding colours.
Tip
Run the css-audit Development Task to check currently used classes in templates.
Styles are defined in src/lantern/resources/templates/_assets/css/main.css.j2, which is a Jinja2 template to allow
the search path for content to be set dynamically at runtime. This content is needed for the Tailwind compiler to find
classes used in the built static site.
Note
Using the Site Templates as the content path will not work, as they contain interpolated class names the Tailwind compiler cannot resolve, causing missing styles.
Compiled and minified output MUST be stored as src/lantern/resources/css/main.css, as this file will be copied into
the site build directory and referenced within generated pages.
Tip
See the Development documentation for how to update styles.
Font Awesome Pro 7 MAY be used for adding icons.
Font Awesome is included via a hosted Kit.
Important
Icons SHOULD be used sparingly and MUST NOT exclusively convey context or meaning.
An Icon Audit and reference is manually maintained to coordinate and constrain icons used across the site. Update this document if changing or adding icons.
Tip
Run the icons-audit Development Task to check currently used icons in templates
and a list of additional places to manually check.
A set of site wide scripts are included using Site Macros for:
- Sentry error monitoring and user feedback
- Plausible analytics
- Cloudflare Turnstile bot protection for forms
- Progressive Enhancements for various bits of functionality
Note
Functionality SHOULD be preferably implemented using HTML and CSS alone where practical. Scripts SHOULD be used for progressive enhancement and support graceful degradation where possible.
First party JavaScript are defined in:
src/lantern/resources/js/for static filessrc/lantern/resources/templates/_assets/js/*for scripts including variables from macros
Tip
See the Development documentation for how to update scripts.
Where functionality relies on JavaScript, templates SHOULD:
- use a
<noscript>element to show a static fallback of some content for users without JavaScript - use
class="{{ com.show_js_only() }} ..."on the full/interactive version which will add a.hiddenclass
The Enhancements script will remove this .hidden class from any elements, and the browser
will automatically hide any <noscript> elements, where JavaScript is available.
This approach is used for distribution options for example, where collapsible sections are used to hide optional data
where possible. Where JavaScript is disabled, <noscript> elements show the full content statically as a fallback.
A set of targeted enhancements to:
- enable 'sticky tabs' where:
- the active tab is set in the URL fragment when switching tabs
- an initial tab is switched to automatically if a tab fragment is present on page load
- enable progressive disclosure via simple collapsible sections
- used for Site Feedback and some item distribution options (e.g. feature services)
- show content where JavaScript is enabled, as an 'else' to
<noscript> - process feedback from the User Feedback widget when submitted
To ensure the latest CSS and JS files are used by browsers, a query string value is appended to the URLs of static
assets, e.g. main.css?v=123. For reproducibility, this value is set to the first 7 characters of the current package
version as a SHA1 hash, e.g. main.css?v=f053ddb for version 0.1.0.
Important
Asset references are not automatically changed. Rebuild the site after a release to update references.
Tip
You may need to manually clear caches locally when developing, as this value will not change until the next release.
Content in the live static site is cached for 24 hours by default. To force a cache invalidation, use the
site-invalidate Development Task specifying one or more key patterns to invalidate.
A permissive Content Security Policy is set via HTTP header.
This policy allows resources from all origins and inline scripts (needed to support Item Sharing Previews).
CORS headers are set to allow access to all site resources from any origin.
For features vulnerable to spam and abuse, such as the Item Enquires, Cloudflare Turnstile is used to distinguish humans from bot agents. Typically, this check is non-interactive but may require the user to check a box.
Note
An error handler is configured to supress 300x and 600x series errors (Generic challenge failures) from
Sentry, as these don't indicate an error with the site configuration.
Warning
Turnstile triggers various browser warnings and errors, even when working correctly.
These include:
- cross-origin errors between the challenge iframe and main page, such as: 'Blocked a frame with origin "https://challenges.cloudflare.com" from accessing a frame with origin "https://data.bas.ac.uk". Protocols, domains, and ports must match.'
- various messages with junk content at different log levels, such as '%c%d' from the challenge script.
- 401 errors for requesting a Private Access Token, which are expected to fail
Tip
See https://browser-compat.turnstile.workers.dev/ to check your browser against Turnstile generically.
A custom form for collecting User Feedback via Sentry is included on all pages via a Site Macro included in the Base Layout.
HTML templates use the Jinja2 framework.
Templates use these options from the app lantern.Config class:
TEMPLATES_CACHE_BUST_VALUE: See Cache bustingTEMPLATES_ITEM_CONTACT_ENDPOINT: See Contact formTEMPLATES_ITEM_CONTACT_TURNSTILE_KEY: Turnstile site key for item form Bot ProtectionTEMPLATES_ITEM_MAPS_ENDPOINT: See Extent mapsTEMPLATES_ITEM_VERSIONS_ENDPOINT: Base URL for constructing links to view Record RevisionsTEMPLATES_PLAUSIBLE_DOMAIN: Plausible site identifier for Frontend Analytics
See the Config docs for how to set these config options.
A set of layouts are available in src/lantern/resources/templates/_layouts/. All pages SHOULD ultimately extend the
Base Layout. Most pages SHOULD extend from the Main Layout.
The base.html.j2 layout provides a common HTML structure including:
- a
<head>element with HTML metadata and imports for site styles and scripts - a
<body>element with:- a
<header>element with site navigation, development phase banner and user feedback link - a 'content' block for each HTML page's content with minimal padding
- a
<footer>element with site feedback link and legal information
- a
Note
This layout requires a Site Context instance as a meta template context
variable.
The main.html.j2 layout extends the Base Layout with:
- a
<main>element containing a 'main' block for each HTML page's content, wrapped in a container at a standard width
The page.html.j2 template extends the Main Layout providing a simple page structure for legal
policies, error documents, guides, etc.
It extends the parent 'main' block with:
- a page header
- a 'page_content' block for each page's content
Important
Child templates MUST set a main_title variable for setting the page header title. E.g.:
{% extends "_layouts/page.html.j2" %}
{% set header_main = "Foo" %}
{% block page_content %}
<p>...</p>
{% endblock %}Macros are used extensively within templates, to emulate the component pattern commonly used in JavaScript frameworks.
Note
Whilst this is an aim, it is applied pragmatically rather than dogmatically and will evolve over time.
src/lantern/resources/templates/_macros/common.html.j2 defines macros for:
- classes for layouts, links, buttons, tables, icons and other common elements
- common identifiers for 'back to top' links, user feedback widget triggers, etc.
- low level components such as internal and external links, page and item headers, layout containers, etc.
- higher level components such as item summaries, alerts, etc.
Common macros are intended for use across templates to avoid inconsistencies and simplify maintenance.
src/lantern/resources/templates/_macros/assets.html.j2 defines macros for:
- JavaScript snippets for Progressive Enhancements
src/lantern/resources/templates/_macros/site.html.j2 defines:
- a
primary_nav_itemsvariable for Primary Navigation - a
html_headmacro builds a<head>element- requires a Site Metadata context object
- a
headermacro builds a site wide<header>element with side wide navigation and development phase banner including site feedback - a
feedback_widgetmacro creates a User Feedback widget- requires a Site Metadata context object
- a
footermacro builds a side wide<footer>element with site feedback and legal information- requires a Site Metadata context object
Items use a complex template when rendered, with the Item passed as a context variable. It extends the Main Layout with:
- a top part, consisting of a page header
- a middle part, consisting of a summary section and optional item thumbnail
- a bottom part, with dynamic tabs, where a macro is called based on a series of tab names
Elements across these parts use Item Macros to organise and breakdown the template's content.
Tip
See the Development documentation for how to add new elements.
Macros in these templates are used to assemble Items:
src/lantern/resources/templates/_macros/site.html.j2src/lantern/resources/templates/_macros/tabs.html.j2src/lantern/resources/templates/_macros/_tabs/*.j2
The data tab within the Item Templates shows any available downloads, services or other distribution methods (collectively distribution items) in a grid-based table layout. Each grid row consists of:
- columns for:
- a distinguishing label: which may be the file format if unique or a custom value
- an optional download size: automatically formatted with appropriate units if measured in bytes
- an action link or button: either to an external URL or to trigger a collapsible section
- optional descriptive text: shown full-width without any HTML formatting
- an optional collapsible section, shown full-width using a template snippet
Note
It isn't intended for descriptive text and a collapsible section to be used together.
Distribution items are defined by the lantern.models.item.catalogue.distributions.Distribution) class with properties
for the label, action, description, etc. Subclasses for file and service based options (e.g. feature services)
set common defaults.
For file based options, label and description properties map to the title and description if set in the transfer option online resource. Where the title is not set, the file format is used as a default.
Important
For consistency, file based options should use the file format as the online title using values defined by the
lantern.models.item.catalogue.enums.DistributionType enum.
For service based options, labels are hard-coded to the service type name and descriptions are disabled as collapsible sections are used for showing service endpoints and usage instructions.
The extent tab within the Item Templates includes a map for the Item's geographic extent. These maps
use the BAS Embedded Maps Service, embedded as an <iframe> with a src
URL computed within each Item.
The contact tab within the Item Templates includes a form for users to send item enquires. These forms submit to a Microsoft Power Automate flow which routes enquires to the relevant team and returns a result page to the user.
To protect against spam and abuse, the form includes a hidden Bot Protection field, validated in the Power Automate flow. Where this validation fails, the flow returns an error page to the user.
Free-text item properties including title, abstract, summary, lineage, etc. support Markdown formatting.
In addition to typical syntax, some additional features are supported:
- tables
- admonitions (notes, tips, warnings, etc.)
- automatically formatting inline URLs and email addresses as links
The guide in src/resources/templates/_views/-/formatting.html.j2 SHOULD be maintained to show end-users how supported
formatting will appear.
For development, use the Formatting Test Record for more exciting examples.
Item pages include metadata to improve how items appear when shared on social media and messaging platforms:
- Open Graph is included as part of Site Metadata
- limited Schema.org (JSON-LD) metadata is implemented via and for Microsoft Teams
