Basic principle
The shop provides a set of predefined actions. They are defined by the system and cannot be named freely. Each action has a fixed name, for exampleBasketItemAdd (add a product to the basket), Login (log in user), or AccountRegister (create a new account).
Actions can be executed in three ways:
- Via a form — the most common case. The user fills out a form and submits it.
- Via a link — for actions without user input, for example logging out.
- Via AJAX — when the page should not be reloaded after execution.
Preparing actions
Before an action can be used in a template, a so-called action object must be created. You can think of it as a container that holds everything needed to execute the action and, after submission, also contains the shop’s response. The action object is created with $wsActions.create(), where the name of the desired action is passed:$myAction, for example with $myAction.success or $myAction.errors. A complete description of all available properties can be found in the $wsActions module reference.
| Property | Description |
|---|---|
$action.id | The ID of the action, which is required in the form so the shop knows what to execute. |
$action.csrf | A security token that protects every request (more on this here). |
$action.success | Is true when the action was executed successfully. |
$action.error | Is true when an error occurred. |
$action.errors | A list of all errors that occurred, with error code, affected field, and optional detail. |
$action.params | The most recently entered values. Useful for displaying a form pre-filled after an error so the user doesn’t have to re-enter everything. |
Executing actions
Execution via forms
The most common way to execute an action is via an HTML form. The prepared action object is embedded into the form, and the action is executed as soon as the user submits the form. The form is always sent to the URL of the current page so that the shop can rebuild the same page after execution and display the response:| Field | Value | Description |
|---|---|---|
wsact | {{= $action.id }} | Tells the shop which action should be executed. |
wscsrf | {{= $action.csrf }} | A security token to protect against unauthorized access (see INSERT LINK HERE). |
wstarget | e.g., {{= $wsViews.viewUrl('basket.htm') }} | The page the user is redirected to after successful execution. The redirect also prevents a page reload from resubmitting the form. |
Tags - distinguishing multiple forms of the same action type
If a page contains multiple forms of the same action type, for example an “Add to basket” button in each product box on a category page, all of these forms share the same response by default. This means: if an error occurs for one product, all forms on the page would display this error. A tag allows each action to be uniquely distinguished. The product ID, for example, is well-suited as a tag:BasketItemAdd:42 (where 42 would be the product ID in this example). This gives each product its own action object, and errors appear only on the affected form.
For some actions, particularly in the checkout, the tag is used to specify the address type directly in the action name:
Securing actions
Actions can be protected against unauthorized access in two ways — via a CSRF token, which is mandatory for every action, and optionally via a captcha.CSRF protection
CSRF (Cross-Site Request Forgery) refers to an attack in which an external website unnoticeably sends requests to the shop on behalf of a logged-in user, for example to trigger an order or change account data. CSRF protection prevents the shop from accepting such requests.
For this purpose, a one-time CSRF token is generated for each user session. Because the token is bound to the current session, an external website cannot know it and therefore cannot trigger the action unnoticed. The token is available directly on the action object and is embedded as follows:
Captcha protection
For certain actions, for example registration or a contact form, a captcha can additionally be enabled. A captcha is a security check that ensures the form is filled out by a real human and not by an automated bot. If captcha protection is active for an action, the action is only executed if the user has solved the captcha successfully. If the check fails, the action is not executed. For protection to take effect, two prerequisites are required:- The action must be entered under
security.actionGuardin the shop configuration for captcha protection. - The captcha widget must be included in the template of the corresponding form. More on this here.
If an action is executed via a confirmation link in an email (opt-in link), no captcha check takes place. In this case, the link itself serves as proof that a human has acted.
Execution via links
Actions without user input, for example logging out or removing an item from the basket, can be triggered via a link without the need for a form. For this purpose, a URL is generated with $wsActions.url(). The method expects three arguments: the action name, the target page after execution, and optional parameters as a list. If no optional parameters are needed, an empty list{} is passed:
Execution via AJAX
By default, the entire page is reloaded after a form is submitted. Sometimes this is not desired, however, for example when only a small area of the page should be updated without the user experiencing a visible reload. In such cases, the action can be executed via AJAX. The data is sent to the shop in the background and the response (success or error) is processed directly via JavaScript without reloading the page. CSRF protection is required just as for forms; the token can be retrieved via $wsActions.csrfToken. A typical use case:The user adds a product to the basket and only the basket counter in the header updates; the rest of the page remains unchanged.
Executing multiple actions simultaneously
Sometimes multiple actions should be executed in sequence with a single click on “Submit”. A typical example is the last step in the checkout, where the billing address and shipping address are confirmed and the order is completed. For this purpose, thewsmultiact field is used instead of the normal wsact field, once per action. wsact and wsmultiact cannot be combined in the same form.
The actions are executed in the order in which the wsmultiact fields are listed in the form.\
Assigning fields to an action
Because multiple actions in the same form accept fields, each field must be clearly assigned to a specific action. This is done by a prefix before the field name, separated by|. In the template it looks like this:
addressType with the value bill belongs to the action $commitBillAction.\
An action’s error should stop the next one
By default, all actions are executed, even if one of them fails. If a failed action should abort the subsequent one, the parameterwsmultiactabortonerror can be set to on:
Ignoring an action’s error
Withwsmultiactignoreerror, individual actions can be marked as non-critical. If an action marked this way fails, this is not treated as a fatal error. The parameter can be specified multiple times, once per action:
- Redirect despite error
By default, the user remains on the current page in case of an error and is not redirected to the target page specified inwstarget. If the failed action is marked viawsmultiactignoreerror, the redirect still takes place. - Subsequent actions continue running
Ifwsmultiactabortonerror=onis also set, an error would normally abort all subsequent actions. Actions marked viawsmultiactignoreerrordo not trigger this abort — execution continues.
The following example shows the last step of a checkout. With a click on “Order now”, three actions are executed in sequence:
CheckoutCommitDraftAddress:bill- apply the billing addressCheckoutCommitDraftAddress:shipping- apply the shipping addressCheckoutConfirm- complete the order
Result of execution
Success
If the action was successful,$myAction.success equals true. In this case, a success message can be displayed or the user can be redirected to another page via wstarget.
Error
If the action fails, for example because a required field is missing or an email address is invalid,$myAction.error equals true. The error messages should be output in the template so the user knows what needs to be corrected:
