Page tree
Skip to end of metadata
Go to start of metadata

Introduction

This tutorial creates server-wide custom login pages for the cPanel, WHM, or Webmail interfaces. For more information about cPanel & WHM's login theme, read our Guide to cPanel Interface Customization - The Login Theme documentation.

Notes:

  • Throughout this document, themename represents the name of your custom theme. 
  • You cannot modify login pages for individual cPanel accounts.
  • Resellers cannot create their own custom login pages.

Create custom-branded login pages


Duplicate the existing login theme.

To duplicate the existing login theme, perform the following steps:

  1. Navigate to WHM's Theme Manager interface (Main >> Themes >> Theme Manager).

    Note:

    In cPanel & WHM version 11.48 and earlier, navigate to WHM's Universal Theme Manager interface (Home >> Themes >> Universal Theme Manager).

  2. Click Manage Themes under Login.
  3. Click Clone next to the theme that you wish to duplicate.
  4. Enter a name for the duplicate theme in the available text box and click Submit.

WHM saves your new theme in the /usr/local/cpanel/base/unprotected/themename/ directory, where themename represents the name that you entered.

 


 

Modify the login page subheader logos.

Replace any or all of the subheader images in the /usr/local/cpanel/base/unprotected/themename/images/ directory.

  • Subheader images appear at the top of the login pages for cPanel, WHM, and Webmail.
  • Make certain that your replacement images use the correct dimensions in order to allow for the appropriate amount of padding within the login subheader containers.

The default cPanel & WHM login theme contains the following subheader logo images:

Image locationDescriptionHeightWidthDefault theme image
images/cpanel-logo.png
The cPanel subheader.50233
images/whm.png The WHM subheader.55208
images/whm-white.png The WHM subheader for non-white backgrounds.55208
images/webmail.png The Webmail subheader.50306

Notes:

  • These images appear in the default login theme for the most recent version of cPanel & WHM. If you use an older version of cPanel & WHM, check the images in your default login theme to ensure that you use the correct image dimensions. 
  • For more information about login theme images, read our Guide to cPanel Interface Customization - Login Images documentation.

 


 

Modify other login page images.

Replace any or all of the other login theme images in the /usr/local/cpanel/base/unprotected/themename/images/ directory.

The default cPanel & WHM login theme contains the following additional images:

Image locationDescriptionHeightWidthDefault theme image
images/cpanel-logo-tiny.png The cPanel logo at the bottom of the login pages.2525
images/cpanel-logo-tiny-white.png The cPanel logo at the bottom of login pages, for non-white backgrounds.2525
images/icon-password.png The icon that appears in the password text box.2020
images/icon-username.png The icon that appears in the username text box.2020
images/locale-map.png The image that displays for the list of available locales.220455
images/login-error-close.png

The icon that allows users to close any messages that the system receives.

1212
images/notice-error.png The image that appears on the page whenever an error is encountered.2828

images/notice-info.png The image that appears whenever the system needs to display additional information.2828

images/notice-success.png The image that appears whenever the user successfully logs in or resets their password.2828

images/security-policy-error.png The image that appears whenever an error occurs on a security policy page.2121
images/security-policy-success.png The image that appears in order to indicate success on a security policy page.2121
images/warning.png

The image that appears whenever the system raises a warning.

2828

Notes:

  • These images appear in the default login theme for the most recent version of cPanel & WHM. If you use an older version of cPanel & WHM, check the images in your default login theme to ensure that you use the correct image dimensions. 
  • For more information about login theme images, read our Guide to cPanel Interface Customization - Login Images documentation.

 


 

Modify the login page templates.

Make the desired changes to your custom theme's other login page templates. Login themes include the main templates that all users view when they log in, error page templates, and templates for the Reset Password feature.

  • These template files control what users see when they log in, encounter login errors, or reset their passwords.
  • Advanced users can modify the main.tmpl and resetpass.tmpl files to change how the system processes user input.

The default cPanel & WHM login theme contains the following template files:

templates/_error_wrapper.tmpl

The system accesses this wrapper template whenever the user encounters an error.

Template variables

This template does not use template variables.

Default template example

[%
SET app_images = {
    'whostmgrd' => 'whm-white.png',
    'webmaild'  => 'webmail.png',
    'cpaneld'   => 'cpanel-logo.png',
};
SET app_image = app_images.$app_name || app_images.cpaneld;
SET app_image = MagicRevision(get_theme_url("images/$app_image"));
%]
<p class="logo"><img src="[% app_image %]" alt="logo"></p>
<div class="error_notice">
    <div id="error-wrapper">
        <div id="error_msg_contents">
            <h2>[% locale.maketext('HTTP error [_1]',http_status_code) %]</h2>
[% content %]
        </div>
    </div>
</div>

templates/access_denied.tmpl

The system accesses this template whenever the server responds with an Access Denied error. This error occurs whenever a user attempts to log in with an invalid username or password.

Template variables

VariableTypeDescription
dest_uristringThe URL to load after a user authenticates. This URL does not contain the security token.
error_msgstringThe error message to display.
form_refhashA hash of the form variables to pass with the request. The system sends this hash to the location that the redirect_uri variable specifies.
parameterized_formhashA hash of form variables that the user provided as a URL query string.
themestringThe theme to load.
userstringThe username to authenticate.

Default template example

[% WRAPPER 'templates/_error_wrapper' -%]
    <h2>[% uri FILTER html %]</h2>
    <p>[% locale.maketext('You do not have permission to access this page.') %]</p>
    [% IF page_message %]
      <blockquote>[% locale.makevar(page_message) %]</blockquote>
    [% END %]
[% END -%]

templates/error502.tmpl

The system accesses this template whenever the server responds with a 502 (server) error.

Template variables

VariableTypeDescription
dest_uristringThe URL to load after a user authenticates. This URL does not contain the security token.
error_msgstringThe error message to display.
form_refhashA hash of the form variables to pass with the request. The system sends this hash to the location that the redirect_uri variable specifies.
parameterized_formhashA hash of form variables that the user provided as a URL query string.
themestringThe theme to load.
userstringThe username to authenticate.

Default template example

[% WRAPPER 'templates/_error_wrapper' -%]
    <p>[% locale.maketext('The server received a bad response while acting as a proxy.') %]</p>
[% END -%]

templates/error503.tmpl

The system accesses this template whenever the server responds with a HTTP status 503.

Note:

The system displays HTTP status 503 when the requested service is unavailable.

 

Template variables

VariableTypeDescription
dest_uristringThe URL to load after a user authenticates. This URL does not contain the security token.
error_msgstringThe error message to display.
form_refhashA hash of the form variables to pass with the request. The system sends this hash to the location that the redirect_uri variable specifies.
page_messagestringThe optional message provides more details about why the service is unavailable.
parameterized_formhashA hash of form variables that the user provided as a URL query string.
themestringThe theme to load.
userstringThe username to authenticate.
[% WRAPPER 'templates/_error_wrapper' -%]
    <h2>[% locale.maketext('The service is unavailable.') %]</h2>
    [% IF page_message%]<p>[% page_message FILTER html %]</p>[%END%]
[% END -%]

templates/fourohfour.tmpl

The system accesses this template whenever the server responds with a HTTP 404 (page not found) error.

Template variables

VariableTypeDescription
dest_uristringThe URL to load after a user authenticates. This URL does not contain the security token.
error_msgstringThe error message to display.
form_refhashA hash of the form variables to pass with the request. The system sends this hash to the location that the redirect_uri variable specifies.
parameterized_formhashA hash of form variables that the user provided as a URL query string.
themestringThe theme to load.
userstringThe username to authenticate.

Default template example

[% WRAPPER 'templates/_error_wrapper' -%]
    <p>[% locale.maketext('The requested page was not found.') %]</p>
    <h2>[% locale.maketext('Possible reasons why you are seeing this page:') %]</h2>
    <ul>
        <li>[% locale.maketext('A bookmarked URL may have changed since you last visited.') %]</li>
        <li>[% locale.maketext('The URL was entered incorrectly.') %]</li>
        <li>[% locale.maketext('The URL was entered with inaccurate capitalization (URLs are [output,url,_1,case sensitive]).','http://wikipedia.org/wiki/Case_sensitivity') %]</li>
    </ul>
    <p>[% locale.maketext('Please re-check the URL you are trying to reach. ([output,url,_1,Go Back])', 'javascript:history.back()' ) %]</p>
[% END -%]

templates/generic_error.tmpl

The system accesses this template whenever the server responds with a generic error.

Template variables

VariableTypeDescription
dest_uristringThe URL to load after a user authenticates. This URL does not contain the security token.
error_msgstringThe error message to display.
form_refhashA hash of the form variables to pass with the request. The system sends this hash to the location that the redirect_uri variable specifies.
parameterized_formhashA hash of form variables that the user provided as a URL query string.
themestringThe theme to load.
userstringThe username to authenticate.

Default template example

[% WRAPPER 'templates/_error_wrapper' -%]
    <h2>[% uri FILTER html %]</h2>
    <p>[% generic_error FILTER html %]</p>
[% END -%]

templates/login.tmpl

This template determines the appearance of the first login page that users see when they attempt to log in to cPanel, WHM, or Webmail.

Template variables

VariableTypeDescription
dest_uristringThe URL to load after a user authenticates. This URL does not contain the security token.
msg_codestringThe key that corresponds to the login_messages value. This message displays on the loading page, after the user authenticates.

Default template example

