Repository navigation
[6.x] Forms 2: Unique Instances - #15255
Draft
duncanmcclean wants to merge 254 commits into
Draft
duncanmcclean wants to merge 254 commits into
duncanmcclean wants to merge 254 commits into
Conversation
…need to use antlers Using Antlers in email address fields is still supported, but this is a slightly easier approach for end-users.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…llection Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The form fieldtype goes back to its forms-2 version. The View Submissions button only appeared in certain ui modes. To support it in others, it would require even more changes. This PR is already big enough. Now that there's a top level form instances field, there's already a simple way to view submissions. We can bring back the button in a future PR. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Submissions, limits, partials, overrides and the CP's View Submissions filters now resolve to the root entry, so every localization of an entry shares one instance. The submission's _site still records where it came from. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
It only works inside the form_instances fieldtype, so name it and its injection key accordingly. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Lost when FormFieldtype.test.js was deleted. Covers the submissionsMeta guard in the form_instances fieldtype. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
The field holds per-entry form configuration rather than content, so it augments to null in templates and API responses. Augmenting it to forms listed stored handles the runtime no longer honours, and the shape (forms vs instances) can be decided later without a breaking change. The CP listing column still lists the stored forms. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The entry's Configure → Connections editor was preloaded with the form's connector components, so entry-only connections got no meta and overridden ones got the form's. Meta-dependent fields like Grid lost their row state. Opening a connector now posts the field's current value to a new editor endpoint, which renders the component and meta from it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The entry lookup and localization now only run when a template or email actually uses `entry`, so looping over submissions doesn't pay for it otherwise. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Opening an entry serialized the submission entry filter for every form its collection offers, plucking _entry from all of each form's submissions and loading every matching entry, three times per form since toArray() builds the fields thrice. When the context provides an entry, the filter now only offers that entry, and its options are computed once per instance. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Malformed bodies caused a 500 from a TypeError in process(). Only id, enabled and conditions are checked, so stored connections that fail the connector's own rules can still be opened and fixed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Entry saves stored per-entry overrides without running any rules, so a crafted request could bypass connector validation (e.g. a namespaced email view) and the Access field rules. The Forms field now validates posted overrides for forms the user can configure, using the override blueprint's field rules and each connector's rules(), and reports a single error on the field. Stored config for forms the user can't edit is still kept without validation. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Applying a connector read the editing handle when the validate response arrived, so closing the editor mid-request wrote the result under a null key and silently dropped it, and opening another connector meanwhile overwrote that connector's connections and showed the old request's errors on it. The editor now can't be closed while Apply is in flight, and Apply captures its handle and request so a response from a closed or replaced editor is ignored. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Stored overrides are re-posted on every entry save, so one that drifted out of validity (a renamed form field, an unresolvable webhook host, a changed email view folder) blocked unrelated saves. Only overrides that differ from what's stored are validated now, and connections are compared per connection id so a drifted row doesn't block edits to its siblings. Localizations skip override validation entirely since they never store the field. An invalid date override's error now lands on the form instances field instead of a bare close_date key. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…editor Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Member
|
Storing per-entry connection config overrides is getting complicated. Going to revisit after forms 2 releases. |
jasonvarga
marked this pull request as draft
October 21, 2026 16:30
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This pull request implements "unique instances" for forms: a Forms Pro feature which lets a form be treated as its own instance per entry, with submissions tracked against the entry they were submitted from, rather than in aggregate.
The classic use case is an Events collection where every event has its own RSVP form — each event gets its own submissions, its own capacity and its own close date, all from a single
rsvpform.Like multi-page forms, everything lives in core but is only available when the
statamic/forms-proaddon is installed.Enabling unique instances
Toggle on "Unique Instances" in the form's configure screen, then attach the form to entries using the
formfieldtype.The frontend
When
{{ form:create }}is rendered in an entry's context, it outputs a hidden_entryinput, and the submission is tracked against that entry.Per-entry restrictions & overrides
When unique instances is enabled, the form's Access settings are evaluated per entry:
Connections are overridable in the same way, so each entry can have its own notifications. A warning banner is visible when configuring connections on a form with "unique instances" enabled.
CleanShot.2026-08-24.at.21.42.58.mp4
In the Control Panel
The submissions listing shows which entry each submission came from, and can be filtered down to a single entry.
On the entry's publish form, the form fieldtype has a "View Submissions" option which opens the entry's submissions in a stack, with individual submissions opening in a nested stack. The fieldtype's index view links to the pre-filtered submissions listing, and the submission page links back to the entry.
PHP API
The form fieldtype's value is stored as a plain handle until an entry has overrides, at which point it becomes an array with
formandconfigkeys.Restriction logic lives on a new
Instanceclass, since "is this form open?" becomes a per-entry question when unique instances is enabled:Depends on: