User modules

This article is machine translated.

User modules are modules that are used in connection with the administration of frontend users. This includes, for example, the registration of new members or the login/logout of existing members.

Login form

The front-end module “Login Form” adds a form to the website, with which registered members can authenticate themselves.

Frontend output

As soon as a frontend user is logged on, a logoff button is automatically displayed instead of the logon form.

Frontend output

So when formatting CSS, consider both states of the module, and also remember that an error message may be output.

Allow Autologin: If you select this option, members can remain logged in if they wish. If a user session expires, Contao will automatically create a new session without requiring you to enter the password again.

Forwarding page: Here you can define to which page a member will be forwarded after successful registration. You can override this setting per user group to set up a group-specific redirection.

Go to last visited page: If you select this option, the frontend user will be redirected to the last visited page instead of the redirection page.

Individual template: Here you can overwrite the standard mod_login template.

HTML output
The frontend module generates the following HTML code:

<!-- indexer::stop -->
<div class="mod_login login block">

    <form action="/_contao/login" id="tl_login" method="post">
        <div class="formbody">
            <input type="hidden" name="FORM_SUBMIT" value="tl_login">
            <input type="hidden" name="REQUEST_TOKEN" value="…">
            <input type="hidden" name="_target_path" value="…">
            <input type="hidden" name="_failure_path" value="…">
            <input type="hidden" name="_always_use_target_path" value="0">
            <div class="widget widget-text">
                <label for="username">Username</label>
                <input type="text" name="username" id="username" class="text" value="" required>
            </div>
            <div class="widget widget-password">
                <label for="password">Password</label>
                <input type="password" name="password" id="password" class="text password" value="" required>
            </div>
            <div class="widget widget-checkbox">
                <fieldset class="checkbox_container">
                    <span>
                        <input type="checkbox" name="autologin" id="autologin" value="1" class="checkbox"> 
                        <label for="autologin">Remember me</label>
                    </span>
                </fieldset>
            </div>
            <div class="widget widget-submit">
                <button type="submit" class="submit">Login</button>
            </div>
        </div>
    </form>

</div>
<!-- indexer::continue -->

After a member has logged in, the HTML code changes as follows:

<!-- indexer::stop -->
<div class="mod_login logout block">

    <form action="/_contao/logout" id="tl_logout" method="post">
        <div class="formbody">
            <input type="hidden" name="FORM_SUBMIT" value="tl_logout">
            <input type="hidden" name="REQUEST_TOKEN" value="…">
            <input type="hidden" name="_target_path" value="…">
            <p class="login_info">
                You are logged in as j.smith.<br>Your previous login was 2015-11-15 20:54. Welcome back!
            </p>
            <div class="widget widget-submit">
                <button type="submit" class="submit">Logout</button>
            </div>
        </div>
    </form>

</div>
<!-- indexer::continue -->

Automatic Logout

The frontend module “Automatic Logout” adds an invisible module to the website that automatically logs off a logged in front-end user.

As soon as a member has logged in to the frontend of the website, a logout link appears in the main menu on the right hand side, with which the member can log out again. In reality, these are two different pages in the page structure, which contain the login and the logout module.

Forwarding page: Here you can define to which page a frontend user will be forwarded after logging out.

Go to last visited page: If you select this option, the member will be redirected to the last page visited instead of the redirection page.

The module does not generate HTML output.

Personal information

The frontend module “personal data” adds a form to the website, which allows a member to change his personal data such as his e-mail address or password. As an administrator, you can define exactly which fields can be edited and which cannot.

Frontend output member_default

Frontend output member_grouped

Personal data
Contact details
Login details

Editable fields: Here you can define the editable fields.

Set editable fields

Subscribable newsletters: If you are using the Contao newsletter extension, you can define here which distribution lists a member can subscribe to.

Forwarding page: Here you can choose to which page a member is forwarded to after submitting the changes.

Form template: Here you select the template of the form.

Template Explanation
member_default The editable fields are listed below each other.
member_grouped The input fields are grouped using field sets.

HTML Output
The frontend module generated using the member_default following HTML code:

