makr.dk

Content Type: Contact

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 way to get in touch — one Contact Content Element can hold several related entries at once (e.g. a Work and a Private Mail address under the same card), each rendered as an actionable link.

Fields

A Contact Content Element holds zero or more ordered entries. Each entry has:

  • Kind (mandatory) — one of a fixed, ordered list: Mail, Mobile (SMS Capable), Phone, Signal, Telegram, WhatsApp, Facebook, LinkedIn, Instagram, Home Page.
  • Value (mandatory) — the address, number, or service handle — never a complete service URL. Kartotek builds the actual link itself; pasting a full URL is rejected with an explanation, except for Home Page, where a URL/domain is exactly what's expected.
  • Description (optional) — free text describing the purpose of that one entry, e.g. "Work", "Private", "Press enquiries", "Booking". Repeated Kinds are allowed (e.g. two Mail entries).

Handle storage and generated links

The Value is stored as a bare handle, not a generated URL — Kartotek owns the canonical link template per Kind (mailto:, tel:, wa.me/…, signal.me/…, t.me/…, instagram.com/…, facebook.com/…, linkedin.com/…, and a plain https:// prefix for Home Page). A leading @ on a handle-based Kind is stripped automatically; a telephone number's own readable spacing (e.g. "+45 12 34 56 78") is preserved in what's stored and displayed — only the generated tel:/wa.me: link itself is normalized to bare digits. Mobile and Phone are visually distinct Kinds, but both link via tel:; SMS is a capability of Mobile, not a second action.

A legacy entry whose stored Value still looks like a full URL (from before this Issue) remains fully functional — the link still works — but is flagged for Admin repair rather than silently accepted as the new normal.

Semantic HTML and accessibility

Each entry renders as a native <a> with the Kind's own generated href (see above), a small fixed icon per Kind (decorative, aria-hidden — the Kind is understandable without color and without recognizing the icon shape, since an accessible name/hover title carrying the full Kind label always accompanies it), and the entry's own Value as the visible link text. mailto:/tel: links invoke the platform's own handler; every other Kind opens a normal external link.

Role, Rank, and Reference

A Post can hold several Contact Content Elements at once, each its own card of one or more entries, typically distinguished by Role (e.g. presentation) and Rank — see /_docs/posts. Entry order within one element is preserved as authored. Every Contact element also has an optional Reference — a separate, Post-unique name for addressing it inline instead of by Role/Rank — see /_docs/posts's "Reference: inline addressing" for the full detail.

Editing

In the admin Post editor, the Contacts section holds one block per Content Element, each with a Role field, a Position (Rank) field, and its own nested list of entries — a Kind selector, a Value field (with a live preview of the generated link, and a warning if the value still looks like a full URL), and an optional Description, with Add/Remove controls for entries within the block. Every Post Type's editor shows the same Contacts section regardless of which Type is active — used most heavily by the Category Presentation Post Type (/_docs/category-presentation), which requires at least one.

Rendering contexts

Inline

{{role}} or {{contact:reference}} embeds one Contact element's compact block at that position in the text: every entry, icon + linked Value, in authored order. A Description shows in parentheses after its entry's Value only when that entry's own Kind is repeated more than once within this element — never merely because a Description happens to be set.

Additional Information group

Every eligible Contact Content Element gathers into one Contacts group — the same icon + linked-Value rows as inline, Rank then stable Version order for elements, entry order preserved within each. Here the Description-shown-only-when-duplicated rule is scoped to the whole group, not just one element — a Kind appearing twice across two different Contact cards still triggers the Description display for both. Equal Values are never deduplicated; separately authored entries stay separately shown. Contact is a documented duplication exception (alongside Image): a Contact element referenced inline still also appears here, unlike every other kind.

Post metadata-page traversal

Every Contact element the Post has ever held (current Version, or full history via /metadata/history) is enumerated with its full entries array (Kind/Value/Description each) as JSON-LD/native JSON — see /_docs/posts's Metadata page section.

Standalone Content Element page

/_element/contact/:id shows every entry on that one Content Element — Kind, the generated actionable link, and its Description always shown as text (never gated on whether the Kind repeats, unlike the compact inline/Additional Information views) — gated exactly like the owning Post's own page.

Migration note

Existing Contact rows (an earlier email/phone/social model) were migrated automatically: each became its own single-entry element at its existing Role/Rank/address, with email → Mail, phone → Phone, and social → Home Page (the closest generic fit, since social previously covered six now-distinct services with no way to tell which one a given row meant). Nothing was merged — a genuinely multi-entry card only exists from this point forward, built explicitly in the admin editor.