[%
SET disp_apps = {
    'whostmgrd' => 'WHM',
    'webmaild' => 'Webmail',
    'cpaneld' => 'cPanel',
};
SET disp_app  = disp_apps.item(app_name) || 'cPanel';
SET app_images = {
    'whostmgrd' => 'whm-white.png',
    'webmaild'  => 'webmail.png',
    'cpaneld'   => 'cpanel-logo.png',
};
SET app_image = app_images.$app_name || app_images.cpaneld;
SET app_image = MagicRevision(get_theme_url("images/$app_image"));
SET shownotice = logout || msg_code;
SET notice_message = msg_code
    ? (login_messages.$msg_code || locale.maketext('An authorization error occurred. Please try again.') )
    : locale.maketext('You have logged out.')
;
SET login_target = (dest_uri=='/') ? '_top' : '_self';
#Windows XP doesn't have the fancy arrows, so use ellipsis for now.
SET more_locales_symbol = "…";
-%]
<input type="hidden" id="dest_uri" value="[% dest_uri FILTER html %]" />
<div id="login-wrapper">
    <div id="notify">
        <noscript>
            <div class="error-notice">
                <img src="[% MagicRevision(get_theme_url('images/notice-error.png')) %]" alt="Error" align="left"/>
                [% locale.maketext('JavaScript is disabled in your browser.') %]
                [% locale.maketext('For [_1] to function properly, you must enable JavaScript.', disp_app) %]
                [% locale.maketext('If you do not enable JavaScript, certain features in [_1] will not function correctly.', disp_app) %]
            </div>
            </noscript>
        <div id='login-status' class="[% logout ? 'success-notice' : 'error-notice' %]" style="visibility: [% shownotice ? 'visible' : 'hidden' %]">
            <div id="login-detail">
                <div id="login-status-icon-container"><span class='login-status-icon'></div>
                <div id="login-status-message">[% notice_message %]</div>
            </div>
        </div>
    </div>
    <div style="display:none">
        <div id="locale-container" style="visibility:hidden">
            <div id="locale-inner-container">
                <div id="locale-header">
                    <div class="locale-head">[% locale.maketext('Please select a locale:') %]</div>
                    <div class="close"><a href="javascript:void(0)" onclick="toggle_locales(false)">X [% locale.maketext('Close') %]</a></div>
                </div>
                <div id="locale-map">
                    <div class="scroller clear">
                        [% FOREACH cur_loc = display_locales %]
                            <div class="locale-cell"><a href="?locale=[% cur_loc.tag %]">[% cur_loc.name %]</a></div>
                        [% END %]
                    </div>
                </div>
            </div>
        </div>
    </div>
    <div id="content-container">
        <div id="login-container">
            <div id="login-sub-container">
                <div id="login-sub-header">
                    <img src="[% app_image %]" alt="logo" />
                </div>
                <div id="login-sub">
                    <div id="forms">
                        [% IF reset_pass -%]
                            <form novalidate id="reset_form" action="/resetpass" method="post" style="visibility:hidden">
                                <div class="input-req-login"><label for="reset_pass_username">[% locale.maketext('Username') %]</label></div>
                                <div class="input-field-login icon reset-pass-container">
                                    <input
                                        name="user"
                                        id="reset_pass_username"
                                        class="std_textbox"
                                        type="text"
                                        autocomplete="off"
                                        tabindex="1"
                                        placeholder="[% locale.maketext('Enter your username.') %]"
                                        required>
                                </div>
                                <div class="controls">
                                    <div class="login-btn">
                                        <button
                                            name="login"
                                            type="submit"
                                            id="reset_submit"
                                            tabindex="2">[% locale.maketext('Reset Password') %]</button>
                                    </div>
                                    <div class="reset-pw">
                                        <a href="javascript:void(0)" onclick="return hide_reset();">[% locale.maketext('Cancel') %]</a>
                                    </div>
                                </div>
                                <div class="clear" id="push"></div>
                            </form>
                        [% END -%]
[%# Don't change the form action or the ids/names of the username and password fields.
    Doing so will break browser-native login credential storage.
-%]
                        <form novalidate id="login_form" action="/login/" method="post" target="[% login_target %]">
                            <div class="input-req-login"><label for="user">[% IF app_name=="webmaild" %][% locale.maketext('Email Address') %][% ELSE %][% locale.maketext('Username') %][% END %]</label></div>
                            <div class="input-field-login icon username-container">
                                <input name="user" id="user" autofocus="autofocus" value="[% user FILTER html %]" placeholder="[% IF app_name=="webmaild" %][% locale.maketext('Enter your email address.') %][% ELSE %][% locale.maketext('Enter your username.') %][% END %]" class="std_textbox" type="text" [% allow_login_autocomplete ? '' : 'autocomplete="off"' %] tabindex="1" required>
                            </div>
                            <div style="margin-top:30px;" class="input-req-login"><label for="pass">[% locale.maketext('Password') %]</label></div>
                            <div class="input-field-login icon password-container">
                                <input name="pass" id="pass" placeholder="[% IF app_name=="webmaild" %][% locale.maketext('Enter your email password.') %][% ELSE %][% locale.maketext('Enter your account password.') %][% END %]" class="std_textbox" type="password" tabindex="2" [% allow_login_autocomplete ? '' : 'autocomplete="off"' %] required>
                            </div>
                            <div class="controls">
                                <div class="login-btn">
                                    <button name="login" type="submit" id="login_submit" tabindex="3">[% locale.maketext('Log in') -%]</button>
                                </div>
                                [% IF reset_pass -%]
                                    <noscript><style type="text/css">
                                        .reset-pw { display:none }
                                    </style></noscript>
                                    <div class="reset-pw">
                                        <a href="javascript:void(0)" onclick="show_reset()">[% locale.maketext('Reset Password') %]</a>
                                    </div>
                                [% END -%]
                            </div>
                            <div class="clear" id="push"></div>
                        </form>
                    <!--CLOSE forms -->
                    </div>
                <!--CLOSE login-sub -->
                </div>
            <!--CLOSE login-sub-container -->
            </div>
        <!--CLOSE login-container -->
        </div>
        <div id="locale-footer">
            <div class="locale-container">
                <noscript>
                    <form method="get" action=".">
                        <select name="locale">
                            <option value="">[% locale.maketext('Change locale') %]</option>
                            [% "<option value='${cur_loc.tag}'>${cur_loc.name}</option>" FOR cur_loc=display_locales -%]
                        </select>
                        <button style="margin-left: 10px" type="submit">[% locale.maketext('Change') %]</button>
                    </form>
                    <style type="text/css">#locales_list {display:none}</style>
                </noscript>
                <ul id="locales_list">
                    [% FOREACH cur_loc = display_locales %]
                        [% LAST IF loop.index > 7 %]
                        <li><a href="/?locale=[% cur_loc.tag %]">[% cur_loc.name.replace(' ','&nbsp;') %]</a></li>
                    [% END %]
                    <li><a href="javascript:void(0)" id="morelocale" onclick="toggle_locales(true)" title="[% locale.maketext('More locales') %]">[% more_locales_symbol %]</a></li>
                </ul>
            </div>
        </div>
    </div>
<!--Close login-wrapper -->
</div>
<script>
    // Homerolled.   We're not logged in and don't have access to cjt and yui.
    [%#Try to avoid bringing in a JSON serializer -%]
    var MESSAGES = {
    [% FOR pair=login_messages -%]
        "[% pair.key %]" : "[% pair.value %]",
    [% END -%]
        "": 0
    };
    delete MESSAGES[""];
    window.IS_LOGOUT = [% logout ? 'true' : 'false' %];
[%# Must not include external javascript -jnk 06.20.09 -%]
[%
SET js_url = get_theme_url('js-min/login.js') || get_theme_url('js/login.js');
IF js_url;
    js_url = js_url.replace('^/','');
    INSERT "$js_url";
END;
-%]
</script>

main.tmpl

Note:

Advanced users can update this template to modify the way in which the system processes user input. 

This template contains the conditions to perform the following actions:

  • Correctly set the title of the login page in the web browser.
  • Set the page's favicon.
  • Load the login theme CSS files.
  • Include the login page's copyright notice.

Template variables

This template does not use template variables.

Advanced use

The login application loads the main.tmpl template to determine how the system processes user input.

Application parameters

The login application uses the following parameters, which are only available in templates that use the main.tmpl parent template:

ParameterTypeDescription
app_namestring

The cPanel & WHM service that the user attempted to log in to:

  • cpaneld — The cPanel interface.
  • whostmgrd — The WHM interface.
  • webmaild — The Webmail interface.
http_status_codestringThe HTTP status code that the server used to respond to the request.
login_messageshashA hash of messages that the browser can display dynamically via Javascript.
logoutboolean

Whether the user logged out recently:

  • 1 — The user logged out recently.
  • 0 — The user has not logged out recently.
page_to_showstring

The sub-template that the login application calls after it loads the main.tmpl template:

  • access_denied — Access the templates/access_denied.tmpl template.
  • fourohfour — Access the templates/fourohfour.tmpl template.
  • login — Access the templates/login.tmpl template.
  • passthrough — Access the templates/passthrough.tmpl template.
  • referrer_denied — Access the templates/referrer_denied.tmpl template.
  • token_denied — Access the templates/token_denied.tmpl template.
reset_passboolean

Whether to display the Reset Password link:

  • 1 — Display.
  • 0 — Do not display.
Global objects

Note:

 The Template::Toolkit module does not allow scoping. For more information, read our Guide to Template Toolkit in cPanel & WHM documentation.

When you modify the way in which this template processes input, you can also use the following global objects:

Global objectTypeDescription
display_locales()function

This function retrieves a list of the locales that are available on the server.

  • The function returns this list of locale information in an array of hashes.
  • This function does not accept arguments.
get_theme_url()function

This function searches the /usr/local/cpanel/base/unprotected/ directory and its subdirectories for a specified file and returns its location. Use this function to ensure that the system displays the correct image for the server's current login theme.

  • This function matches against the filename that you request, regardless of the application name. For example, if you use this function to search for the logo.png file, the function would also search for the logo_whostmgr.png file.
  • You must pass values through the MagicRevision() function after you pass them through this function. For example, the following code passes the filename logo.png to the get_theme_url() function, and then passes the file through the MagicRevision() function:

    <img src="[% MagicRevision( get_theme_url('logo.png') ) %]" alt="logo"> 
locale Cpanel::Locale hash object instanceThis global object contains the current user's locale. For more information, read our How cPanel & WHM Determines a Browser's Locale and Guide to Locales documentation.
MagicRevision()function

This function provides a caching system. Use this function to improve load times for users and decrease system I/O.

  • URLs that you pass through the MagicRevision() function contain the file's modification time in the URL path. 
  • The cpsrvd daemon recognizes URL paths that contain a file modification time, and serves files as the browser cached them if no new changes have occurred.
Default template example
[%
    IF fourohfour || access_denied || referrer_denied || token_denied;
        SET title = locale.maketext('Error');
    ELSIF ssl_redirect;
        SET title = locale.maketext('Login redirect');
    ELSE;
        SWITCH app_name;
            CASE 'cpaneld';
                SET title = locale.maketext('[asis,cPanel] Login');
                SET body_class = "cp";
            CASE 'whostmgrd';
                SET title = locale.maketext('WHM Login');
                SET body_class = "whm";
            CASE DEFAULT;
                SET title = locale.maketext('Webmail Login');
                SET body_class = "wm";
        END;
    END;
%]
<!DOCTYPE html>
<html dir="[% locale.get_html_dir_attr() %]">
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta name="google" content="notranslate" />
    <title>[% title %]</title>
    <link rel="shortcut icon" href="[% MagicRevision(get_theme_url('favicon.ico')) FILTER html %]" />
    <!-- EXTERNAL CSS -->
    <link href="[% MagicRevision(get_theme_url('fonts/open_sans/open_sans.min.css')) FILTER html %]" rel="stylesheet" type="text/css" />
    <link href="[% MagicRevision(get_theme_url('style_v2_optimized.css')) FILTER html %]" rel="stylesheet" type="text/css" />
    <!--[if IE 6]>
    <style type="text/css">
        img {
            behavior: url([% MagicRevision('/unprotected/cp_pngbehavior_login.htc') %]);
        }
    </style>
    <![endif]-->
    <script>
    window.DOM = { get: function(id) { return document.getElementById(id) } };
    </script>
</head>
<body class="[% body_class %]">
[% PROCESS "templates/$page_to_show" -%]
    <div class="copyright">[% locale.maketext('Copyright©[output,nbsp][current_year] cPanel, Inc.') %]</div>
</body>
</html>

templates/passthrough.tmpl

This template generates the page that displays when a user authenticates successfully after a Token Denied error.

Template variables

VariableTypeDescription
cp_security_tokenstringThe security token to use in the URL.
form_refhashA hash of the form variables to pass with the request. The system sends this hash to the location that the redirect_uri variable specifies.
redirect_uristringThe URL to which the system will redirect the user.

Default template example

    <div class="error_notice">
        <div id="error-wrapper">
            <h1>[% locale.maketext('Security token updated.') %]</h1>
            <p>[% locale.maketext('Your login credentials have been validated. You are being redirected to the correct page …') %]</p>
            <form action="[% redirect_uri FILTER html %]" method="post" name="passthroughform">
            [% FOR pair=form_ref -%]
                <input type="hidden" name="[% pair.key FILTER html %]" value="[% pair.value FILTER html %]" />
            [% END -%]
            </form>
            <script type="text/javascript">
                // Reset frame locations for WHM
                function reloadFrames() {
                    if (top.commander && top.commander.location.href.match('scripts/command$')) {
                        top.commander.location = "[% cp_security_token %]/scripts/command";
                    }
                    if (top.topFrame && top.topFrame.location.href.match('scripts/command[?]PFILE=topframe$')) {
                        top.topFrame.location = "[% cp_security_token %]/scripts/command?PFILE=topframe";
                    }
                };
                reloadFrames();
                document.passthroughform.submit();
            </script>
        </div>
    </div>

templates/referrer_denied.tmpl

The system accesses this template whenever the server returns a Referrer Denied error. The system returns this error if the server rejects the user's reference link.

Template variables

VariableTypeDescription
dest_uristringThe URL to load after a user authenticates. This URL does not contain the security token.
error_msgstringThe error message to display.
form_refhashA hash of the form variables to pass with the request. The system sends this hash to the location that the redirect_uri variable specifies.
parameterized_formhashA hash of form variables that the user provided as a URL query string.
themestringThe theme to load.
userstringThe username to authenticate.

Default template example

[% WRAPPER 'templates/_error_wrapper' -%]
    [% referring_url = referrer FILTER html; -%]
    <p>[% locale.maketext('You do not have permission to access this page from “[_1]”.', "<code>$referring_url</code>") %]</p>
[% END -%]

resetpass.tmpl

Note:

Advanced users can update this template to modify the way in which the system processes user input.

This template generates the page that instructs users to reset their passwords.

Template variables

This template does not use template variables.

Advanced use

The resetpass application loads the resetpass.tmpl template to determine how the system processes user input when users reset their passwords.

Note:

The resetpass application uses the resetpass-email.tmpl and resetpass-email-html.tmpl templates when it sends a confirmation email to the user. 

Application parameters

The resetpass application uses the following parameters, which are only available in templates that use the resetpass.tmpl parent template:

ParameterTypeDescription
notice_classstringThe HTML class for the notice_text notice.
notice_textstring

The notice to display, if one exists.

page_to_showstring

The sub-template that the resetpass application calls after it loads the resetpass.tmpl template:

  • resetpass_confirmation — Access the templates/resetpass_confirmation template.
  • resetpass_no_user — Access the templates/resetpass_no_user.tmpl template.
  • resetpass_success — Access the templates/success.tmpl template.
Global objects

Note:

 The Template::Toolkit module does not allow scoping. For more information, read our Guide to Template Toolkit in cPanel & WHM documentation.

When you modify the way in which this template processes input, you can also use the following global objects:

Global objectTypeDescription
display_locales()function

This function retrieves a list of the locales that are available on the server.

  • The function returns this list of locale information in an array of hashes.
  • This function does not accept arguments.
get_theme_url()function

This function searches the /usr/local/cpanel/base/unprotected/ directory and its subdirectories for a specified file and returns its location. Use this function to ensure that the system displays the correct image for the server's current login theme.

  • This function matches against the filename that you request, regardless of the application name. For example, if you use this function to search for the logo.png file, the function would also search for the logo_whostmgr.png file.
  • You must pass values through the MagicRevision() function after you pass them through this function. For example, the following code passes the filename logo.png to the get_theme_url() function, and then passes the file through the MagicRevision() function:

    <img src="[% MagicRevision( get_theme_url('logo.png') ) %]" alt="logo"> 
locale Cpanel::Locale hash object instanceThis global object contains the current user's locale. For more information, read our How cPanel & WHM Determines a Browser's Locale and Guide to Locales documentation.
MagicRevision()function

This function provides a caching system. Use this function to improve load times for users and decrease system I/O.

  • URLs that you pass through the MagicRevision() function contain the file's modification time in the URL path. 
  • The cpsrvd daemon recognizes URL paths that contain a file modification time, and serves files as the browser cached them if no new changes have occurred.

Default template example

[% notice_text %]
 
[% PROCESS "templates/$page_to_show" %] 
[% locale.maketext('Copyright©[output,nbsp][current_year] cPanel, Inc.') %]

templates/resetpass_confirmation.tmpl

This template generates the page that displays when a user clicks Reset Password and has entered a username in the Username text box.

  • When the system accesses this template, it also sends a confirmation code to the user via email. This email message uses either the resetpass-email.tmpl or resetpass-email-html.tmpl template, based on whether the user's email client can display HTML. 
  • The user must enter the confirmation code that they receive in order to reset the password.

Template variables

This template does not use template variables.

Default template example

<div id="forms">
    <form id="reset_form" novalidate action="" method="post">
        <!--prevent submit on Enter if login button is disabled-->
        <input style="display:none" />
        <input type="hidden" name="user" value="[% user FILTER html %]" />
        <input type="hidden" name="action" value="reset" />
        <div class="input-req-login"><label for="confirmation">[% locale.maketext('Confirmation code:') %]</label></div>
        <div class="input-field-login no-icon">
            <input name="confirm" type="text" class="std_textbox" id="confirmation" maxlength="16" required autocomplete="off">
        </div>
        <div class="controls">
            <div id="confirm-submit-btn" class="login-btn">
                <button type="submit" id="confirm-submit">[% locale.maketext('Submit') %]</button>
            </div>
            <div class="reset-pw"><a href="/">[% locale.maketext('Cancel') %]</a></div>
        </div>
        <div class="clear"></div>
    </form>
</div>

templates/resetpass_no_user.tmpl

This template generates the page that displays when a user clicks Reset Password without a username in the Username text box.

Template variables

This template does not use template variables.

Default template example

<div id="forms">
    <form id="reset_form" method="POST">
        <!-- Prevent submit via Enter if submit button is disabled -->
        <input style="display:none" />
        <div class="input-req-login"><label for="username">[% locale.maketext('Username') %]</label></div>
        <div class="input-field-login icon username-container">
            <input name="user" id="username" placeholder="[% locale.maketext('Enter your username.') %]" type="text"  autocomplete="off" class="std_textbox" tabindex="1" required>
        </div>
        <div class="controls">
            <div class="login-btn">
                <input name="login" type="submit" id="login" value="[% locale.maketext('Reset Password') %]" >
            </div>
        </div>
        <div class="controls">
            <div class="reset-pw"><a href="/">[% locale.maketext('Cancel') %]</a></div>
        </div>
        <div class="clear"></div>
    </form>
</div>

templates/resetpass_success.tmpl

This template generates the confirmation page that displays when a user resets a password successfully.

Template variables

This template does not use template variables.

Default template example

<div class="form-container">
    <div class="input-req-login">
        <label for="new_password">[% locale.maketext('This is your account’s new password:') %]</label>
    </div>
    <div class="input-field-login no-icon">
        <input type="text" id="new-password" class="std_textbox" readonly="readonly" name="newpass" value="[% newpass FILTER html %]">
    </div>
    <p>[% locale.maketext('Please make a note of your new password. Changing this password affects all of the services associated with your [asis,cPanel] account, including [output,acronym,FTP,File Transfer Protocol], [output,acronym,SSH,Secure Shell], [asis,WebDAV], and [asis,MySQL].') %]</p>
    <div class="controls">
        <div class="login-btn">
            <a class="loginbtn" href="/">[% locale.maketext('Log in') %]</a>
        </div>
    </div>
</div>

securitypolicy_footer.html.tmpl

This template generates the Security Policy page's footer. Users set the security questions for their accounts through this page.

Template variables

This template does not use template variables.

Default template example

</div>
</div>
<div class="clear"></div>
</div>
</div>
<!-- close login-wrapper -->
</div>
</div>
</div>
</div>
</div>
<div class="copyright">[% locale.maketext('Copyright©[output,nbsp][current_year] cPanel, Inc.') %]</div>
</div>
</body>
</html>

securitypolicy_header.html.tmpl

This template generates the Security Policy page's header. Users set the security questions for their accounts through this page.

Template variables

This template does not use template variables.

Default template example

[%
IF action == 'setquestions';
    SET warning = locale.maketext('You have not set up security questions for your account.')
        _ " " _ locale.maketext('Please take a moment to set up your security questions.');
ELSIF action == 'challenge';
    SET warning = locale.maketext('You appear to be logging in from an unknown location.')
        _ " " _ locale.maketext('Please verify your identity by answering the following security questions:');
END;
SET body_class = '';
IF (app_name == 'whostmgrd') || (CPANEL.appname == 'whostmgrd');
    SET app = 'WHM';
    SET body_class = 'whm';
ELSIF (app_name == 'cpaneld') || (CPANEL.appname == 'cpaneld');
    SET app = 'cPanel';
    SET body_class = 'cp';
ELSE;
    SET app = 'Webmail';
    SET body_class = 'wm';
END;
SET title = locale.maketext('[_1] Login Security',app);
SET app_images = {
    'whostmgrd' => 'whm-white.png',
    'webmaild'  => 'webmail.png',
    'cpaneld'   => 'cpanel-logo.png',
};
SET app_image = app_images.$app_name || app_images.cpaneld;
SET app_image = MagicRevision(get_theme_url("images/$app_image"));

-%]
<!DOCTYPE html>
<html dir="[% locale.get_html_dir_attr() %]">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<!-- EXTERNAL CSS -->
<link href="[% MagicRevision(get_theme_url('fonts/open_sans/open_sans.min.css')) FILTER html %]" rel="stylesheet" type="text/css" />
<link href="[% MagicRevision(get_theme_url('style_v2_optimized.css')) FILTER html %]" rel="stylesheet" type="text/css" />
<title>[% title %]</title>
</head>
<body class="yui-skin-sam security_policy [% body_class %]">
<div class="login-page">
    <div class="login-content">
        <div class="login-center-answer">
            <div id="login-wrapper">
            [% IF warning -%]
                <div id="login-status" class="warn-notice">
                    <div class="message-detail">
                        <div id="login-status-icon-container"><span class="login-status-icon"></div>
                        <div id="login-status-message">[% warning %]</div>
                    </div>
                </div>
            [% END -%]
            <div id="content-container">
                <div id="security-container">
                    <div id="security-sub-container">
                        <div id="login-sub-header">
                            <img src="[% app_image %]" alt="logo" />
                        </div>
                        <div id="security-sub">
                            <div class="login-rt">
                                <div class="form">

templates/token_denied.tmpl

The system accesses this template whenever the server responds with a Token Denied error.

Template variables

VariableTypeDescription
dest_uristringThe URL to load after a user authenticates. This URL does not contain the security token.
error_msgstringThe error message to display.
form_refhashA hash of the form variables to pass with the request. The system sends this hash to the location that the redirect_uri variable specifies.
parameterized_formhashA hash of form variables that the user provided as a URL query string.
themestringThe theme to load.
userstringThe username to authenticate.

Default template example

[% WRAPPER 'templates/_error_wrapper' -%]
    <h3>[% locale.maketext('Invalid Security Token') %]</h3>
    <p>[% locale.maketext('The requested [output,acronym,URL,Uniform Resource Locator] does not contain your session’s correct security token.') %]</p>
    <p>[% locale.maketext('You may have reached this error by copying and pasting a URL from a different cPanel, WHM, or Webmail session into your browser’s address bar. To resolve this situation, please take one of the following steps:') %]</p>
    <ul class="options">
        <li>[% locale.maketext('[output,url,_1,Go back one page,_2,_3] and reload the URL, making sure that the [output,class,/cpsess … /,_4] section of the URL remains the same.','javascript:history.back()','class','page-link','code') %]</li>
        <li>[% locale.maketext('Re-enter your account’s password below. This will assign your session a new security token. This new token will prevent you from using other pages of this application that may be open in other tabs.') %]</li>
    </ul>
    <div id="token-forms">
        <div class="pagevars">
            <h3>[% locale.maketext('Request information') %]</h3>
            <p>
                [% dest_html = dest_uri FILTER html -%]
                [% locale.maketext('Requested page: [_1]', dest_html) %]
            </p>
            [% IF form_ref.keys.size -%]
                <table class="formtbl" cellspacing="6">
                    <tr>
                        <th>[% locale.maketext('Parameter name') %]</th>
                        <th>[% locale.maketext('Parameter value') %]</th>
                    </tr>
                    [% FOR pair = form_ref -%]
                    <tr><td>[% pair.key FILTER html %]</td><td>[% pair.value FILTER html %]</td></tr>
                    [% END -%]
                </table>
            [% END -%]
        </div>
        <form id="badtokenloginform" action="/login" method="POST">
            <input type="hidden" name="user" value="[% user FILTER html %]" />
            <input type="hidden" name="token_denied" value="1" />
            <input type="hidden" name="parameterized_form" value="[% parameterized_form FILTER html %]" />
            <input type="hidden" name="goto_uri" value="[% dest_uri FILTER html %]" />
            <input type="hidden" name="theme" value="[% theme FILTER html %]" />
            <p>[% locale.maketext('Username: [_1]', user) FILTER html %]</p>
            <div class="control_container">
                <div class="group">
                <div class="controls">
                    <div class="input-field-login icon password-container">
                        <input name="pass" id="pass" placeholder="[% IF app_name=="webmaild" %][% locale.maketext('Enter your email password.') %][% ELSE %][% locale.maketext('Enter your account password.') %][% END %]" class="std_textbox" type="password" autofocus required>
                    </div>
                </div>
                </div>
                <div class="group">
                <div class="controls">
                    <div class="login-btn" id="proceed_btn_container">
                        <button type="submit" id="token-submit">[% locale.maketext('Proceed with the Current Request') %]</button>
                    </div>
                </div>
                </div>
            </div>
        </form>
        <form id="badtokenlogoutform"  action="/logout" target="_top">
            <div class="control_container">
                <div class="controls">
                    <div class="login-btn" id="logout_btn_container">
                        <button type="submit" id="logout-btn">[% locale.maketext('Log Out') %]</button>
                    </div>
                </div>
            </div>
        </form>
    </div>
    <script>
        try { document.getElementById("pass").focus(); } catch(e) {}
    </script>
[% END %]

Note:

For more information about login page templates, read our Guide to cPanel Interface Customization - Login Templates documentation.

 


 

Modify theme CSS files.

Make the desired changes to the style_v2.css and style_v2_optimized.css files.

Note:

Subheader logo customizations may require changes to the subheader logo style attributes. Modify these attributes under the login-sub-header div tag in the style_v2.css file.

 


 

Update your server's locales.

If you added new text to your theme's login templates, add those new phrases to your server's locales.

  • To do this, use WHM's Edit a Locale  interface (Home >> Locale >> Edit a Locale).
  • For more information about cPanel & WHM's localization system, read our Guide to Locales documentation.

 


 

Use your new custom login theme.

To cause all of your server's accounts to use the new custom login theme, select the theme's name from the Default login theme menu in WHM's Tweak Settings interface (Home >> Server Configuration >> Tweak Settings).