Skip to content

Build a form

Briefing, not authority. (R) rule at linked source · (O) dated upstream fact · (P) procedure · (C) open work · (G) not established.

WHAT THIS MEANS IN DRUPAL

"Form" is four things. Pick the row:

You need Drupal calls it Route
Editors edit a bundle Entity form + form display, field groups Config only (R) site-building §4a
Visitors submit data Webform (contrib) Adoption gate first (R) standard §13
Settings for a PROVEN_GAP module ConfigFormBase + config/schema Code, last rung (R) site-building §25
Change an existing form Form alter ECA Form or OOP hook: C-FORM-ALTER

Canvas page: place the form's block as a component (O, unverified).

OWNER

  • Entity forms: core config (R) capability map.
  • Visitor forms: no Bluefly record; not in the matrix (G); record work tracked on dam-16u (C). Drupal CMS's contact form is Webform + CAPTCHA + Honeypot; Webform 6.3.1: D10.3/D11, security-covered (O 2026-10-01).
  • Core Contact: deprecated 11.4, removed 12.0 (O change record). Not a route.

PREREQUISITES

  1. (P) State the requirement, not the module (adoption A1).
  2. (P) Visitor form: adoption A1-A5 lands a matrix record DISPOSITION=ADOPT before composer require.
  3. (P) Settings form: a PROVEN_GAP record exists.

DO THIS

  1. (P) Editorial: form display + field groups in §4a order (Core, Story, Relationships, Media, Discovery/SEO, Promotion, Governance); plain-English labels; export config.
  2. (P) Visitor: Webform config entity, exported; reusable form ships as a recipe (R) Rule I standard §3.
  3. (P) Post-submit automation: ECA model, not a subscriber (R) Rule E, how-we-build §12.
  4. (P) Settings: ConfigFormBase, constructor DI, schema in config/schema/.
  5. (P) Verify: submit as anon and authenticated; check stored result and a11y.

WATCH FOR

  • CSRF: Form API adds and validates form_token; non-form routes need _csrf_token (O drupal.org); Bluefly silent (G).
  • #access takes an AccessResult, not a boolean; declare cache contexts; personalized parts via #lazy_builder, scalar args (R) standard §10 render rules.
  • Spam, PII retention: Webform can purge submissions (O); no Bluefly policy (G) C-FORM-POLICY.
  • A11y is acceptance: labels, focus, keyboard, errors (R) site-building §29.
  • Handler credentials: Key reference to 1Password only (R) secrets.

DO NOT

  • Build a custom module, entity or table for submissions (R) Rule J.
  • Post a JS form to a custom route: no Form API CSRF (O); new ingress needs proof (R) how-we-build §14.
  • Put editorial copy in component source (R) site-building §4.

OWNERSHIP / CAN-SHOULD-MAY

  • CAN: config UI, Drush, Tool Belt tools.
  • SHOULD: site repo owns site forms, recipes reusable ones, theme presentation (R) site-building §17, §1, §16.
  • MAY: install only after an adoption record adoption; machine mutations pass the Cedar gate (R) AGENTS.

DO NOT REDISCOVER

  • Config before code, recipes over modules (R) Rules I, J; §4a section order; ECA owns automation (R) Rule E; core Contact is leaving core (O).

CONFLICTS

ID A B Resolution
C-CONTACT dam-16u hypothesis: simple contact = core Contact drupal.org: deprecated 11.4 Follow upstream; no core Contact.
C-FORM-ALTER BEST-PRACTICES §2.2: OOP form_alter Rule E, how-we-build §12: ECA first Undecided. Proposed: ECA Form if event-condition-action, else OOP hook. Thomas decides.
C-WEBFORM-OWNER Drupal CMS default: Webform Bluefly matrix: no record Run adoption first.
C-FORM-POLICY Webform purge, spam add-ons exist No Bluefly retention/spam rule Decision needed.

GO DEEPER

Anchored sources: frontmatter authority_sources. Expires last_verified + 30d.