ai:skills › d3-f-pages · version 1 ·
name
d3-f-pages
description
Pages, apps and embeds — a page is a topic: home cards, tables, built-in blocks, embedhtml widgets and the d2 bridge, App: topics, layouts, show=. Get skills only from /api/v2/skills/d3.
feature
pages
concepts
[page, card, table, block, embed, app, show]
tags
#skill #feature #d3skill #wip

d3-f-pages✎ edit

Intro✎ edit

Pages are topics: tables, blocks, embeds and apps.

In d2 a page is a topic: markdown first, with small fenced blocks for data (table), built-in widgets, live HTML (embedhtml) and, when a page needs a free hand, a whole App: page. show= decides on the server who sees which part. d2's own screens are built the same way. Saving is d3-f-topics and d3-f-drafts; the look d3-f-styles; model and objects d3-f-domain, d3-f-data. Spec: Spec › pages.

Essentials✎ edit

  • R-pages-1 MUST reach for the simplest thing that works, in order: markdown → a table → a built-in block → an embedhtml widget → an App: page.
  • R-pages-2 Data on a page is a table, never code; numbers are computed in the model (computed fields), never in the page.
  • R-pages-3 Keep data in objects and logic in rules; a page only shows and triggers.
  • R-pages-4 Who sees what is show=, applied on the server; NEVER put a secret in a topic, hidden or not.
  • R-pages-5 NEVER let a secret reach an embed or app (no token, vault or starter route) — an embed can fetch other sites, so whatever reaches it can leave.
  • R-pages-6 MUST open the page after saving and read it; a bad table or block shows as a red note in its place.
  • R-pages-7 Signed pages run as built-in: base d2's Page: topics are served inside d2's own page: no frame, same origin, their own script renders on the client with the viewer's session, and the server's role checks decide each call (Razie, 2026-10-10, P-1242). A page d2 itself needs is a signed Page:, never an App: copied into projects. A project's own Pages, Apps and widgets are user code and run sandboxed in a frame; a sandboxed frame has no localStorage: use d2.store (P-1239).

Concepts✎ edit

page✎ edit

A topic rendered as a page at /topics/<name>. Also called: screen, view. Fields (frontmatter): layout (page | full | none), edit (architect makes it the Architect's alone).

page_check✎ edit

  • Summary: after saving, open the page and read it.
  • When: after every save of a page, table, block or app.
  • Needs: the saved topic.
  • Call: open /topics/<name> (or the app's address).
  • Rules: R-pages-6. A red note → fix what it says and save again.
  • Errors: red note → a class or field that doesn't exist, or a bad line.
  • Gotchas: —

page_layout✎ edit

  • Summary: layout: page for a chrome-free page; full for a full-page app.
  • When: a page that shouldn't look like an ordinary topic.
  • Needs: —
  • Call: frontmatter layout: page (navbar and body only — no title bar, contents, frontmatter box, history or button row; editors get a floating ✎ Edit) Also: layout: full (whole window, no d2 chrome, a small Home button) · none: an ordinary topic page.
  • Rules: Use full only when needed (a console, an app for a phone's home screen) and handle your own navigation (hash links). The user menu's Edit is the fail-safe for pages whose own buttons don't show.
  • Errors: —
  • Gotchas: —

card✎ edit

A home page's app launcher line in the first ```cards block right after the # title. **Also called:** app card, home card. **Fields:** icon | title | link | text (link: /path, a URL or [[Topic]]; soon for one not live yet), optional | show=<cond>.

card_add✎ edit

  • Summary: one card per app, in Home's first cards block.
  • When: a new app should show on Home.
  • Needs: Home read first.
  • Call: save Home with the line added to its first cards block (start one right after the # title if none).
  • Rules: Change only the card block; keep the lines already there; never two cards for one app.
  • Errors: —
  • Gotchas: —

table✎ edit

A ```table fence that draws a class's objects with the page (reload for new data). **Also called:** data table, list. **Fields (one key: value per line):** class (required), columns (fields or paths through one reference, each optionally as a label; none: every plain field), totals, sort (<col> asc|desc), filter (an expression, account is "TFSA"), color (greens/reds numbers), add: no, title, limit.

table_show✎ edit

  • Summary: show objects with a table fence, not code.
  • When: any data on a page; for an app, its table(s) at the top of its page, then a line on what it is.
  • Needs: the class and field names (d3-f-domain).
  • Call: ```table with class: Holding, columns: company, shares, company.price as Price, value, pl as P/L, totals: value, pl, sort: value desc, color: pl.
  • Rules: R-pages-2. The first cell opens the object's edit form, + Add the new-object form; both return to the page. On a phone each row becomes a card.
  • Errors: red note → unknown class or field · E_WAIT → a web fetch in a table, query or computed field: fetch in a rule.
  • Gotchas: —

block✎ edit

A built-in fence d2 renders per viewer (code, not page content). Also called: widget. Kinds: next-step (Sign up / Log in; make your first project; back to the last-used project), my-projects (the viewer's projects, newest first, then + New project), new-project (the create form alone), connect-ai (the Connect your AI steps).

block_use✎ edit

  • Summary: drop in a built-in fence; it renders for the viewer.
  • When: landing, home or onboarding pages.
  • Needs: —
  • Call: ```next-step · ```my-projects · ```new-project · ```connect-ai.
  • Rules: connect-ai is the only place a starter token shows (sealed, never in page text). A visitor-only renderer shows nothing for an unknown block.
  • Errors: —
  • Gotchas: —

embed✎ edit

An ```embedhtml fence: HTML, CSS and a <script> run in a sandboxed frame (no cookies, no same-origin), sized to its content; links open in a new tab. **Also called:** widget, live HTML. **Bridge:** d2.api(method, path, body), d2.go(url), d2.params (the page address's query, read-only).

embed_write✎ edit

  • Summary: prefer an embed in a plain topic over an App:.
  • When: a page needs live HTML a table or block can't give.
  • Needs: —
  • Call: an ```embedhtml fence in the topic.
  • Rules: Embeds keep the navbar and need no special routing. Use the page's look: the CSS variables (var(--ink), var(--card), var(--line), var(--soft), var(--leaf), var(--rose), var(--display), var(--body)) or link /styles/current.css (d3-f-styles › style_link).
  • Errors: —
  • Gotchas: —

embed_callD2✎ edit

  • Summary: talk to d2 only through the bridge, as the viewer, allowlisted routes only.
  • When: an embed reads objects or topics, or creates a project.
  • Needs: a route on the allowlist.
  • Call: await d2.api(method, path, body) → the parsed answer (throws with the error) Also: d2.go(url) navigates the page to a URL on this d2.
  • Rules: R-pages-5. Allowlist: GET /api/v2/me, reads of /api/v2/dom/… and /api/v2/topics/… on the page's project, GET /api/v2/search, GET /api/v2/projects/available, POST /api/v2/projects.
  • Errors: E_SCOPE → route not on the allowlist (or d2.go to another site): use a table, an App:, or ask for a platform change.
  • Gotchas: —

embed_fetchOutside✎ edit

  • Summary: outside sources only if open CORS and keyless; never a blank on failure.
  • When: an embed shows data from another site.
  • Needs: a source that allows any origin and needs no key.
  • Call: fetch(<url>) from the embed's script.
  • Rules: Show a clear state when the source doesn't answer (source unreachable), never a blank. A source that refuses CORS or needs a key → fetch it in a rule (http.json, d3-f-engine).
  • Errors: embed shows nothing → its source refused CORS or needs a key.
  • Gotchas: —

app✎ edit

A model (a Spec: topic with $class lines), its data (objects, often seeded from a Story:), a page (a table, or an App:<name> topic) and a card on Home. An App:<name> topic is a whole HTML page at /app/<name> under the project's top bar. Also called: tool, dashboard.

app_build✎ edit

  • Summary: model, sample data, a page, a Home card — from your person's words.
  • When: your person wants something to track or do.
  • Needs: what they said, in their words.
  • Call: a Spec: topic (d3-f-domain) → a Story: with $object samples (d3-f-data › object_declare) → a page with a table → card_add.
  • Rules: Add a few sample objects so they see it working, then show them: with Mind Meld on, take their tab there (d3-f-esp); otherwise give the link.
  • Errors: —
  • Gotchas: —

app_import✎ edit

  • Summary: copy an example project's topics under the same names.
  • When: your person wants an app like an existing example.
  • Needs: the example project's topic names.
  • Call: GET https://<example>/api/v2/topics/<T> (e.g. Spec:portfolio) for each → write it under the same name.
  • Rules: Offer to replace the samples with their own data.
  • Errors: —
  • Gotchas: —

app_page✎ edit

  • Summary: an App: topic only when a page needs a free hand.
  • When: a dashboard or a custom editor; an embed won't do.
  • Needs: the routes it calls.
  • Call: an App:<name> topic → /app/<name>; it calls await d2.api(method, path, body) as the viewer, e.g. d2.api("GET", "/api/v2/dom/MarketStatus") or a rule run d2.api("POST", "/api/v2/diesel/run", {story: "$send market.refresh", scratch: false}).
  • Rules: R-pages-3. Only the project's /api/v2 routes (not accounts, tokens or admin). data-show="<cond>" on any element removes it on the server for viewers who don't match. layout: full per #page_layout. A project's landing or home may name a full-page app.
  • Errors: E_SCOPE → a route outside the project's /api/v2.
  • Gotchas: —

app_fast✎ edit

  • Summary: make an App: or Page: show at once and stay quick — what a frame costs and how to avoid each cost.
  • When: writing or reviewing any App: or Page: topic, d2's own or a project's; a page that feels slow.
  • Needs: the reads the page makes before it can draw, and after each write.
  • Call: what a page costs, and the fix for each:
    1. The frame starts late. The page loads, then its sandboxed frame (/embed), then the script is parsed, then the first read. → Keep the script small (load only what the first screen needs, then the rest), and put the first read in frontmatter as boot: /api/v2/<one GET path>: the server runs it as the viewer while serving and the page reads it from d2.boot before any call (falls back to its own read when d2.boot is null). boot: ships with P-1180.
    2. Every d2.api call is a hop through the outer page. → One read that answers what the first screen needs (an …/app-style route), never a loop of small reads; at most four reads at once.
    3. Large inputs built in the browser. → Never read whole big topics (Testing, Spec) to compute a view; ask for the computed answer from a server route, cached with ETag/If-None-Match (the brain map: GET /api/v2/brain, P-1181). Keep what is read in sessionStorage for the session, keyed by project and build.
    4. A full reload after each write. → Patch in place: every write answers with what it changed; put that one row or card into the list and redraw only it. Notice others' changes with a cheap stamp (GET …/stamp, or the list's stamp) and reload only when it moved.
    5. Waiting on the slowest part. → Paint the main content first (cards, rows), then the heavy extras (maps, charts) after it; show a one-line placeholder, never a blank frame.
  • Rules: R-pages-9. Never ask for server rendering of a page's own script: designer code doesn't run in the server. A route the page needs that the bridge refuses is a coder ticket naming the route, not a workaround.
  • Errors: E_SCOPE from d2.api on a route the page needs → see #app_page (a base Page: reaches more than a project's page).
  • Gotchas: Before saving, check the page against points 1–5. Then open it and look at the network: count the reads before the first paint, and after one save (aim: one before, none after).

show✎ edit

A condition that removes part of a page on the server before it leaves. Also called: visibility, hidden section. Where: a heading (## Admin tools {show=admin} hides it to the next heading of the same or higher level), any fence (```cards show=mod), a cards line ending | show=member, a ```show <cond> fence around markdown, data-show in apps. Conditions: the ladder visitor < guest (signed in, not a member) < member < mod < admin < architect, each at least; person, ai, an agent role (designer, maker…); level:hero|creator|pro|master (at least); projects:none|some. , any of, + and, ! not: show=guest+!member, show=member+level:pro.

show_hide✎ edit

  • Summary: hide a section, block or line with show=; server-side everywhere.
  • When: a part only some viewers should see.
  • Needs: the condition.
  • Call: {show=<cond>} on a heading, show=<cond> on a fence, | show=<cond> on a cards line, data-show in an app.
  • Rules: R-pages-4. Applied on the rendered page, GET /api/v2/topics/<t>, search, the system view and exports. A token is judged by its role capped by its person's role. A section left empty after filtering is dropped. Inherited pages show with the viewer's role in the project they're on.
  • Errors: —
  • Gotchas: window.d2user (planned) only decorates on the client; anything that must stay hidden uses show=.

show_edit✎ edit

  • Summary: editing needs seeing everything.
  • When: editing, drafting, publishing or reading the full text/history of a topic with show= parts.
  • Needs: a role that sees every part.
  • Call: the ordinary topic write (d3-f-topics).
  • Rules: Whoever can't see every part may not edit, draft, publish or read its full text or history. edit: architect makes a topic the Architect's alone. Inherited pages are edited only at home, with the role there.
  • Errors: E_SCOPE naming the hidden part's condition → someone who sees all of it edits it.
  • Gotchas: —

Rules✎ edit

  • R-pages-7 d2's own screens (the landing App:Landing, the new-project pages named by base newProject, admin tiles, the Toolbox) are topics on base d2, changed as pages; code only for what a page can't do itself (a new API or core behaviour).
  • R-pages-8 Every new user-facing page gets a Toolbox tile and a Help section in the same change (d3-f-help › toolbox_addTile).
  • R-pages-9 Every App: and Page: MUST be fast: its first screen from one read (boot: once it ships), writes patched in place, big inputs computed on the server, the main content painted first (app_fast). Razie, 2026-10-10: "save all this info on how to make a page somewhere where makers and designers can reference, so custom Pages are also fast".

Errors✎ edit

  • red note where a table or block should be — a class or field that doesn't exist, or a bad line → fix what it says, save again. see #page_check
  • E_SCOPE from d2.api / d2.go — route not on the bridge's allowlist, or another site → a table, an App:, or a platform change. see #embed_callD2
  • E_SCOPE naming a show= condition on edit or save — part of the topic is hidden from you → someone who sees all of it edits it. see #show_edit
  • embed shows nothing — its outside source refused CORS or needs a key → source unreachable, fetch in a rule. see #embed_fetchOutside
  • a page slow to show or after a save — too many reads before the first paint, or a full reload after a write → see #app_fast
  • E_WAIT — a web fetch in a computed field, table or query → fetch in a rule. see #table_show