<!-- indexer::stop -->
<div class="mod_personalData block">

    <form action="…" id="tl_member" method="post" enctype="application/x-www-form-urlencoded">
        <div class="formbody">
            <input type="hidden" name="FORM_SUBMIT" value="tl_member">
            <input type="hidden" name="REQUEST_TOKEN" value="…">
            <div class="fields">
                <div class="widget widget-text">
                    <label for="ctrl_firstname">
                        <span class="invisible">Mandatory field </span>First name<span class="mandatory">*</span>
                    </label>
                    <input type="text" name="firstname" id="ctrl_firstname" class="text" value="John" required maxlength="255">
                </div>
                <div class="widget widget-text">
                    <label for="ctrl_lastname">
                        <span class="invisible">Mandatory field </span>Last Name<span class="mandatory">*</span>
                    </label>
                    <input type="text" name="lastname" id="ctrl_lastname" class="text" value="Smith" required maxlength="255">
                </div>
                <div class="widget widget-text">
                    <label for="ctrl_email">
                        <span class="invisible">Mandatory field </span>E-mail address<span class="mandatory">*</span>
                    </label>
                    <input type="email" name="email" id="ctrl_email" class="text" value="j.smith@example.com" required maxlength="255">
                </div>
                <div class="widget widget-password">
                    <label for="ctrl_password">Password</label>
                    <input type="password" name="password" id="ctrl_password" class="text password" value="">
                </div>
                <div class="widget widget-password confirm">
                    <label for="ctrl_password_confirm" class="confirm">Confirmation</label>
                    <input type="password" name="password_confirm" id="ctrl_password_confirm" class="text password" value="">
                </div>
            </div>
            <div class="widget widget-submit">
                <button type="submit" class="submit">Save data</button>
            </div>
        </div>
    </form>

</div>
<!-- indexer::continue -->

The frontend module generates with the member_grouped following HTML code:

<!-- indexer::stop -->
<div class="mod_personalData block">

    <form action="…" id="tl_member" method="post" enctype="application/x-www-form-urlencoded">
        <div class="formbody">
            <input type="hidden" name="FORM_SUBMIT" value="tl_member">
            <input type="hidden" name="REQUEST_TOKEN" value="…">

            <fieldset>
                <legend>Personal data</legend>
                <div class="widget widget-text">
                    <label for="ctrl_firstname">
                        <span class="invisible">Mandatory field </span>First name<span class="mandatory">*</span>
                    </label>
                    <input type="text" name="firstname" id="ctrl_firstname" class="text" value="John" required maxlength="255">
                </div>
                <div class="widget widget-text">
                    <label for="ctrl_lastname">
                        <span class="invisible">Mandatory field </span>Last Name<span class="mandatory">*</span>
                    </label>
                    <input type="text" name="lastname" id="ctrl_lastname" class="text" value="Smith" required maxlength="255">
                </div>
            </fieldset>

            <fieldset>
                <legend>Contact details</legend>
                <div class="widget widget-text">
                    <label for="ctrl_email">
                        <span class="invisible">Mandatory field </span>E-mail address<span class="mandatory">*</span>
                    </label>
                    <input type="email" name="email" id="ctrl_email" class="text" value="j.smith@example.com" required maxlength="255">
                </div>
            </fieldset>

            <fieldset>
                <legend>Login details</legend>          
                <div class="widget widget-password">
                    <label for="ctrl_password">Password</label>
                    <input type="password" name="password" id="ctrl_password" class="text password" value="">
                </div>
                <div class="widget widget-password confirm">
                    <label for="ctrl_password__confirm" class="confirm">Confirmation</label>
                    <input type="password" name="password_confirm" id="ctrl_password_confirm" class="text password" value="">
                </div>
            </fieldset>

            <div class="widget widget-submit">
                <button type="submit" class="submit">Save data</button>
            </div>
        </div>
    </form>

</div>
<!-- indexer::continue -->

Member registration

The frontend module “Member registration” adds a form to the website, with which new members can register and, depending on the configuration, automatically receive a user account for the protected area.

Frontend output member_default

Frontend output member_grouped

Personal data
Contact details
Login details

Subscribable newsletters: If you are using the Contao newsletter extension, you can define here which distribution lists a member can subscribe to.

Disable spam protection: Here you can disable the spam protection (not recommended). Since Contao 4.4, this question is only “displayed” to spambots. Without a security question it is possible that spammers automatically create user accounts and abuse your website.

Member groups: Here you define the group membership of the new member.

Allow login: If you select this option, a new member can log in after registering in the frontend login. For this to work, the registration form must contain the fields username and password.

Create a user directory: If you select this option, a new user directory is automatically created in a folder of your choice during registration. The name of the new directory will be generated from the username.

Forwarding page: Here you can define to which page a member will be forwarded after registration (e.g. to the page with the login form).

Automation of member registration

You can fully automate the registration process if you wish. A new member will then receive an e-mail with a confirmation link when registering, with which they can activate their account independently.

Send activation email: Here you can switch on the automatic activation.

Confirmation page: Here you can define to which page a user is redirected after successful activation of his account (e.g. the login page).

