{form 'contact'} writes a <form method="post"> round its content that posts back to the page it stands in. A posting form carries two hidden fields: the visitor's CSRF token (padCsrfToken, the session starts on demand) and its own name (padForm). In the page's PHP, padPosted('contact') is TRUE when this form came back, so a page with two forms knows which one was sent. A form with method='get' carries neither - its fields end up in the address.

Every item besides the name, method, error and client is an attribute of the <form> tag - class=, id=, action=, enctype= - written the way {attrs} writes them. The token only goes to this site: a form whose action=, or the formaction= of a button in it, points to another site gets none. A posting form holding a file field gets enctype="multipart/form-data" unless it names one itself.

Fields that refill

The {input} and {textarea} fields inside know which form they are in. When that form came back they show what was sent, escaped, and the message padValidate left for them - a field of the same name in another form of the page stays as it was. A GET form refills from the query string once it holds more than the page's name. With error= a form that came back with errors starts with <div class="error" role="alert"> holding the message; error alone says "Please correct the errors below."

Rules in the template

The fields of a named form can carry their own rules: rules='required|email'. They are read from the page's own text before any PHP runs and a post of the form is checked against them there, so padPosted('contact') is TRUE only for a post that kept them, and padFormFailed('contact') for one that broke them - that one renders the form again, refilled, with the messages. Only the page's own template (with its _inits.pad and _exits.pad) is read: rules in a snippet, a custom tag, a {page} or a layout, rules from a variable, rules in a GET form or one with action=, and an unknown rule are errors, strict check or not - each would be a check that never runs. That is also why the examples with rules on this page are shown, not run: they are rendered here through {page}.

client checks the same rules in the browser as well, with the same messages, before the form leaves: the form gets novalidate, its rules in data-pad-rules, and the checker script (see {validator}) follows it once a page. A form with client needs a name and at least one field with rules. The pair must close - a lone {form} is an error under the strict check.