Skip to content

[FEAT] Section-manifest grid page — profile-driven layout, numbering, and defect-visible stubs - #79

Merged
eleanorfrajka merged 6 commits into
mainfrom
rep/06-manifest-grid
Aug 17, 2026
Merged

[FEAT] Section-manifest grid page — profile-driven layout, numbering, and defect-visible stubs#79
eleanorfrajka merged 6 commits into
mainfrom
rep/06-manifest-grid

Conversation

@eleanorfrajka

Copy link
Copy Markdown
Collaborator

Summary

Ports the grid report page onto the section-manifest system (model + resolver landed in #78). The grid page is now described by a declarative profile — an ordered list of sections, each naming the panels beneath it — and rendered by a single generic section loop, instead of a hand-maintained template where every figure had its own {% if fig_x_b64 %} block, heading, and caption. Section numbering, the jump-nav, and the appendix lettering are all generated from the resolved profile, so the two can no longer drift.

The visible payoff: regrouping a page is now data, not code. GRID_DEFAULT gives T-S its own section; GRID_COMBINED_HYDRO folds T-S into Hydrography — a four-line replace, no template edits. And an applicable-but-unavailable panel now renders a visible stub with a reason rather than silently vanishing, which is what surfaces metadata defects instead of hiding them.

What changed

  • reports/_manifest.py (earlier commits on this branch): PanelGroup (panel-level data expansion, e.g. one panel per isopycnal, without inflating the section count); Panel.unavailable_if (a precondition checked before render — returns a reason string to stub with, distinct from a render that returns None and gets the generic stub); resolve(..., drop_stub=).
  • Grid registry in reports/_grid.py: GridContext + build_grid_context (computes latitude, ts_bounds, history and NetCDF metadata once); GRID_PANELS wrapping the unchanged _make_* figure adapters; GRID_SECTIONS, GRID_DEFAULT (8 content sections + appendix A), GRID_COMBINED_HYDRO; the Overflow per-isopycnal PanelGroup.
  • Captions are now a data field (GRID_CAPTIONS, keyed by panel id): plain text with Unicode scientific notation (σ₀, N², log₁₀, m s⁻¹, …), rendered escaped. This is deliberate: captions are slated to become user-editable via a future config/report.yaml, and trusted HTML in user-editable data is an injection vector. The <code>/<strong> markup on ~6 tokens (CLI flags, "Left:"/"Right:") is dropped for now; restoring it via a safe Markdown-lite converter is tracked as a follow-up.
  • applies_to per panel ("could this exist for this deployment?", not "did it render?"): velocity sections gate on eastward/northward velocity; hydrography and T-S on temperature plus salinity-or-conductivity; stratification and overflow on a sigma* field; spectra on temperature/velocity. A section whose panels are all inapplicable is dropped and named in a new "Not applicable to this deployment" footer line.
  • N² stubs on unresolved latitude. n2's unavailable_if returns a reason when the mooring latitude cannot be parsed from the file attributes, so the page shows "Buoyancy frequency unavailable: mooring latitude could not be resolved" instead of silently computing N² at the equator. The temperature and rotary spectra still compute at lat=0 as before (a spectrum at lat=0 is defensible; N² is not).
  • Shared panel() macro (templates/_macros.html): the single place class="fig slot-*" is emitted, branching on panel kind so |safe applies only to authored html/table payloads — a figure payload is always escaped into an img src, and captions are escaped. The figure collapse toggle is preserved (and now lives in the shared macro, ready to roll out to the other pages as they port).
  • html/table panels render via small sub-templates (_grid_history.html, _grid_nc_variables.html, _grid_nc_scalars.html, _grid_nc_globals.html) whose markup is transcribed verbatim from the old inline template.
  • Tests: tests/unit/test_grid_manifest.py gains render-based checks against the dune2 fixture — content numbering 1..N, appendix A, no duplicate section id/title, every resolved slot is a real SLOTS key, non-figure panels carry their kind, and the ts_bounds-independent-of-the-T-S-section coupling. The grid golden is re-baselined; only the grid page moved.

Breaking changes

  • Grid report HTML layout changed (output format). Section anchors are renamed to their section ids (#hydro#hydrography, #vel#velocity, #ts#ts_diagram, #strat#stratification, #vars#netcdf_variables, etc.). Headings are now numbered (2. Hydrography, appendix A. NetCDF variables). The jump-nav is generated from the resolved sections (one entry per section, not per figure). Figure captions are plain text (Unicode, no <code>/<strong>) and full-width figures now carry an explicit class="fig slot-full". Migration: any external deep-link into a grid page anchor must use the new section-id anchors (an audit found no such links in this repo or the docs).
  • generate_grid_page no longer accepts the per-figure keyword arguments. It now builds a GridContext and resolves a profile internally; callers that invoked it with fig_*_b64=/sigma_sections= kwargs (there are none outside reports/) must stop passing them.
  • Behavioural: N² is stubbed, not drawn, when latitude is unresolved. A grid page for a mooring whose latitude cannot be parsed previously showed an N² figure computed at lat=0; it now shows a stub with the reason. This is intended (a wrong N² is worse than an absent one).

@eleanorfrajka
eleanorfrajka merged commit 34c3a05 into main Aug 17, 2026
5 checks passed
@eleanorfrajka
eleanorfrajka deleted the rep/06-manifest-grid branch August 17, 2026 09:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant