Title: TOFU (Template-Oriented Form Utilities)
Author: LionHeart Group
Published: <strong>Олунньу 18, 2026</strong>
Last modified: Алтынньы 6, 2026

---

Search plugins

![](https://ps.w.org/template-oriented-form-utilities/assets/banner-772x250.jpg?
rev=3722311)

![](https://ps.w.org/template-oriented-form-utilities/assets/icon-256x256.jpg?rev
=3722311)

# TOFU (Template-Oriented Form Utilities)

 By [LionHeart Group](https://profiles.wordpress.org/lionheartgroup/)

[Download](https://downloads.wordpress.org/plugin/template-oriented-form-utilities.0.1.3.zip)

 * [Details](https://sah.wordpress.org/plugins/template-oriented-form-utilities/#description)
 * [Reviews](https://sah.wordpress.org/plugins/template-oriented-form-utilities/#reviews)
 *  [Installation](https://sah.wordpress.org/plugins/template-oriented-form-utilities/#installation)
 * [Development](https://sah.wordpress.org/plugins/template-oriented-form-utilities/#developers)

 [Support](https://wordpress.org/support/plugin/template-oriented-form-utilities/)

## Description

Template-Oriented Form Utilities (TOFU) is designed to streamline the process of
creating and managing forms within WordPress themes and plugins. By adopting a template-
oriented approach, TOFU allows developers to define form structures and behaviors
using reusable templates, making it easier to manage/maintain with team collaboration
through version control systems.

Forms are configured in the theme’s PHP code and nothing about them is stored in
the database. A read-only screen under Tools shows each registered form’s pages,
mail, fields and features, and points out pages and mail templates that don’t exist.

GitHub and documentation for this plugin can be found at:

[https://github.com/lionheart-group/wp-template-oriented-plugins/tree/master/plugins/template-oriented-form-utilities](https://github.com/lionheart-group/wp-template-oriented-plugins/tree/master/plugins/template-oriented-form-utilities)

### External services

This plugin relies on third-party services to protect your website from spam and
automated attacks. Depending on your configuration, this plugin connects to the 
following services:

#### Google reCAPTCHA

 * **Purpose:** Protecting forms from spam and bot abuse.
 * **When data is sent:** When a page containing a reCAPTCHA-protected form is loaded
   or submitted.
 * **Data sent:** IP address, mouse movements, browser/device information, and duration
   of stay.
 * **Service Provider:** Google LLC.
 * **Links:** [Google Privacy Policy](https://policies.google.com/privacy), [Google Terms of Service](https://policies.google.com/terms).

#### Cloudflare Turnstile

 * **Purpose:** Privacy-focused alternative for bot protection and spam prevention.
 * **When data is sent:** When a user interacts with a form protected by Turnstile.
 * **Data sent:** Browser/device characteristics and interaction data (privacy-friendly,
   does not use cookies for tracking).
 * **Service Provider:** Cloudflare, Inc.
 * **Links:** [Cloudflare Privacy Policy](https://www.cloudflare.com/privacypolicy/),
   [Cloudflare Website Terms](https://www.cloudflare.com/website-terms/).

## Installation

 1. From the WP admin panel, click “Plugins” -> “Add new”.
 2. In the browser input box, type “Template-Oriented Form Utilities”.
 3. Select the “Template-Oriented Form Utilities” plugin and click “Install”.
 4. Activate the plugin.

OR…

 1. Download the plugin from this page.
 2. Save the .zip file to a location on your computer.
 3. Open the WP admin panel, and click “Plugins” -> “Add new”.
 4. Click “upload”.. then browse to the .zip file downloaded from this page.
 5. Click “Install”.. and then “Activate plugin”.

## FAQ

### Where are the form settings?

In your theme’s code. Tools -> Forms (TOFU) shows them, read-only.

## Reviews

There are no reviews for this plugin.

## Contributors & Developers

“TOFU (Template-Oriented Form Utilities)” is open source software. The following
people have contributed to this plugin.

Contributors

 *   [ LionHeart Group ](https://profiles.wordpress.org/lionheartgroup/)

[Translate “TOFU (Template-Oriented Form Utilities)” into your language.](https://translate.wordpress.org/projects/wp-plugins/template-oriented-form-utilities)

### Interested in development?

[Browse the code](https://plugins.trac.wordpress.org/browser/template-oriented-form-utilities/),
check out the [SVN repository](https://plugins.svn.wordpress.org/template-oriented-form-utilities/),
or subscribe to the [development log](https://plugins.trac.wordpress.org/log/template-oriented-form-utilities/)
by [RSS](https://plugins.trac.wordpress.org/log/template-oriented-form-utilities/?limit=100&mode=stop_on_copy&format=rss).

## Changelog

 * v0.0.1 — Initial release.
 * v0.0.2 — Arranged required PHP version to 8.1, added external services section
   to the readme.
 * v0.0.3
    - Implemented Ajax form submission and validation with reCAPTCHA and Turnstile
      support.
    - Fixed recaptcha issue when embedded multiple forms on the same page.
    - Replaced validation library from wixel/gump to somnambulist/validation.
 * v0.0.4
    - Added optional database recording of form submissions (`saveToDatabase`), 
      encrypted at
       rest, with an admin screen to view recorded data.
    - Added `Form::setTemplate()` to override a form’s input/confirm/result URLs
      per visitor
       session, so a single registered form can be embedded on multiple
      pages (e.g. post templates); added `FormConfig::$dynamicTemplate` for forms
      configured this way.
 * v0.0.5
    - The AJAX nonce endpoint (`GET /wp-json/tofu/v1/forms/{key}/nonce`) now also
      returns the
       reCAPTCHA/Turnstile site key when enabled, so cross-origin/headless
      clients no longer need to hardcode it separately from the server-side configuration.
 * v0.0.6
    - Fixed: AJAX form submissions with a field literally named `key` could fail
      with a
       “form not found” error, because the REST handlers read the form key
      from the merged request parameters instead of strictly from the URL route.
 * v0.0.7
    - Replaced the bundled validation library with an in-house engine. The plugin
      now has no
       runtime dependencies at all. Every rule name still resolves, so
      existing `rules:` configuration keeps working — see the upgrade notice for
      the behavioural differences.
    - Added: `required_file` as the name of the required-file rule. `custom_required_file`,
      
      its name since 0.0.3, still works and runs the same code.
    - Fixed: a full-width space (U+3000) no longer satisfies `required`. It is what
      a Japanese
       IME emits for the space bar, so a field the visitor sees as empty
      could pass.
    - Fixed: `required` now recognises an empty file input as empty.
    - Fixed: `after`, `before`, `extension` and `uuid` no longer raise a fatal error
      on
       ordinary input — a blank date field was enough to return a 500.
    - Fixed: `uploaded_file`, `mimes` and `extension` now work. They depended on
      a check that
       is never true in this plugin’s request flow.
    - Fixed: a file carried over to the confirm page is verified against the server’s
      own
       session record, so a tampered form cannot claim an upload that is not
      there.
    - Fixed: the session cookie is issued only when a session is actually saved.
      It was
       previously sent on every request, including pages with no form and
      the admin screens, which is enough to stop most full-page caches serving anything
      cached.
    - Fixed: the plugin never called `load_plugin_textdomain()`, so its bundled 
      Japanese
       translations were not loaded and validation, reCAPTCHA and Turnstile
      messages rendered in English on Japanese sites.
    - Fixed: “reCAPTCHA token is missing.” and “Turnstile token is missing.” were
      the only
       bot-protection messages not passed through `__()`, so they stayed
      English even on a translated site.
    - Fixed: none of the recorded-submissions admin screen’s text had been extracted
      for
       translation since it was added in 0.0.4, so translators never received
      it. It is in the .pot now, with Japanese supplied.
    - Tested against WordPress 7.1.
 * v0.1.0
    - Added: seven actions and filters, so code outside a form’s own configuration
      can react to
       submissions and extend validation — `tofu_form_submitted`, tofu_register_validation_rules,`
      tofu_pre_send_mail`, `tofu_validation_failed`, tofu_redirect_url, `tofu_record_values`
      and `tofu_admin_page_capability`. They fire for the redirect and AJAX flows
      alike. See docs/hooks/index.md.
    - Added: a named custom validation rule can now be registered site-wide, via
      the
       tofu_register_validation_rules action. The validator factory was previously
      unreachable, so this was not possible without editing the plugin.
    - Fixed: `Form::setTemplate()` no longer writes to the session, and so no longer
      sends a
       Set-Cookie, when a page is merely rendered. A theme calling it for
      each of its registered forms on every page load was issuing one cookie per
      form on every response — including pages with no form on them — which stops
      server and CDN page caches serving anything cached. The override is now carried
      to the following POST in a hidden field and persisted only when the visitor
      actually submits.
    - Fixed: at most one session cookie is issued per response. A single response
      can save the
       session more than once, and each save sent its own redundant`
      Set-Cookie`.
    - Fixed: database migrations now run when the plugin is updated. The plugin 
      listened for
       upgrade_process_complete, which WordPress does not define — 
      the hook is upgrader_process_complete — so migrations had only ever run on
      activation. A site that installed before a migration was added and updated
      since never received it; updating to this version applies anything outstanding.
      Migrations are tracked in `wp_tofu_migrate` and already-applied ones are skipped,
      so there is nothing to do by hand.
    - Fixed: a submission nonce is now bound to the form it was issued for. The 
      redirect flow
       minted its nonce against a bare `input`/`confirm` action, so
      a nonce issued for one form verified against every other one; only the field
      name distinguished them, and a field name is a label the sender controls. 
      The REST flow already did this.
    - Changed: the plugin’s own hidden field names now all use a `__tofu_` prefix,
      and a form may
       no longer declare a field name starting with `_tofu_` or `
      __tofu_` — `FormConfig` throws at registration instead of letting the collision
      silently drop the form’s value. Breaking for AJAX/headless clients that hardcode
      those names; see the upgrade notice.
 * v0.1.1
    - Added: `MailConfig::$returnPath` sets the Return-Path (envelope sender) of
      the plugin’s
       emails, so bounces go to a chosen address instead of the server
      default. WordPress ignores a `Return-Path:` header passed to `wp_mail()`, 
      so it is applied to PHPMailer’s Sender and only for the plugin’s own messages.`
      Mail::setReturnPath()` lets a tofu_pre_send_mail callback set it per recipient.
      See docs/settings/mailconfig.md.
 * v0.1.2
    - Added: a read-only screen under Tools -> Forms (TOFU) that shows each registered
      form’s
       pages, mail, fields and features, one tab per form. It points out 
      pages and mail templates that don’t exist, bot protection that is enabled 
      but not registered, and placeholders that are not allowed fields. Secret keys
      are never shown. The screen uses the same `tofu_admin_page_capability` as 
      the records screen. See docs/admin/index.md.
    - Fixed: the migration that adds the `data` and `submitted_at` columns compares
      column
       names exactly. With `LIKE`, the `_` in `submitted_at` matched any 
      character, so a similarly named column could make the migration skip adding
      it.
    - Fixed: running the migrations a second time in the same request, after one
      had failed,
       stopped with a fatal error instead of retrying it.
    - Declared `Requires at least: 6.0`, so translate.wordpress.org imports the 
      plugin’s strings.
    - Escaped and sanitized request values flagged by Plugin Check.
 * v0.1.3
    - Fixed: database migrations now also run when the plugin’s files are replaced
      without
       WordPress’s updater (FTP, deployments). The plugin compares the stored`
      tofu_db_version` with its own version on `init` and runs any outstanding migration
      once; a failed one is retried on the next request.
    - Requires WordPress 6.5.

## Meta

 *  Version **0.1.3**
 *  Last updated **2 нэдиэлэ ago**
 *  Active installations **Fewer than 10**
 *  WordPress version ** 6.5 or higher **
 *  Tested up to **7.1.3**
 *  PHP version ** 8.1 or higher **
 *  Language
 * [English (US)](https://wordpress.org/plugins/template-oriented-form-utilities/)
 * Tags
 * [forms](https://sah.wordpress.org/plugins/tags/forms/)[utilities](https://sah.wordpress.org/plugins/tags/utilities/)
 *  [Advanced View](https://sah.wordpress.org/plugins/template-oriented-form-utilities/advanced/)

## Ratings

No reviews have been submitted yet.

[Your review](https://wordpress.org/support/plugin/template-oriented-form-utilities/reviews/#new-post)

[See all reviews](https://wordpress.org/support/plugin/template-oriented-form-utilities/reviews/)

## Contributors

 *   [ LionHeart Group ](https://profiles.wordpress.org/lionheartgroup/)

## Support

Got something to say? Need help?

 [View support forum](https://wordpress.org/support/plugin/template-oriented-form-utilities/)