makr.dk

Content Type: Image

Changes to how this Type behaves are requested through a GitHub Issue and implemented, together with this reference page, through the repository's normal workflow. See /_docs/posts for how Content Types, Roles, and Rank work in general, and docs/Internal/type-doc-templates.md for the Content Type Doc template this file follows.

A single image attached to a Post — a cover photo, an avatar, one entry in a gallery, or any other picture a Post needs. Not to be confused with the Image Post Type (/_docs/image), which is a whole Post built around showing one image; an Image ContentElement is a smaller building block usable by any Post Type, including several at once under different Roles (cover, avatar, gallery, …).

Where it comes from

Ingested one of three ways, same as Video and Audio — see /_docs/media for the full mechanics:

  • Upload — a file (or a batch of files), drag-dropped, pasted, or chosen from a file picker.
  • Fetch by URL — paste a URL and the server downloads and stores the file itself.
  • Embed — a hand-provided embed snippet (e.g. a live chart or widget). An embedded Image has no local file at all.

Fields

  • The image itself (mandatory) — a locally-stored file (Upload/Fetch by URL) or an embed snippet (Embed). Whichever it is, it doesn't change after the fact: editing an Image never replaces its file in place, it creates a new Image ContentElement (see /_docs/posts for why).
  • Caption (key optional) — text shown alongside the image.
  • Metadata (specialist) — read-only, extracted automatically at ingestion time from the file's EXIF data where present: captured date and GPS location, plus every other EXIF tag the file carries (camera make/model, exposure, ISO, and so on) behind a "Full EXIF" disclosure in the admin editor. Only populated for a locally-stored Image (Upload/Fetch by URL); an embedded Image has no file to extract it from. An Image ingested before this existed doesn't get it retroactively on its own; the Database admin page has a one-off "Backfill EXIF metadata for existing Images" action. A curated, non-identifying subset of this (camera make/model/lens, exposure settings, capture date) is also shown publicly on the Image's own standalone metadata page, along with a geolocation map when GPS was captured — everything not on that allowlist (device serial numbers, and so on) stays Admin-only.
  • Descriptive metadata (optional) — a separate, editable set of fields (a label, description, alt text, creator/attribution, rights, and similar) distinct from the read-only EXIF metadata above — mainly useful for an Image brought in from elsewhere, to preserve facts about where it came from. The description and creator fields feed directly into the public caption display wherever one is shown (see "Semantic HTML and accessibility," below) — the rest (alt text, rights, and so on) still aren't rendered publicly. See /_docs/json-import for the full field list.
  • Source citation (optional) — a real, managed Link identifying where the image came from: a source label and URL, edited in their own "Source citation" section on the Image (not the generic Links section — a citation Link isn't independently listed there or in Related information/Additional Information, since it's presentation data attached to this Image, not its own separate item). This is a genuine Link Content Element under the hood, so it gets the same live health checking, local-PDF/Wayback fallback, and colored status icon as any other managed link on the site — the citation section shows its current status and links to its own metadata page. Removing or replacing the source label/URL replaces or clears this citation on the next save. Content imported before this Content Type existed and never re-saved since may still show an older plain-text form — see "Semantic HTML and accessibility" below.

Semantic HTML and accessibility

Renders as a native <img> (MediaElement.tsx) for a locally-stored Image, or the admin-provided embed snippet verbatim for an Embed row. A caption, where there's anything to show, is composed (ImageCaption.tsx for a React-rendered site; contentReferences.ts's imageCaptionHtml for an inline {{...}}-referenced one — same underlying data via composeImageCaption, kept in sync by hand since one builds JSX and the other an escaped HTML string) from the plain Caption field and the description/creator/source-citation fields — "Description (Credit: Creator, via Source)," each part omitted when absent, the entire parenthetical credit in italics, Source rendered as a real hyperlink when both its label and URL are present. Source additionally carries the same compact colored status icon every other managed Link shows — opens the citation's own metadata/status page, separate from the citation link's own click-through. An Image whose source citation was never promoted to a real Link (imported, or created, before this Content Type existed) still shows Source as plain text/a bare hyperlink with no status icon, exactly as it always has — the admin editor's Source citation section starts empty for it (it doesn't read the old text fields), so promoting it means re-typing the source label/URL into that section once. Shown as separate visible text (a <figcaption> in a gallery/listing/inline-reference context, a plain paragraph elsewhere) rather than as the image's alt attribute. An Additional Information mini-gallery thumbnail is the one deliberate exception: thumbnail only, no caption shown there at all (see /_docs/article's Content placement section). Most call sites pass no alt at all (an empty, decorative-image default), except Category Presentation's avatar, which uses the Post's title as alt. This is a known, honestly-documented gap, not a deliberate accessibility design — captioned images elsewhere aren't currently alt-texted for a screen reader.

Hover overlay and fullscreen viewer: on a Post's own page, an eligible Image (see "Stable classes" below for which ones aren't) is wrapped in a .media-hoverable container exposing two small controls on pointer hover or keyboard focus — always visible on touch-only devices, since there's no hover state to reveal them — Fullscreen (opens the site's fullscreen media viewer on that Image) and Info (opens /_element/image/:id, that Image's own standalone metadata page). Clicking the image itself (not a control) does the same thing as the Fullscreen control in a Post's own page; in a Category/Tag/listing context (PostBrief.tsx's thumbnail), clicking it instead opens the owning Post — there's no fullscreen viewer in that context. The fullscreen viewer itself browses every eligible Image rendered anywhere in the current Post Version, once per Content Element, in the order it actually appears in the page — Left/Right Arrow keys, swipe (touch), and on-screen Previous/Next controls step through it, stopping (not wrapping) at the first/last entry; its open/closed state and current Image are reflected in the address bar's ?view=image:<id> query parameter, so Back closes it and a copied link reopens the same Image.

Role, Rank, and Reference

A Post can hold several Images at once, each with its own Role (cover, avatar, gallery, …) — see /_docs/posts for what Role and Rank mean in general. Several Images can share the same Role (e.g. a gallery), distinguished by Rank, editable directly in the admin editor as a "Position" field. Every Image also has an optional Reference — a separate, Post-unique name for addressing it inline (e.g. {{team-photo}}) instead of by Role/Rank — see /_docs/posts's "Reference: inline addressing" for the full detail.

Editing

In the admin Post editor, the Images section holds one block per Image. Each block has the ingestion controls described above (Upload / Fetch by URL / Embed tabs), a Role field, a Position (Rank) field when more than one Image shares a Role, and a caption field with the extracted metadata shown read-only beside it. A "Source citation" section holds the source label/URL, the citation's current link-health status once saved, and a link to its own metadata page — separate from the Metadata section's other descriptive fields, which no longer has its own Source URL field for Images (Links still have theirs, since a Link's own upstream source is a different concept). Every Post Type's editor shows the same Images section regardless of which Type is active — see /_docs/posts.

Rendering contexts

Inline

{{cover}} inline-embeds the current cover-Role Image (or any other single-Role Image, by its Role name) right where the reference sits — see /_docs/posts for the full content reference syntax. On larger screens it's sized to 80% of the surrounding prose column's width, centred; below a ~800px width it takes the full column width instead. Aspect ratio is always preserved, and it's never rendered wider than its own intrinsic pixel size — a smaller source image is shown at its natural size, never stretched to fill the column. When there's a composed caption to show, the image renders inside a <figure> with that caption as a <figcaption> below it, same as every other captioned Image context; with nothing to show, it stays a bare <img> as before.

Additional Information "Media" mini-gallery

Every Post Type's shared Additional Information container's Media group (Images, Videos, and Audio combined): every eligible Image on the resolved Version, as one compact, consistently cropped thumbnail grid, in Rank-then-stable-Version order — thumbnail only, no caption shown there (see "Semantic HTML and accessibility" above). This is the one Content Type with a documented duplication exception: an Image already shown by its Post Type's own primary/inline renderer (Article's cover, Image's primary, FullScreen's preview, a Gallery's own gallery-role grid, an inline {{role}} reference, …) still also appears here — every other Content Type is shown once, never duplicated (Video/Audio share this same grid without gaining Image's own duplication exception). Selecting an Image thumbnail opens the same fullscreen viewer described above, navigating the same Post-wide sequence — a Video/Audio tile instead opens its own standalone metadata page, since neither has an in-page fullscreen viewer.

Gallery's own primary grid (its gallery-role images, shown separately from Additional Information — see /_docs/gallery) is unrelated to this grouping, despite the visual similarity.

End-of-Post listing

Not typically used standalone — see each Post Type's own Doc for exactly where its Image elements land on its Full page.

Post metadata-page traversal

Every Image the Post has ever held (current Version, or full history via /metadata/history) is enumerated with its caption, URL, and EXIF metadata as JSON-LD/native JSON fields — see /_docs/posts's Metadata page section.

Standalone Content Element page

/_element/image/:id shows the image itself plus its composed caption, gated exactly like the owning Post's own page. Publicly useful technical facts follow when present: original dimensions, format, and file size; a curated public-safe subset of extracted EXIF behind a "Technical (EXIF) details" disclosure; a geolocation map and coordinates when GPS EXIF was captured; and a download link for the original file. See docs/Internal/type-doc-templates.md.