Skip to content
Gaurav TiwariChangelog

All products

Changelog

Every release across our products, newest first.

RSS feed

Showing 313–324 of 618 releases

  1. Beta

    Core Forms 4.2.0-beta3

    Pre-release. Iterating on v4.2.0-beta2 based on tester feedback.

    Read full notes 10 changes

    Pre-release. Iterating on v4.2.0-beta2 based on tester feedback.

    Cross-origin Referer headers are stripped to the bare origin (https://example.com) by browsers under the default strict-origin-when-cross-origin policy, so without this [CF_REFERRER_URL], [CF_REFERRER_HOST], [CF_REFERRER_PATH], and [CF_POST_ID] were resolving to the WP REST endpoint's own URL on every embed.

    • What changed
    • WhatsApp actions now show in the per-form Add Action picker: All three v4.2.0 WhatsApp actions (Cloud API, Twilio WhatsApp, Click-to-WhatsApp redirect) live under a new Messaging & SMS category alongside Twilio SMS. They show up regardless of whether global WhatsApp Cloud credentials have been configured — credentials can be filled per-action when no global ones exist. Previously the picker only surfaced actions present in the static category map, so the three new actions were silently hidden.
    • Headless [CF_REFERRER_URL] etc. now resolve correctly: The headless submit endpoint now reads _cf_page_url from the JSON body and substitutes it into $_SERVER['HTTP_REFERER'] for the duration of Forms::process(). The bundled embed.js automatically forwards window.location.href; the native-fetch snippet in the Headless tab now shows this pattern too.
    • Import page redesigned
    • Renamed in the sidebar from "Import (CF7)" to Import — this page will house migration paths from multiple form plugins.
    • New source-picker card grid: Contact Form 7 (active), plus Gravity Forms, WPForms, Fluent Forms, Ninja Forms, and Formidable as visibly muted "Coming soon" cards.
    • CF7 form list rebuilt as a custom card-style layout below the picker rather than a wp-list-table.
    • Replaced the WP-native red-bar notice-error with a clean inline empty state.
    • Typeform-style mode is prominent: Promoted from a buried row inside the "Add-ons" accordion at the bottom of the Settings tab to a dedicated Display mode card at the top, with a marketing-style pitch panel explaining what Fullscreen mode is for. Card auto-opens when the form is already in fullscreen.
    • Carried over from earlier betas: See v4.2.0-beta for the WhatsApp / CF7 migration / 14 security fixes changelog, and v4.2.0-beta2 for the new Core Forms icon.
  2. Beta

    Core Forms 4.2.0-beta2

    Pre-release. Builds on v4.2.0-beta.

    Read full notes 9 changes

    Pre-release. Builds on v4.2.0-beta.

    Single visual language across every touchpoint:

    viewBox is normalised to a square 640×640 so the natural 640×512 glyph reads balanced at small render sizes. Menu fill stays black so WordPress's color-scheme stylesheet can tint it for active/hover states; block icons use currentColor for Gutenberg's hover/selected states.

    See v4.2.0-beta release notes for the full v4.2.0 changelog.

    • What's new: Replaced the abstract circular "C" admin-menu icon and the generic clipboard block-inserter icon with pen-field from Font Awesome Pro 7.2 — a square frame containing an input row and a pen.
    • WP admin sidebar menu
    • Gutenberg block inserter
    • In-editor Placeholder state (shown when no form is selected)
    • Carried over from v4.2.0-beta
    • WhatsApp Cloud API, Twilio WhatsApp, and Click-to-WhatsApp redirect actions
    • CF7 → Core Forms migration tool (forms + messages, with preview)
    • WhatsApp activity logging through Email Logs
    • 14 security audit findings fixed (CSRF default-on, headless API key header-only, headless CORS allowlist, webhook SSRF guard, email header CRLF injection, custom CSS </style> escape, polls/drafts hardening, file upload blocklist extended, honeypot returns opaque success, and more)
  3. Beta

    Core Forms 4.2.0-beta

    Pre-release. Distribution channel for testers before 4.2.0 GA.

    Read full notes 29 changes

    Pre-release. Distribution channel for testers before 4.2.0 GA.

    The cf_form_redirect_url filter now fires on every successful submission (not just when a per-form Redirect URL is set) and receives the Submission as a 4th argument. Existing 3-arg handlers keep working.

    Each row in the importer table has a "Preview converted HTML" disclosure so you can sanity-check before committing. CF7 stays installed and untouched — run both side-by-side during cutover. Flamingo submission import is out of scope.

    Full commit: b37bfae

    • WhatsApp, three ways
    • WhatsApp Cloud API action. Meta Graph API. Template + free-form modes. Global creds (Settings → WhatsApp Cloud API) with per-action override. Includes a Test connection button that pings /v21.0/{phone_number_id} and reports verified business name + quality rating.
    • Twilio WhatsApp action. Reuses your existing Twilio SID/token; posts to the whatsapp: channel. Optional Content Template SID for business-initiated outreach.
    • Click-to-WhatsApp redirect. Generates a wa.me deep link with the submission pre-filled into the chat draft and injects it as the post-submit redirect.
    • Contact Form 7 → Core Forms migration: New page at Core Forms → Import (CF7). Scans every wpcf7_contact_form post and converts: - Shortcode markup → plain HTML (text, email, tel, url, number, date, hidden, textarea, select, checkbox, radio, acceptance, file, submit, recaptcha) - CF7 mail template → Core Forms Send Email action - _messages meta → cf_message_* post meta (so your custom success/validation/spam copy carries over)
    • Operational polish
    • WhatsApp activity in Email Logs. Both Cloud API and Twilio sends log through the existing cf_email_logs table. The Type column labels them; Resend is suppressed for non-email rows (which would otherwise try to wp_mail a phone number).
    • cf_log_email() now switches between sanitize_email and sanitize_text_field based on action type.
    • Security hardening (14 audit findings fixed)
    • CSRF default flipped on. New installs get enable_nonce=1. Existing installs are preserved at 0 via a 4.2.0 migration that writes the prior value explicitly into stored settings. Sites that have always cached aggressively can keep nonces off; sites that haven't been should turn them on.
    • Submission mass-assignment closed. Forms::process() intersects POST keys with field names declared in the form markup. Filterable via cf_allowed_field_names.
    • Headless API key is header-only. The ?cf_key= query-string fallback is gone (leaked into logs/history/Referer).
    • Headless CORS allowlist. New textarea at Settings → Headless → Allowed origins. Empty preserves 4.1 behavior with an admin warning.
    • Workflow /actions/test requires manage_options. No longer a wp_mail / wp_remote / paid-SMS-anywhere primitive in editor-level hands.
    • Webhook SSRF guard. New cf_is_safe_outbound_url() helper rejects loopback, RFC1918, link-local, IPv6 unique-local, and non-HTTP schemes. Webhook auth header name/value also strip CR/LF.
    • Email header CRLF injection closed. New cf_esc_email_header() sanitizer replaces strip_tags on every header substitution in Email, Emailit, and Autoresponder actions.
    • Custom CSS </style> escape closed. The previous regex pattern didn't consume the closing >. Now strips every < from custom CSS at both save and render time.
    • process_save_form gains inline cap+nonce check (defense in depth — matches the existing guard on process_create_form).
    • Two ghost wp_ajax_* handlers removed (registered methods that didn't exist; calling them returned a fatal).
    • Polls trust REMOTE_ADDR only. HTTP_CLIENT_IP and HTTP_X_FORWARDED_FOR no longer honored by default. Opt back in via cf_poll_trust_forwarded_for for sites behind a trusted reverse proxy.
    • Draft saves rate-limited to 30 new drafts per IP+form per minute (filterable via cf_draft_save_rate_limit).
    • File upload blocklist extended with html, htm, xhtml, xml, xsl, xslt. Closes a stored-XSS path where nginx (which ignores the uploads .htaccess) served uploaded HTML as text/html on the WP origin.
    • Honeypot returns opaque success on missing/populated field instead of WordPress's silent 0 response — bots can no longer distinguish "rejected" from "accepted but never processed."
    • Upgrade notes
    • Backwards-compatible: the CSRF migration only writes enable_nonce=0 into installs that had no explicit value before, so existing form-bearing cached pages keep working.
    • Behavior changes worth knowing:
    • Webhooks pointing at 127.0.0.1, 192.168.*, 10.*, etc. will now fail. Local dev environments needing the loopback can override via the cf_is_safe_outbound_url filter.
    • Forms with JS-injected fields not present in the static markup will have those keys dropped. Use the cf_allowed_field_names filter to opt them in.
    • Editor-role users with edit_forms can no longer test arbitrary actions via the REST endpoint — they can still test by saving the action first.
  4. Stable

    Core Forms 4.1.0

    Five months of beta cooking, condensed into one release: payments on submission, headless / cross-origin REST, six new payment-ready templates, a full admin redesign, and a bootstrap hardening that protects the site during plugin upgrades.

    Read full notes 31 changes

    New submission statuses (pending_payment, paid, payment_failed, refunded), atomic CAS on the paid-state transition so concurrent webhook retries can't double-fire the action loop, return-URL signing with 2-hour expiry to stop replay.

    | Template | Provider | Pricing | |---|---|---| | One-time payment | Stripe | Fixed $19 | | Donation | PayPal | Donor-entered via [AMOUNT] | | INR payment | Razorpay | Fixed ₹999 | | FluentCart product | FluentCart | Variation-driven, with address fieldset | | Subscription | FluentCart Pro | Variation-driven, recurring | | Event ticket | Stripe | Tier select drives [TIER] |

    Templates registry gained settings and messages callbacks alongside markup. Every starting point — payment and non-payment — now ships with a context-appropriate success message ("Redirecting to PayPal…", "Booking received…") instead of the generic "We will be in touch soon."

    • Payments on submission: Five providers, all bundled, all webhook-verified.
    • Stripe Checkout — hosted Checkout Sessions, test + live keys side-by-side
    • PayPal — Orders API, fixed or donor-driven amounts via [field] references
    • Razorpay — UPI / cards / wallets via Razorpay Checkout
    • Polar.sh — Standard Webhooks signature verification
    • FluentCart — hosted-checkout handoff. Free + Pro, one-time + subscriptions. Address fields prefilled into FluentCart's checkout (and its tax engine). Order paid → submission paid via fluent_cart/order_paid_done; refunds round-trip.
    • Headless / cross-origin REST: External sites — Astro, Next.js, Vue, Svelte, plain HTML — can now render and submit Core Forms over REST. Same validation, captcha, action loop and payment redirect machinery runs server-side; the headless site just submits JSON.
    • GET /wp-json/core-forms/v1/forms/{id} — schema + rendered HTML
    • POST /wp-json/core-forms/v1/forms/{id}/submit — runs the full pipeline
    • GET /wp-json/core-forms/v1/embed.js — drop-in vanilla JS widget
    • Single API key per site (Settings → Headless), per-form opt-in toggle
    • Snippets in three flavours: widget, native fetch, cURL — each pre-filled with your actual submit URL + active key
    • New "Keeping the API key private" guidance card with copy-paste server-side proxy templates for Cloudflare Workers / Pages Functions, Next.js App Router, and Astro server endpoints
    • Six new payment-ready starting points: Each ships with a provider preselected so the form lands one configuration step away from working:
    • Admin redesign
    • Per-form Settings, Messages, Payment, Headless tabs converted to native <details>/<summary> accordions with state badges (rate-limit count, schedule "window set", honeypot on/off, FluentCart variation price/type/subscription summary, custom CSS/JS indicators, headless On/Off, configured/not-configured per gateway).
    • Per-form Submissions list rebuilt: Inbox / Spam / All view tabs with live counts (no more bouncing to global Spam to triage one form), redesigned table with status badges (New / Read / Replied / Archived / Paid / Pending payment / Refunded / Payment failed / Spam), row stripes for new/spam, per-row actions, relative dates with absolute on hover, varied empty states per view.
    • All Submissions page rebuilt for WordPress 7.0: toolbar split into a filter card (form picker + date range + Filter + Clear) and a search card. Consistent control heights so taller WP 7.0 native dates don't stagger the row. Side-fix: filter inputs are now in their own GET form so form_id / date_from / date_to actually land in the URL — previous version had them inside the bulk-actions POST form so filtering silently did nothing.
    • WordPress Screen Options dropdown hidden across all Core Forms admin screens.
    • Persistent "Akismet spam protection is active" banner removed from form-edit pages — status info doesn't belong as a banner on screens unrelated to it.
    • New cf_get_form_submissions / cf_count_form_submissions is_spam argument; new bulk_mark_spam per-form action.
    • Bootstrap hardening
    • vendor/autoload.php require now guarded with file_exists() so a mid-extraction race during a WordPress in-place plugin upgrade can't fatal the site. The upgrader replaces the plugin directory non-atomically; a hard require in that window kills every PHP request including wp-login.php. Now falls through cleanly and surfaces an admin notice on the next page load if vendor/ is genuinely missing.
    • Modernisation
    • Minimum requirements: PHP 8.1, WordPress 6.4
    • Schema\Field and Schema\FormSchema properties typed, declare(strict_types=1)
    • CI matrix runs PHP 8.1 / 8.2 / 8.3
    • prefers-reduced-motion respected throughout; logical-property RTL fixes
    • Fullscreen multi-step forms expose aria-current="step" + a polite live region for step changes
    • New filters + actions: cf_payments_orchestrator, cf_payment_completed, cf_form_default_settings, cf_form_templates. Full upgrade guide at docs/getting-started/upgrade-to-4.1.md.
    • Upgrading: Drop-in compatible from 4.0.x. The vendor-autoload guard means in-place WP upgrades from 4.0.x → 4.1.0 won't fatal even on slow filesystems. Database migrations run automatically on activation / via upgrader_process_complete.
  5. Beta

    Core Forms 4.1.0-beta7

    A new "Keeping the API key private" accordion on every form's Headless tab walks through the three patterns that actually keep the site-wide API key out of the browser bundle.

    Read full notes 1 change

    Threat-model framing comes first — honest, not moralizing. The key only authorises form submissions on headless-enabled forms; the worst case is spam on those forms (no account access, no billing, no data exfil). But spam is annoying, so:

    Server-side proxy templates — copy-paste, with the form's actual submit URL pre-filled: - Cloudflare Pages Functions / Workers (wrangler secret put) - Next.js App Router route handler (process.env, never NEXT_PUBLIC_*) - Astro server endpoint (import.meta.env, never PUBLIC_*)

    Captcha note: Turnstile / reCAPTCHA on the WP install verifies on every submission through the same pipeline — headless or not. Links straight to the global settings.

    Defense-in-depth checklist at the proxy: Origin allowlist, body size cap, User-Agent sanity, and an explicit "don't add a honeypot at the proxy" warning (browser autofill on field names like url / company / phone silently drops real submissions — the plugin has its own honeypot upstream).

    "If you must put the key in client code" — pragmatic close: not the end of the world, rotate when abused, watch the per-form Spam tab.

    • Headless tab — API key security guidance: A new "Keeping the API key private" accordion on every form's Headless tab walks through the three patterns that actually keep the site-wide API key out of the browser bundle.
  6. Beta

    Core Forms 4.1.0-beta6

    WP 7.0's taller native form controls (especially date inputs) caused the old toolbar to wrap onto four lines — bulk actions, then the form filter, then dates, then pagination, each on its own row. New layout:

    Read full notes 6 changes

    Consistent min-height: 36px across selects, date inputs, and buttons so the taller WP 7.0 dates don't stagger the row vertically. Stacks under 900px viewport.

    AllSubmissionsTable::extra_tablenav is now a no-op for the same reason (the WP_List_Table hook fires inside the wrong form).

    • Submissions page rebuilt for WP 7.0: WP 7.0's taller native form controls (especially date inputs) caused the old toolbar to wrap onto four lines — bulk actions, then the form filter, then dates, then pagination, each on its own row. New layout:
    • Filter card (top): form-picker + date range + Filter button + Clear link, in one row
    • Search card (right of the same row): search input + Search button
    • Bulk-actions row (under): bulk action select + Apply on the left, item count + pagination on the right
    • Cards grid below
    • Bonus fix: The previous markup had the filter inputs nested inside the bulk-actions POST form, so the "Filter" button never actually wrote form_id / date_from / date_to to the URL — and the listing reads $_GET. Filtering now uses an independent GET form, so query-string state survives the round trip.
  7. Beta

    Core Forms 4.1.0-beta5

    Templates registry gained a messages callback alongside markup and settings. Every template now ships with a context-appropriate Success message instead of the generic "We will be in touch soon":

    Read full notes 13 changes

    cf_get_template_messages() helper feeds the preset into cf_message_* post meta on form creation.

    • FluentCart fixes
    • Address fields collected on the form. FluentCart's checkout requires billing address by default. Beta4's templates didn't collect it, so users hit a half-empty checkout. The FluentCart product + subscription templates now include a billing fieldset (address line 1/2, city, state, postcode, country) named to match FluentCart's checkout schema.
    • Form fields prefill FluentCart checkout. The gateway maps submission data into cart->checkout_data['form_data'] so FluentCart auto-fills its inputs and TaxManager picks up country/state for tax. Two-pass mapping: billing_* / shipping_* keys forward verbatim; common aliases (NAME, EMAIL, COUNTRY, etc.) map to FluentCart equivalents.
    • Test/Live badge now reads FluentCart's own mode. The per-form Payment tab no longer shows the global Core Forms test/live badge for the FluentCart provider (which it doesn't gate). Instead reads FluentCart\Api\CurrencySettings's order_mode and renders "FluentCart: Live" / "FluentCart: Test" with a tooltip linking to the FC store settings.
    • FluentCart hidden when not installed. The gateway only registers when FluentCart's PHP classes exist. The "FluentCart product" and "Subscription" starter templates are filtered out of the Add Form gallery on the same condition.
    • Provider-switch resilience. FluentCart templates ship with a fallback payment_amount + currency so swapping to Stripe/PayPal/Razorpay later doesn't trip the gateway's "amount must be greater than zero" guard.
    • Per-template submission messages: Templates registry gained a messages callback alongside markup and settings. Every template now ships with a context-appropriate Success message instead of the generic "We will be in touch soon":
    • Payment templates — "Redirecting to PayPal…", "Welcome aboard…", etc. + payment-specific error copy
    • Contact — "Your message is on its way"
    • Newsletter — "You're on the list. Check your inbox"
    • Support — "Support ticket received. We'll reply within one business day"
    • Booking — "Booking received. You'll get a confirmation email"
    • (and so on for the rest)
  8. Beta

    Core Forms 4.1.0-beta4

    Six new templates in the Add Form gallery, each pre-configured with a payment provider so the form lands one step away from collecting money:

    Read full notes 5 changes

    | Template | Provider | Pricing | |---|---|---| | One-time payment | Stripe | Fixed $19 | | Donation | PayPal | Donor-entered amount via [AMOUNT] | | INR payment | Razorpay | Fixed ₹999 | | FluentCart product | FluentCart | Variation-driven | | Subscription | FluentCart Pro | Variation-driven, recurring | | Event ticket | Stripe | Tier select drives [TIER] amount |

    Templates registry now supports a settings callback alongside markup — new cf_get_template_settings() helper feeds the preset into the new form's _cf_settings meta on creation. Payment-category templates carry a blue "Payment ready" badge instead of the default "Accessible" one.

    • Payment-ready starting points: Six new templates in the Add Form gallery, each pre-configured with a payment provider so the form lands one step away from collecting money:
    • UI fixes
    • Global Payments settings: gateway accordions collapsed by default, not auto-opened on unconfigured gateways. Less visual noise; expand the one you're configuring.
    • Screen Options hidden: the WordPress Screen Options dropdown is suppressed across all Core Forms admin pages — All Forms, Add New, Settings, Spam, plus the per-form editor and submissions views.
    • Akismet banner removed: dropped the persistent "Akismet spam protection is active" notice on every form edit page. Status info doesn't belong as a banner on screens unrelated to it.
  9. Beta

    Core Forms 4.1.0-beta3

    Tested live against gauravtiwari.org's FluentCart 1.3.27 — beta2's correlation path was wrong:

    Read full notes 13 changes

    New UI primitives: - Pill-style Yes/No radios with hover/checked state - Number inputs with trailing unit hints (e.g. "submissions / IP / hour") - From → To range pairs for date and time - Day-of-week segmented picker — checked days fill blue - Monospace inset-shadow code textareas for Custom CSS/JS - Tightened form-table spacing inside accordions - Stacks to single column under 1100px viewport

    • FluentCart correlation fixes: Tested live against gauravtiwari.org's FluentCart 1.3.27 — beta2's correlation path was wrong:
    • Cart model uses cart_hash as its primary key, not id. Beta2 referenced $cart->id (always null), so the metadata-fallback path could never run. Removed it.
    • Order → Cart link goes through wp_fct_order_operations.cart_hash, not a direct $order->cart_id (no such column). The order_paid_done listener now walks Order → orderOperation → cart_hash → Cart and reads checkout_data['core_forms']['submission_id'].
    • Variations have no per-row currency; FluentCart is single-currency. Currency is now read from FluentCart\Api\CurrencySettings.
    • Per-form preview chip formats price using FluentCart's currency sign + position, surfaces subscription billing summary, trial days, and physical-fulfillment hints.
    • Form settings UI redesign: Six sections in the Settings tab now use <details>/<summary> accordions matching the Payment and Headless tabs. Each summary carries useful at-a-glance state:
    • Submissions — "rate limit 60/h" or "not stored" badges
    • After submission — confirmation type badge; redirect URL row only renders when redirect is selected
    • Anti-spam — honeypot on/off badge
    • Save & resume — on/off badge
    • Scheduling — "window set" / "always open" badge
    • Advanced — CSS / JS badges when custom code is present
    • Messages tab redesign: Same accordion pattern. Four core messages grouped under "Submission outcomes" with an explanatory header. Extension-injected <tr> rows get their own accordion when present, otherwise the section is omitted entirely.
  10. Beta

    Core Forms 4.1.0-beta2

    External sites (Astro, Next.js, plain HTML, anywhere) can now render and submit Core Forms over REST.

    Read full notes 18 changes
    • Headless / REST API: External sites (Astro, Next.js, plain HTML, anywhere) can now render and submit Core Forms over REST.
    • New endpoints under /wp-json/core-forms/v1:
    • GET /forms/{id} — schema (HTML + structured fields)
    • POST /forms/{id}/submit — runs the same validation/captcha/action pipeline as on-site submissions
    • GET /embed.js — drop-in vanilla JS widget
    • Site-wide API key (Settings → Headless) gates submissions; per-form Headless tab toggles exposure on/off and shows copy-paste snippets (widget, native fetch, cURL) pre-filled with the actual key.
    • Reveal/generate/copy controls on the API key field, status banners on the per-form tab.
    • CORS reflected per-origin; captcha is force-recommended since cross-origin submits can't use WP nonces.
    • FluentCart integration: Hosted-checkout handoff via FluentCart's own checkout — works on free + Pro, one-time + subscriptions.
    • New FluentCart payment gateway slots into the existing payments orchestrator alongside Stripe/PayPal/Razorpay/Polar.
    • Per-form Variation ID picker with live preview (title, price, payment type, link to FluentCart).
    • Listens to fluent_cart/order_paid_done to mark submissions paid and fire the post-payment action loop. order_status_changed_to_refunded syncs refunds back.
    • Pricing/currency come from the FluentCart variation — the form's Pricing fields are bypassed when this provider is selected.
    • Subscription variations work transparently on FluentCart Pro (FluentCart owns the recurring billing).
    • UI polish
    • Per-form Payment tab sections converted to native <details>/<summary> accordions matching the global Payments gateway list.
    • New Headless tab in the form editor with status banners, monospace code blocks, floating copy buttons, color-coded HTTP method tags.
    • Same-site gateways (FluentCart) skip the irrelevant Webhook URL row in global settings and explain why no credentials are needed.
  11. Beta

    Core Forms 4.1.0-beta1

    What's Changed

    Read full notes 6 changes
    • What's Changed
    • Add payment gateway integration (Stripe, PayPal, Razorpay, Polar)
    • Improvements
    • Convert per-form Payment tab (Provider / Pricing / After payment) to native <details>/<summary> accordions, matching the global Payments gateway list
    • Fixes
    • Fix undefined $form_id in submissions list tab (use $form->ID)
  12. Stable

    Core Forms 4.0.3

    Dashboard navigation, dashboard chrome, submissions polish, and updated documentation links.

    Read full notes 10 changes

    Stat tiles recoloured to the same restrained palette (32×32 icon chip, 18px/600 number, 12px label).

    .cf-btn family tightened to native WordPress scale: 7×14 padding, 13px/500, no brand shadow, no lift transform. .cf-btn--secondary uses the standard WP secondary palette so buttons sit comfortably next to native admin chrome.

    Extensible via the cf_action_value_labels filter. Applied in the per-form submissions table and the All Submissions cards.

    Strip action from new submissions — action is now in the default cf_ignored_field_names, so future submissions never store the AJAX router key. Existing rows still resolve through the friendly-label map.

    Hide column — the Data Management extension grows a non-destructive Hide Column toggle alongside Rename Column and Delete Column. Hidden columns are persisted per-form in _cf_hidden_columns post meta and merged with WordPress's get_hidden_columns(). Rename and Delete handlers keep that meta in sync.

    • Navigation
    • New shared views/admin-subnav.php — a tab bar (Forms · Add New · Submissions · Settings · Spam) included from every Core Forms dashboard page, with dashicons and an active-tab underline.
    • Old breadcrumb markup hidden via CSS so legacy includes degrade silently.
    • Page chrome — Form Theme Customizer card style: .cf-page-hero rebuilt as a clean white card matching the Form Theme Customizer: - 1px solid #dcdcde, 8px radius, subtle 0 1px 2px rgba(0,0,0,.04) shadow. - No gradients, no eyebrow pill, no chrome competing with the content. - Heading scales back to 18px / 600 / #1d2327; sub-text 13px / #50575e.
    • Submissions: Friendly action labels — new cf_friendly_action_label() helper maps stored WordPress AJAX action keys to human-readable labels: - cf_form_submit → Form Submission - cf_save_draft → Form Draft Saved
    • Documentation links: All in-app docs links now point to gauravtiwari.org/course/core-forms-training/ (the previous /core-forms/ subdirectory was defunct). The /product/core-forms/ landing page is reserved for marketing CTAs only.
    • Upgrade notes
    • No data or schema migrations.
    • Pure UI / chrome refresh plus opt-in column hiding — fully backwards compatible.
    • Existing submissions that already contain the action field stay intact and now render as friendly labels.