{% comment %} 015-read-single-record T002: one term/value pair, rendered as a
/
— a caller wraps a run of these in a
. Namespaced at cotton/controlled_vocabularies/ (plan.md Key design decision #5): a component at cotton/data_field.html in this package would silently shadow django-mvp's own for every project that installs both. Composes django-mvp's own / for everything inside the row; the two literal classes below are copied verbatim from django-mvp's own cotton/data_field.html (this package ships no stylesheet of its own, and django-mvp's is prebuilt from django-mvp's own templates, so a class this package invented would do nothing, silently — tests/test_ui/test_templates.py proves both are in the shipped stylesheet). short_form/uri/href are given together for a record-valued row (plan.md Key design decision #6): the short form is the in-site link's own text, and the canonical identifier is disclosed on hover behind it, never printed inline (015-read-single- record T029, FR-007). A ".tooltip" span *wraps* the link rather than the link carrying the class itself: daisyUI's reveal rule is :has(:focus-visible), which matches a focused *descendant*, so a keyboard user tabbing to the link inside the span sees the tooltip, but the identical class on the anchor never would. The accessible description is aria-describedby naming a visually-hidden ".sr-only" span (both verified present in the shipped stylesheet) holding the identifier — not title, which aria-describedby wins over where both are present and whose announcement is a per-user screen-reader setting anyway, and not aria-label, which would replace the link's accessible name (the short form) with the identifier rather than add to it. identifier_id is generated by the caller, one per record-valued row, so the hidden span's id stays unique on the page. entries (015-read-single-record T028) carries a list of {short_form, uri, href, identifier_id} dicts instead — a collection's membership is one row for every member it holds, not one row each, so the single
below lists them rather than a caller repeating this whole component once per member. Each entry gets the same hover disclosure, its own identifier_id keeping every member's hidden span distinct. term_uri (015-read-single-record T031) is the URI the term's own CURIE abbreviates, disclosed the same way a value's is: the tooltip for a pointer, a visually-hidden ".sr-only" span for assistive technology. It carried a title attribute as well until a reader saw both fire at once — the native title tooltip and daisyUI's, one on top of the other, saying the same thing. Nothing needed the title: the term is not interactive, so its hidden text is simply read in flow and needs no aria-describedby to tie it to anything, which is the same disclosure the
below makes and the reason there was never an asymmetry to justify. The tooltip class sits on a wrapping span rather than on the
, which sets display:inline-block and would shrink-wrap the whole term row. {% endcomment %}
{{ term }} {{ term_uri }}
{% if entries %}
    {% for entry in entries %}
  • {{ entry.uri }}
  • {% endfor %}
{% elif short_form %} {{ uri }} {% else %} {{ value }} {% endif %}