Activation mail: Enter the text of the activation mail here. You can use placeholders in the format ##key## for all input fields of the registration form as well as the placeholders ##domain## for the domain and ##link## for the confirmation link.

Below is a short example:

Dear ##firstname## ##lastname##,

Thank you very much for your registration on ##domain##.

Please click on the link to complete your registration and activate your account:

##link##

The confirmation link is valid for 24 hours.

If you have not requested access, please ignore this email.

Your administrator

Form template: Here you select the template of the form.

Template Declaration
member_default The input fields are listed one below the other.
member_grouped The input fields are grouped using field sets.

HTML Output
The frontend module generates with the member_default following HTML code:

<!-- indexer::stop -->
<div class="mod_registration block">

    <form action="…" id="tl_registration" method="post" enctype="application/x-www-form-urlencoded">
        <div class="formbody">
            <input type="hidden" name="FORM_SUBMIT" value="tl_registration">
            <input type="hidden" name="REQUEST_TOKEN" value="…">
            <div class="fields">
                <div class="widget widget-text mandatory">
                    <label for="ctrl_firstname" class="mandatory">
                        <span class="invisible">Mandatory field </span>First name<span class="mandatory">*</span>
                    </label>
                    <input type="text" name="firstname" id="ctrl_firstname" class="text mandatory" value="" required maxlength="255">
                </div>
                <div class="widget widget-text mandatory">
                    <label for="ctrl_lastname" class="mandatory">
                        <span class="invisible">Mandatory field </span>Last Name<span class="mandatory">*</span>
                    </label>
                    <input type="text" name="lastname" id="ctrl_lastname" class="text mandatory" value="" required maxlength="255">
                </div>
                <div class="widget widget-text mandatory">
                    <label for="ctrl_email" class="mandatory">
                        <span class="invisible">Mandatory field </span>E-mail address<span class="mandatory">*</span>
                    </label>
                    <input type="email" name="email" id="ctrl_email" class="text mandatory" value="" required maxlength="255">
                </div>
                <div class="widget widget-text mandatory">
                    <label for="ctrl_username" class="mandatory">
                        <span class="invisible">Mandatory field </span>Username<span class="mandatory">*</span>
                    </label>
                    <input type="text" name="username" id="ctrl_username" class="text mandatory" value="" required maxlength="64">
                </div>
                <div class="widget widget-password mandatory">
                    <label for="ctrl_password" class="mandatory">
                        <span class="invisible">Mandatory field </span>Password<span class="mandatory">*</span>
                    </label>
                    <input type="password" name="password" id="ctrl_password" class="text password mandatory" value="" required>
                </div>
                <div class="widget widget-password confirm mandatory">
                    <label for="ctrl_password_confirm" class="confirm mandatory">
                        <span class="invisible">Mandatory field </span>Confirmation<span class="mandatory">*</span>
                    </label>
                    <input type="password" name="password_confirm" id="ctrl_password_confirm" class="text password mandatory" value="" required>
                </div>
            </div>
            <div class="widget widget-submit">
                <button type="submit" class="submit">Register</button>
            </div>
        </div>
    </form>

</div>
<!-- indexer::continue -->

The frontend module generates using the member_grouped following HTML code:

<!-- indexer::stop -->
<div class="mod_registration block">

    <form action="…" id="tl_registration" method="post" enctype="application/x-www-form-urlencoded">
        <div class="formbody">
            <input type="hidden" name="FORM_SUBMIT" value="tl_registration">
            <input type="hidden" name="REQUEST_TOKEN" value="…">

            <fieldset>
                <legend>Personal data</legend>              
                <div class="widget widget-text mandatory">
                    <label for="ctrl_firstname" class="mandatory">
                        <span class="invisible">Mandatory field </span>First name<span class="mandatory">*</span>
                    </label>
                    <input type="text" name="firstname" id="ctrl_firstname" class="text mandatory" value="" required maxlength="255">
                </div>
                <div class="widget widget-text mandatory">
                    <label for="ctrl_lastname" class="mandatory">
                        <span class="invisible">Mandatory field </span>Last Name<span class="mandatory">*</span>
                    </label>
                    <input type="text" name="lastname" id="ctrl_lastname" class="text mandatory" value="" required maxlength="255">
                </div>
            </fieldset>

            <fieldset>
                <legend>Contact details</legend>
                <div class="widget widget-text mandatory">
                    <label for="ctrl_email" class="mandatory">
                        <span class="invisible">Mandatory field </span>E-mail address<span class="mandatory">*</span>
                    </label>
                    <input type="email" name="email" id="ctrl_email" class="text mandatory" value="" required maxlength="255">
                </div>
             </fieldset>

             <fieldset>
                <legend>Login details</legend>
                <div class="widget widget-text mandatory">
                    <label for="ctrl_username" class="mandatory">
                        <span class="invisible">Mandatory field </span>Username<span class="mandatory">*</span>
                    </label>
                    <input type="text" name="username" id="ctrl_username" class="text mandatory" value="" required maxlength="64">
                </div>
                <div class="widget widget-password mandatory">
                    <label for="ctrl_password" class="mandatory">
                        <span class="invisible">Mandatory field </span>Password<span class="mandatory">*</span>
                    </label>
                    <input type="password" name="password" id="ctrl_password" class="text password mandatory" value="" required>
                </div>
                <div class="widget widget-password confirm mandatory">
                    <label for="ctrl_password_confirm" class="confirm mandatory">
                        <span class="invisible">Mandatory field </span>Confirmation<span class="mandatory">*</span>
                    </label>
                    <input type="password" name="password_confirm" id="ctrl_password_confirm" class="text password mandatory" value="" required>
                </div>
             </fieldset>

            <div class="widget widget-submit">
                <button type="submit" class="submit">Register</button>
            </div>
        </div>
    </form>

