PHPackages                             perfectus/perform - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Validation &amp; Sanitization](/categories/validation)
4. /
5. perfectus/perform

ActiveCraft-plugin[Validation &amp; Sanitization](/categories/validation)

perfectus/perform
=================

Form handling for Craft developers. Process, test, store, send email notifications, configure client side validation, include powerful spam protection, and more.

1.0.2(5y ago)41.2k↓100%[2 issues](https://github.com/ohlincik/craft-perform/issues)proprietaryPHPCI failing

Since Nov 8Pushed 5y ago1 watchersCompare

[ Source](https://github.com/ohlincik/craft-perform)[ Packagist](https://packagist.org/packages/perfectus/perform)[ RSS](/packages/perfectus-perform/feed)WikiDiscussions master Synced 1mo ago

READMEChangelog (4)Dependencies (1)Versions (6)Used By (0)

PerForm plugin for Craft CMS 3.x
================================

[](#perform-plugin-for-craft-cms-3x)

PerForm facilitates form handling for Craft developers. Process, test, store, send email notifications, configure client side validation, include powerful spam protection, and more.

[![Screenshot](resources/img/plugin-logo.png)](resources/img/plugin-logo.png)

Requirements
------------

[](#requirements)

This plugin requires Craft CMS 3.0.18 or later.

Installation
------------

[](#installation)

To install the PerForm plugin, follow these instructions:

1. Open your terminal and go to your Craft project:

    ```
     cd /path/to/project

    ```
2. Then tell Composer to load the plugin:

    ```
     composer require perfectus/perform

    ```
3. In the Control Panel, go to *Settings → Plugins* and click the “Install” button for PerForm.

PerForm works on Craft 3.x.

PerForm Usage Notes
-------------------

[](#perform-usage-notes)

### Issues

[](#issues)

Please report any issues you find to the [PerForm Issues](https://github.com/ohlincik/craft-perform/issues) page.

PerForm Overview
----------------

[](#perform-overview)

PerForm is built for **Craft CMS web developers** with ultimate flexibility in mind. The goal is to let you build the web form front-end anyway you'd like while following a handful of simple conventions. After you include the web form in your Twig template, the plugin will assist you with the following:

- Client-side form validation using [Parsley](http://parsleyjs.org/)
- Spam protection using the [Google Invisible ReCaptcha](https://developers.google.com/recaptcha/docs/invisible)
- Saving the form submissions in the Control Panel for future reference
- Delivering the form submission content via email (built-in testing using [Mailtrap](https://mailtrap.io/))

[![Screenshot](resources/screenshots/perform-control-panel-index-example.png)](resources/screenshots/perform-control-panel-index-example.png)

Using PerForm
-------------

[](#using-perform)

Using PerForm is quite simple. The following needs to be in place to get PerForm working properly.

1. PerForm **formTag** — to make sure that the form will be submitted to and processed by PerForm
2. Form built according to PerForm **form fields conventions** — to make sure that PerForm knows which fields need to be processed
3. PerForm **form settings** — to let PerForm know how to process the form submission
4. PerForm **plugin settings** — to configure additional options and connect PerForm with external services

Continue reading below to learn more about each concept. We're going to put together a simple form that collects *First Name*, *Last Name* and *Email* to illustrate how to build, setup and configure a form that will be processed by PerForm.

### PerForm `formTag`

[](#perform-formtag)

The `formTag` variable generates the opening `` tag. The form will not be processed without it.

```
{{ craft.perForm.formTag({
  'entryId': entry.id
}) }}
```

The `formTag` has one required configuration option **entryId** that specifies which entry contains the *Form Settings* for the form that will be included below. This will generate html code that looks something like this.

```

        #perform-submission {
            display: none;
        }

        You don't have JavaScript enabled.
        To continue, please
        enable JavaScript in your browser.

```

Note, that if you provide an incorrect **entryId** or have not setup the *Form Settings* associated with the provided **entryId** properly, you will see a message on the screen that looks like this.

[![Screenshot](resources/screenshots/perform-invalid-formtag-message.png)](resources/screenshots/perform-invalid-formtag-message.png)

### PerForm form fields conventions

[](#perform-form-fields-conventions)

PerForm is not concerned with how you decide to build your form, that's totally up to you. While you're building your form, you need to keep one important convention in mind. You need to let PerForm know what are the field lables and values that whould be processed and stored.

```
First Name

```

In the example above, PerForm will process and store the field for **First Name** textbox. You need to let PerForm know what is the field label and what is the field value:

- *Label:* use a hidden field ``
- *Value:* configure the input **name** to correspond with the hidden field for label `name="fields[firstName][value]"`

Note that in the example above, you can replace `firstName` with anything you'd like. In fact, you will need to provide a unique 'handle' for each field you want PerForm to process. Of course, you don't need to build the fields by hand (and you shouldn't). There are many ways to go about this, for example, you can use *Twig Macros*, *Twig Includes* or a combination of both.

### PerForm form settings

[](#perform-form-settings)

PerForm comes with a *Form Settings* field type that allows you to add a field to an entry that will include your form. You will need to create a field and add it to the layout of your entry (actually, this can be any entry, not specifically the entry that will include the template to generate your form). You will specify which entry includes the form settings through the [formTag variable](#perform-formtag).

[![Screenshot](resources/screenshots/perform-create-form-settings-field.png)](resources/screenshots/perform-create-form-settings-field.png)

Once you create the field and associate it with an entry layout, you can provide the appropriate settings for the particular form.

[![Screenshot](resources/screenshots/perform-form-settings.png)](resources/screenshots/perform-form-settings.png)

- **Form Title** — a user-friendly label to identify the form submissions that come from this form in the listing page in Control Panel.
- **Form Handle** — this setting is useful if you decide to provide different templates for different form and if you want to setup your own *email content templates*.
- **Form Subject** — what will be displayed on the form submissions listing in the Control Panel and used for the *Email Subject* of the email notification. The subject is processed by Twig so you can include the content of any field that appears in the form using the following format `{{ fieldHandle.value }}`.
- **Notification Recipients** — one or more email addresses that should receive the form submission notification after the form is submitted and processed.
- **Notification ReplyTo** — the form submission notification email is sent using the **System Email Address** configured in the *Control Panel → Settings → Email* so whenever the recipient clicks the 'Reply' button in their email client, the email reply would not go to whomever actually submitted the form. You can provide the email address of the actual person that submitted the form if you are collecting it through the form, in which case you just need to reference the value of the form field. For example, `{{ email.value }}` if the form input handle happens to be 'email'.
- **Test Mode Enabled** — when this setting is ON, the form submissions will be automatically set to **Test** status and delivered according to the *Test Email Delivery Settings* instead of the email addresses specified in the 'Notification Recipients'.

### PerForm plugin settings

[](#perform-plugin-settings)

[![Screenshot](resources/screenshots/perform-plugin-settings.png)](resources/screenshots/perform-plugin-settings.png)

- **Test Email Delivery Settings** — use the [Mailtrap](https://mailtrap.io) email testing service to test out the PerForm email notifications. Sign up for an account at Mailtrap and input the Inbox *Username* and *Password* in the provided fields.
- **Client Side Validation** — PerForm currently does not offer *Server-side form validation* but you can easily validate your form fields **before** the form is submitted. When you check this setting, PerForm will automatically include 'parsley.js' in each form. You will need to [configure your form inputs](http://parsleyjs.org/doc/index.html#validators) to work with Parsley.
- **Google Invisible reCAPTCHA Configuration** — when you turn on this setting, the Google Invisible reCAPTCHA will be automatically enabled for all PerForm driven forms within your site. You can [learn more](https://developers.google.com/recaptcha/docs/invisible) about how it works, but all you need to do is [create reCAPTCHA API keys](https://www.google.com/recaptcha/admin#list) for your site and PerForm will take care of everything else.
- **Custom Email Templates** — provide your own templates to generate the *email notifications*

Example: Simple Contact Form
----------------------------

[](#example-simple-contact-form)

This example will introduce you to how the [various concepts](#using-perform) fit together and will ultimately allow you to build much larger and more complex forms.

The following template code:

```
{% extends "_layouts/base" %}
{% block pageContent %}
  Contact Form

  {% if craft.app.request.getParam('success') == '✓' %}
    Thank you for submitting your information
  {% else %}
    {# Generate the PerForm form tag #}
    {{ craft.perForm.formTag({
      'entryId': entry.id
    }) }}

      {# First Name field #}
      First Name

      {# Last Name field #}
      Last Name

      {# Email field #}
      Email

      Submit

  {% endif %}
{% endblock %}
```

With the following Form Settings:

[![Screenshot](resources/screenshots/perform-simple-form-settings.png)](resources/screenshots/perform-simple-form-settings.png)

And, without any styling, will generate a very simple form.

[![Screenshot](resources/screenshots/perform-simple-form.png)](resources/screenshots/perform-simple-form.png)

By default, PerForm will redirect the browser to the **original url** and set a flash message with the **submissionId** key ([more details](#redirecting-after-submit) about redirecting and flash messages) which you can test for and display a "Thank You" message for the visitor. So, after filling out and submitting the form, the visitor will see this content in the browser:

[![Screenshot](resources/screenshots/perform-simple-form-success.png)](resources/screenshots/perform-simple-form-success.png)

The form submission will be processed by PerForm, saved in the Control Panel:

[![Screenshot](resources/screenshots/perform-control-panel-index.png)](resources/screenshots/perform-control-panel-index.png)

Where a user with the appropriate permissions can see the form submission detail:

[![Screenshot](resources/screenshots/perform-control-panel-detail.png)](resources/screenshots/perform-control-panel-detail.png)

And, the **notification recipient** receives the following email notification:

[![Screenshot](resources/screenshots/perform-simple-form-email-notification.png)](resources/screenshots/perform-simple-form-email-notification.png)

### Redirecting after submit

[](#redirecting-after-submit)

By default, PerForm will automatically reload the current page.

To override this default behavior, include `redirectInput` function after the PerForm `formTag` and specify your redirect destination.

```
{# Generate the PerForm form tag #}
{{ craft.perForm.formTag({
'entryId': entry.id
}) }}

{{ redirectInput('contact-form/thank-you') }}
```

Sometimes it's convenient to retrieve and display the information included in the form submission on the 'thank you' page. You can achieve this by setting query string parameters (although, there is a [much better way](#using-flash-messages)). The following variables can be used within the URL/path you set:

- `submissionId` — the ID of the Form Submission. You can use it to retrieve the entire submission content using the `getSubmissionById` plugin variable, however, for security reasons it is not advisable to expose the ID as a query string parameter. There is a [much better way](#using-flash-messages) to do this built into PerForm.
- `dateCreated` — the date/time when submission was created
- `dateUpdated` — the date/time when submission was last updated (same as `dateCreated` in this case)
- `statusType` — new, read, test *(note that since the submission was just submitted, it will be set to either 'new' or 'test' status)*
- `formHandle` — specified in the *Form Settings*
- `formTitle` — specified in the *Form Settings*
- `subject` — the subject generated using the **Form Subject** template specified in the *Form Settings*
- `replyTo` — the email address extracted based on the **Notification ReplyTo** template specified in the *Form Settings*
- `recipients` — one or more email addresses as specified in the **Notification Recipients** setting in the *Form Settings*. The values are returned as an *array*.
- `fields` — the fields included in the form and submitted to PerForm. The values are returned as an *array* and you can use the field handles to retrieve the submitted values and labels.

For example, if your form looks like this:

```
{{ redirectInput('contact-form/thank-you?replyTo={replyTo}&firstName={fields.firstName.value}') }}

{# First Name field #}

{# Last Name field #}

{# Email field #}

```

On your `contact-form/thank-you.html` template, you can access the parameters using the `craft.app.request.getQueryParam()`:

```

	{{ craft.app.request.getParam('firstName') }}, thank you for submitting your information.
	{% if craft.app.request.getParam('replyTo') is not empty %}

		We will use the {{ craft.app.request.getParam('replyTo') }} email address to send you a reply.
	{% endif %}

```

### Using flash messages

[](#using-flash-messages)

When a form submission is successfully processed, PerForm will set a flash message with the **submissionId** key and submission ID as value to indicate that the form submission was successful. In addition to checking whether the form was successfully processed, this also gives you the ability to retrieve the entire submission content using the `getSubmissionById` plugin variable. The advantage of using this method as opposed to [sending the submissionId as a query parameter](#redirecting-after-submit) is two-fold. First, the actual submission ID cannot be easily extracted from the response, and second, it is no longer available when the page is refreshed (making this approach work very well when redirecting to the same template that includes the form itself).

Using the example from above:

```
{{ redirectInput('contact-form/thank-you') }}

{# First Name field #}

{# Last Name field #}

{# Email field #}

```

On your `contact-form/thank-you.html` template, you can retrieve the **submissionId** from the session flash and use it to fetch the entire submission content using the `getSubmissionById` plugin variable (here is the [list of all submission variables](#redirecting-after-submit)):

```
{% if craft.app.session.hasFlash('submissionId') %}
	{% set submissionId = craft.app.session.getFlash('submissionId') %}
	{% set submission = craft.perForm.getSubmissionById(submissionId) %}

		{{ submission.fields.firstName.value }}, thank you for submitting your information.
        {% if submission.replyTo is not empty %}

            We will use the {{ submission.replyTo }} email address to send you a reply.
        {% endif %}

{% elseif craft.app.session.hasFlash('error') %}
    {{ craft.app.session.getFlash('error') }}
{% endif %}
```

As you can see in the example above, if a flash with the **submissionId** key has not been set, PerForm could not process the form submission and it is likely that an `error` flash message was set instead.

Example: Full-featured Complex Form
-----------------------------------

[](#example-full-featured-complex-form)

Content is coming soon...

PerForm Widget
--------------

[](#perform-widget)

You can enable the PerForm **dashboard widget** to keep track of the various form submissions.

[![Screenshot](resources/screenshots/perform-dashboard-widget.png)](resources/screenshots/perform-dashboard-widget.png)

PerForm Utility
---------------

[](#perform-utility)

The handy PerForm **utility** allows you to easily delete all the *Test Submissions* from the Control Panel.

[![Screenshot](resources/screenshots/perform-utility.png)](resources/screenshots/perform-utility.png)

Control Panel Permissions
-------------------------

[](#control-panel-permissions)

If you are using Craft CMS "Pro" edition, PerForm provides permissions that can be used to grant access to users based on their User Group. These are set in *Settings → Users → User Groups*.

#### Grant General Access to PerForm

[](#grant-general-access-to-perform)

[![Screenshot](resources/screenshots/perform-general-permissions.png)](resources/screenshots/perform-general-permissions.png)

With **General Access** to PerForm the users are able to:

- List, view, delete and change the status of all form submissions
- Add and utilize the *PerForm Dashboard Widget*

#### Grant Utilities Access to PerForm

[](#grant-utilities-access-to-perform)

[![Screenshot](resources/screenshots/perform-utilities-permissions.png)](resources/screenshots/perform-utilities-permissions.png)

With **Utilities Access** to PerForm the users are able to:

- Access the PerForm page under Craft CMS Utilities section and easily delete all test form submissions

PerForm Roadmap
---------------

[](#perform-roadmap)

Some things to do, and ideas for potential features:

- Process forms submitted through AJAX
- Add preview of form submission fields in **Test Mode**
- Add the option to send a *receipt* or *confirmation* after a form is submitted
- [Submit your new feature request](https://github.com/ohlincik/craft-perform/issues) if you need PerForm to do something specific that would be useful for other Craft developers...

Brought to you by [Perfectus Digital Solutions](https://perfectus.us)

###  Health Score

29

—

LowBetter than 60% of packages

Maintenance10

Infrequent updates — may be unmaintained

Popularity19

Limited adoption so far

Community7

Small or concentrated contributor base

Maturity65

Established project with proven stability

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~239 days

Total

4

Last Release

2020d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/9790ecd7c4c67c4d7fbfdb70f3d94407182b36070c15001c79e119e2f1d0cab5?d=identicon)[ohlincik](/maintainers/ohlincik)

---

Top Contributors

[![ohlincik](https://avatars.githubusercontent.com/u/1297647?v=4)](https://github.com/ohlincik "ohlincik (57 commits)")

---

Tags

craftcraft-plugincraft3craftcmscraftcms-pluginperfomwebformcmsCraftcraftcmscraft-pluginweb form

### Embed Badge

![Health badge](/badges/perfectus-perform/health.svg)

```
[![Health](https://phpackages.com/badges/perfectus-perform/health.svg)](https://phpackages.com/packages/perfectus-perform)
```

###  Alternatives

[nystudio107/craft-seomatic

SEOmatic facilitates modern SEO best practices &amp; implementation for Craft CMS 5. It is a turnkey SEO system that is comprehensive, powerful, and flexible.

1741.4M46](/packages/nystudio107-craft-seomatic)[verbb/image-resizer

Resize assets when they are uploaded.

127269.1k7](/packages/verbb-image-resizer)[elivz/vzurl

A URL fieldtype with validation.

4433.2k](/packages/elivz-vzurl)[verbb/tablemaker

Create customizable and user-defined table fields.

40168.8k1](/packages/verbb-tablemaker)[acclaro/translations

Easily launch and manage multilingual Craft websites without having to copy/paste content or manually track updates.

1229.5k](/packages/acclaro-translations)[verbb/footnotes

Adds a footnotes feature to CKEditor fields and Twig templates.

213.3k](/packages/verbb-footnotes)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