</div>
<!-- indexer::continue -->

Change Password

The frontend module “Change Password” adds a form to the website that allows a logged in frontend user to change his password.

Frontend output

Forwarding page: Here you can select to which page a member will be forwarded after submitting the changes.

Individual template: Here you can overwrite the default mod_changePassword template.

HTML output
The frontend module generates the following HTML code:

<!-- indexer::stop -->
<div class="mod_changePassword block">

    <form action="…" id="tl_change_password" method="post">
        <div class="formbody">
            <input type="hidden" name="FORM_SUBMIT" value="tl_change_password">
            <input type="hidden" name="REQUEST_TOKEN" value="…">
            <div class="fields">
                <div class="widget widget-text mandatory">
                    <label for="ctrl_oldpassword" class="mandatory">
                        <span class="invisible">Mandatory field </span>Old password<span class="mandatory">*</span>
                    </label>
                    <input type="password" name="oldpassword" id="ctrl_oldpassword" class="text password mandatory" value="" required>
                </div>
                <div class="widget widget-password mandatory">
                    <label for="ctrl_password" class="mandatory">
                        <span class="invisible">Mandatory field </span>New password<span class="mandatory">*</span>
                    </label>
                    <input type="password" name="password" id="ctrl_password" class="text password mandatory" value="" required>
                </div>
                <div class="widget widget-password confirm mandatory">
                    <label for="ctrl_password_confirm" class="confirm mandatory">
                        <span class="invisible">Mandatory field </span>Confirmation<span class="mandatory">*</span>
                    </label>
                    <input type="password" name="password_confirm" id="ctrl_password_confirm" class="text password mandatory" value="" required>
                </div>
            </div>
            <div class="widget widget-submit">
                <button type="submit" class="submit">Change password</button>
            </div>
        </div>
    </form>

</div>
<!-- indexer::continue -->

Forgot your password?

The front-end module “Forgot your password” adds a form to the website that a member can use to request a new password. Contao sends an automatic email with a confirmation link to the email address stored in the user account. Only after clicking on this confirmation link is it possible to enter a new password.

Frontend output

Do not query username: If you select this option, the username will not be queried when you request it.

Disable spam protection: Here you can disable the spam protection (not recommended). Since Contao 4.4, this question is only “displayed” to spambots. Without a security question it is possible that spammers automatically create user accounts and abuse your website.

Forwarding page: Here you can define to which page a user is forwarded after requesting a new password.

Confirmation page: Here you can define to which page a user will be redirected after a new password has been successfully created.

Confirmation mail: Enter the text of the confirmation mail here. You can use placeholders in the format ##key## for all user properties as well as the placeholders ##domain## for the current domain and ##link## for the confirmation link.

For example, a confirmation mail could look like this:

Dear ##firstname## ##lastname##,

You have requested a new password for ##domain##.

Please click on the link to set the new password:

##link##

If you have not requested this email, please contact the website administrator.

Your administrator

Individual template: Here you can overwrite the default mod_lostPassword template.

HTML output
The frontend module generates the following HTML code:

<!-- indexer::stop -->
<div class="mod_lostPassword block">

    <form action="…" id="tl_lost_password" method="post">
        <div class="formbody">
        <input type="hidden" name="FORM_SUBMIT" value="tl_lost_password">
        <input type="hidden" name="REQUEST_TOKEN" value="…">
            <div class="fields">
                <div class="widget widget-text mandatory">
                    <label for="ctrl_username" class="mandatory">
                        <span class="invisible">Mandatory field </span>Username<span class="mandatory">*</span>
                    </label>
                    <input type="text" name="username" id="ctrl_username" class="text mandatory" value="" required maxlength="64">
                </div>
                <div class="widget widget-text mandatory">
                    <label for="ctrl_email" class="mandatory">
                        <span class="invisible">Mandatory field </span>E-mail address<span class="mandatory">*</span>
                    </label>
                    <input type="email" name="email" id="ctrl_email" class="text mandatory" value="" required maxlength="255">
                </div>
            </div>
            <div class="widget widget-submit">
                <button type="submit" class="submit">Request a new password</button>
            </div>
        </div>
    </form>

</div>
<!-- indexer::continue -->

Close account

The frontend module “Close Account” adds a form to the website, which a member can use to close his account. Depending on the configuration, the account is either deactivated or completely deleted from the database.

Frontend output

Mode: Here you can specify whether the account should be deactivated or completely deleted from the database when the form is submitted.

Forwarding page: Here you define to which page a member will be forwarded after account closure. The target page must not be protected.

Individual template: Here you can overwrite the default mod_closeAccount template.

HTML Output
The frontend module generates the following HTML code:

<!-- indexer::stop -->
<div class="mod_closeAccount block">

    <form action="…" id="tl_close_account" method="post">
        <div class="formbody">
            <input type="hidden" name="FORM_SUBMIT" value="tl_close_account">
            <input type="hidden" name="REQUEST_TOKEN" value="…">
            <div class="fields">
                <div class="widget widget-text mandatory">
                    <label for="ctrl_password" class="mandatory">
                        <span class="invisible">Mandatory field </span>Password<span class="mandatory">*</span>
                    </label>
                    <input type="password" name="password" id="ctrl_password" class="text password mandatory" value="" required>
                </div>
            </div>
            <div class="widget widget-submit">
                <button type="submit" class="submit">Close account</button>
            </div>
        </div>
    </form>

</div>
<!-- indexer::continue -->

Two-Factor Authentication

This feature is only available in Contao 4.8 and later.

The “Two-Factor Authentication” front-end module adds a form to the website that a member can use to enable two-factor authentication. If the two-factor authentication for members is forced, this module must be used on the page structure described in Further settings at start points can be added to the selected two-factor forwarding page.

Frontend output

Please enable two-factor authentication before you proceed.

Please scan the QR Code with your 2FA/TOTP app.

If you cannot scan the QR code, enter this key instead:

YEXTWQFNZ5DJPZH7QTUN5U3WHBKIFAZG2O6VWYCUO7MRZENQTUVILUFRI23S6EIXCJ7PHT2L47QXY36SIQUUGR6A3ZP6VUMSHDED4KBYKAZCZJ5Q36AH6NRYELROIZL4EAZHBZLTPQ5HSW3ZSOTUH6IZWOBR7H5X4RHOTEHYVFKJ6THZB7XT3OREBEW5S5JET3TNOZIDBGJOI

Please enter the confirmation code generated by your 2FA/TOTP app.

Individual template: Here you can overwrite the standard mod_two_factortemplate.

HTML Output
The frontend module generates the following HTML code:

<!-- indexer::stop -->
<div class="mod_two_factor two-factor block">

    <p class="error">Bitte aktivieren Sie die Zwei-Faktor-Authentifizierung bevor Sie fortfahren.</p>
    <p>Bitte scannen Sie den QR-Code mit Ihrer 2FA/TOTP-App.</p>

    <form action="" class="tl_two_factor_form" method="post">
        <div class="formbody">
            <input type="hidden" name="FORM_SUBMIT" value="tl_two_factor">
            <input type="hidden" name="REQUEST_TOKEN" value="_">
            <div class="qr-code">
                <img src="data:image/svg+xml;base64,…" alt>
            </div>
            <div class="widget">
                <p>If you cannot scan the QR code, enter this key instead:</p>
                …
            </div>
            <div class="widget widget-text">
                <label for="verify">Confirmation code</label>
                <input type="text" name="verify" id="verify" class="text" value="" autocapitalize="off" autocomplete="off" required>
                <p class="help">Please enter the confirmation code generated by your 2FA/TOTP app.</p>
            </div>
            <div class="submit_container">
                <button type="submit" class="tl_submit">Activate</button>
            </div>
        </div>
    </form>

</div>
<!-- indexer::continue -->