[Development Guides Home](/guides) >> [Guide to cPanel Interface Customization and Branding](/guides/guide-to-cpanel-interface-customization-and-branding) >> [Guide to cPanel Interface Customization - The Login Theme](/guides/guide-to-cpanel-interface-customization-and-branding/guide-to-cpanel-interface-customization-the-login-theme) # Guide to cPanel Interface Customization - Login Templates ## Introduction Template files determine the appearance of each login page. Each login theme includes template files for the main login pages, error pages, and templates for the *Reset Password* feature. ## Templates The locations listed below are relative to the `/usr/local/cpanel/base/unprotected/cpanel/` directory, which contains the cPanel & WHM default login theme. Select a template file below to view more information about that template file: * [`-error-wrapper.tmpl`](#templates/_error-wrapper.tmpl) * [`access-denied.tmpl`](#templates/access_denied.tmpl) * [`disabled.tmpl`](#templates/disabled.tmpl) * [`error502.tmpl`](#templates/error502.tmpl) * [`error503.tmpl`](#templates/error503.tmpl) * [`external-auth-header.tmpl`](#templates/external_auth_header.tmpl) * [`external-auth.tmpl`](#templates/external_auth.tmpl) * [`fourohfour.tmpl`](#templates/fourohfour.tmpl) * [`generic-error.tmpl`](#templates/generic_error.tmpl) * [`invitation-failure.tmpl`](#templates/invitation_failure.tmpl) * [`invitation-set-password.tmpl`](#templates/invitation_set_password.tmpl) * [`invitation-success.tmpl`](#templates/invitation_success.tmpl) * [`login.tmpl`](#templates/login.tmpl) * [`main.tmpl`](#main.tmpl) * [`templates/passthrough.tmpl`](#passthrough.tmpl) * [`referrer-denied.tmpl`](#templates/referrer_denied.tmpl) * [`resetpass.tmpl`](#resetpass.tmpl) * [`resetpass-confirmation.tmpl`](#templates/resetpass_confirmation.tmpl) * [`resetpass-failure.tmpl`](#templates/resetpass_failure.tmpl) * [`resetpass-no-user.tmpl`](#templates/resetpass_no_user.tmpl) * [`resetpass-puzzle.tmpl`](#templates/resetpass_puzzle.tmpl) * [`resetpass-set-password.tmpl`](#templates/resetpass_set_password.tmpl) * [`resetpass-success.tmpl`](#templates/resetpass_success.tmpl) * [`resetpass-suspended.tmpl`](#templates/resetpass_suspended.tmpl) * [`securitypolicy-footer.html.tmpl`](#securitypolicy_footer.html.tmpl) * [`securitypolicy-header.html.tmpl`](#securitypolicy_header.html.tmpl) * [`token-denied.tmpl`](#templates/token_denied.tmpl) ### 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** ``` [% #---------------------------------------------------------------------- # Arguments received by this template: # This list may not be exhaustive, and other parameters may be added or available. # # app_name - What application is loading this interface (cpaneld, whostmgrd, webmaild) # http_status_code - HTTP Status code # page_to_show - Page to display [% SET app_images = { 'whostmgrd' => 'whm-logo_white.svg', 'webmaild' => 'webmail-logo.svg', 'cpaneld' => 'cpanel-logo.svg', }; SET app_image = app_images.$app_name || app_images.cpaneld; SET app_image = MagicRevision(get_theme_url("images/$app_image")); %] [% IF page_to_show != "access_denied" %] [% END %]

[% locale.maketext('HTTP error [_1]',http_status_code) %]

[% content %] ``` ### 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** | **Variables** | **Type** | **Description** | | --- | --- | --- | | `dest_uri` | *string* | The URL to load after a user authenticates. This URL does **not** contain the security token. | | `error_msg` | *string* | The error message to display. | | `form_ref` | *hash* | A 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_form` | *hash* | A hash of form variables that the user provided as a URL query string. | | `theme` | *string* | The theme to load. | | `user` | *string* | The username to authenticate. | **Default template example** ``` [% #---------------------------------------------------------------------- # Arguments received by this template: # This list may not be exhaustive, and other parameters may be added or available. # # uri - URI user tried to access without authorization # page_message - Additional message to display to the user %] [% WRAPPER 'templates/_error_wrapper' -%]

[% uri.html() %]

[% locale.maketext('You do not have permission to access this page.') %]

[% IF page_message %]
[% locale.makevar(page_message) FILTER html %]
[% END %] [% END -%] ``` ### templates/disabled.tmpl The system accesses this template whenever the visitor attempts to access a disabled account. **Template variables** This template inherits the template variables from its parent template. **Default template example** ``` [% #---------------------------------------------------------------------- # Arguments received by this template: # This list may not be exhaustive, and other parameters may be added or available. # %]
[%# marker for testing%]
``` ### templates/error502.tmpl The system accesses this template whenever the server responds with a 502 (server) error. **Template variables** | **Variable** | **Type** | **Description** | | --- | --- | --- | | `dest_uri` | *string* | The URL to load after a user authenticates. This URL does **not** contain the security token. | | `error_msg` | *string* | The error message to display. | | `form_ref` | *hash* | A 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_form` | *hash* | A hash of form variables that the user provided as a URL query string. | | `theme` | *string* | The theme to load. | | `user` | *string* | The username to authenticate. | **Default template example** ``` [% #---------------------------------------------------------------------- # Arguments received by this template: # This list may not be exhaustive, and other parameters may be added or available. # %] [% WRAPPER 'templates/_error_wrapper' -%]

[% locale.maketext('The server received a bad response while acting as a proxy.') %]

[% END -%] ``` ### templates/error503.tmpl The system accesses this template whenever the server responds with a HTTP status 503. The system displays HTTP status 503 when the requested service is unavailable. **Template variables** | **Variable** | **Type** | **Description** | | --- | --- | --- | | `dest_uri` | *string* | The URL to load after a user authenticates. This URL does **not** contain the security token. | | `error_msg` | *string* | The error message to display. | | `form_ref` | *hash* | A 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_message` | *string* | The optional message provides more details about why the service is unavailable. | | `parameterized_form` | *hash* | A hash of form variables that the user provided as a URL query string. | | `theme` | *string* | The theme to load. | | `user` | *string* | The username to authenticate. | **Default template example** ``` [% #---------------------------------------------------------------------- # Arguments received by this template: # This list may not be exhaustive, and other parameters may be added or available. # # page_message - Message to be displayed to the user %] [% WRAPPER 'templates/_error_wrapper' -%]

[% locale.maketext('The service is unavailable.') %]

[% IF page_message%]

[% page_message.html() %]

[%END%] [% END -%] ``` ### templates/external_auth_header.tmpl The system accesses this template in order to add the header for the External Authentication login section. **Template variables** This template inherits the template variables from its parent template. **Default template variables** ``` [% #---------------------------------------------------------------------- # Arguments received by this template: # This list may not be exhaustive, and other parameters may be added or available. # # https - Is the application running in https mode # link_account - Boolean are we currently trying to link an account %] [%- USE ExternalAuthentication; SET external_auth_modules = https && !link_account ? ExternalAuthentication.get_enabled_and_configured_openid_provider_display_configurations() : []; -%] ``` ### templates/external_auth.tmpl The system accesses this template in order to add the External Authentication login section. **Template variables** This template inherits the template variables from its parent template. **Default template variables** ``` templates/external_auth.tmpl The system accesses this template in order to add the External Authentication login section. Template variables This template inherits the template variables from its parent template. Default template variables [% #---------------------------------------------------------------------- # Arguments received by this template: # This list may not be exhaustive, and other parameters may be added or available. # # external_auth_modules - What are the currently enabled external authentication modules (cpanel, google, facebook, etc) # page_to_show - Page to display # user - The cPanel user (or virtual user that is logged in) # parameterized_form - A dump of the postdata that is uri encoded # theme - The current cPanel theme that the user is using # goto_uri - The uri that the user requested %] [%- USE HTTP; SET query = { 'user' => user, 'theme' => theme, 'parameterized_form' => parameterized_form, 'goto_uri' => goto_uri, 'goto_app' => goto_app, }; IF page_to_show == 'token_denied'; query.token_denied = 1; END; IF external_auth_modules.size > 0 && external_auth_modules %]
[% locale.maketext('OR[comment,this is a decoration separator, shortest form is best]') %] [% locale.maketext("Log in via"); %]
[% FOR auth_mod = external_auth_modules %] [% IF oidc_failed == auth_mod.provider_name; # This must match use the same regex as unprotected/cpanel/js/login.js IF ENV_REQUEST_URI.match('^\/(?:logout|login|openid_connect_callback)\/?'); SET xauth_link = auth_mod.link.html(); ELSE; SET xauth_link = ENV_REQUEST_URI.html; END; ELSE; SET xauth_link = auth_mod.link.html() _ '?' _ HTTP.make_query_string(query); END; %] [% END %]
[% END %] ``` ### templates/fourohfour.tmpl The system accesses this template whenever the server responds with a HTTP 404 (page not found) error. **Template variables** | **Variable** | **Type** | **Description** | | --- | --- | --- | | `dest_uri` | *string* | The URL to load after a user authenticates. This URL does **not** contain the security token. | | `error_msg` | *string* | The error message to display. | | `form_ref` | *hash* | A 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_form` | *hash* | A hash of form variables that the user provided as a URL query string. | | `theme` | *string* | The theme to load. | | `user` | *string* | The username to authenticate. | **Default template example** ``` [% #---------------------------------------------------------------------- # Arguments received by this template: # This list may not be exhaustive, and other parameters may be added or available. # %] [% WRAPPER 'templates/_error_wrapper' -%]

[% locale.maketext('The requested page was not found.') %]

[% locale.maketext('Possible reasons why you are seeing this page:') %]

  • [% locale.maketext('A bookmarked URL may have changed since you last visited.') %]
  • [% locale.maketext('The URL was entered incorrectly.') %]
  • [% locale.maketext('The URL was entered with inaccurate capitalization (URLs are [output,url,_1,case sensitive]).','http://wikipedia.org/wiki/Case_sensitivity') %]

[% locale.maketext('Please re-check the URL you are trying to reach. ([output,url,_1,Go Back])', 'javascript:history.back()' ) %]

[% END -%] ``` ### templates/generic_error.tmpl The system accesses this template whenever the server responds with a generic error. **Template variables** | **Variable** | **Type** | **Description** | | --- | --- | --- | | `dest_uri` | *string* | The URL to load after a user authenticates. This URL does **not** contain the security token. | | `error_msg` | *string* | The error message to display. | | `form_ref` | *hash* | A 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_form` | *hash* | A hash of form variables that the user provided as a URL query string. | | `theme` | *string* | The theme to load. | | `user` | *string* | The username to authenticate. | **Default template example** ``` [% #---------------------------------------------------------------------- # Arguments received by this template: # This list may not be exhaustive, and other parameters may be added or available. # # uri - URI the user was trying to access when the error occurred # generic_error - The error message %] [% WRAPPER 'templates/_error_wrapper' -%]

[% uri.html() %]

[% generic_error.html() %]

[% END -%] ``` ### templates/invitation_failure.tmpl The system accesses this template whenever it cannot properly process a new user invitation. **Template variables** This template inherits the template variables from its parent template. **Default template example** ``` [% #---------------------------------------------------------------------- # Arguments received by this template: # This list may not be exhaustive, and other parameters may be added or available. # # notice_class - class to add to the notice for styling purposes # reason - Reason the invitation failed. %]
[% IF reason == 'unknown' %] [% ELSIF reason == 'bad-request' %] [% ELSIF reason == 'suspended' %] [% ELSIF reason == 'flooding' %] [% ELSE %] [% END %]
[%# marker for testing%] ``` ### templates/invitation_set_password.tmpl The system accesses this template whenever an invited user needs to set a new password. **Template variables** This template inherits the template variables from its parent template. **Default template example** ``` [% #---------------------------------------------------------------------- # Arguments received by this template: # This list may not be exhaustive, and other parameters may be added or available. # # user - User being accessed / updated SET application_dir = 'cpanel'; SET file = 'invitation'; %] [% PROCESS '_assets/cjt2_header_include.tt' %]
  • [% locale.maketext('You must complete this field.') %]
  • [% locale.maketext('You must provide a password with at least 5 characters.') %]
  • [% locale.maketext('You must provide a stronger password.') %]
  • [% locale.maketext('You must complete this field.') %]
  • [% locale.maketext('The passwords do not match.') %]
[%# marker for testing%]
``` ### templates/invitation_success.tmpl The system accesses this template whenever an invited user successfully accepts the invitation and sets their new password. **Template variables** This template inherits the template variables from its parent template. **Default template example** ``` [% #---------------------------------------------------------------------- # Arguments received by this template: # This list may not be exhaustive, and other parameters may be added or available. # # next_steps - List of invitation step objects # { # key => Key identifying the step type # instructions => Instructions for that specific step # services => List of services associate with that step # } # # logins - List of login service objects # { # id => Dom Element ID # url => url the button will direct them to when clicked # button_text => label for the button # } %]
[% FOREACH step IN next_steps %] [% IF step.value.services.size() %]

[% step.value.instructions %]

[% END %] [% END %] [% FOREACH login IN logins -%] [% END %] [%# marker for testing%]
``` ### 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** | **Variable** | **Type** | **Description** | | --- | --- | --- | | `dest_uri` | *string* | The URL to load after a user authenticates. This URL does **not** contain the security token. | | `msg_code` | *string* | The Key that corresponds to the `login_messages` value. This message displays on the loading page after the user authenticates. | **Default template example** ``` [% #---------------------------------------------------------------------- # Arguments received by this template: # This list may not be exhaustive, and other parameters may be added or available. # # allow_login_autocomplete - Boolean for autocompleting login names # app_name - What application is loading this interface (cpaneld, whostmgrd, webmaild) # goto_uri - The uri that the user requested # goto_app - App the user is attempting to log in to. # display_locales - Boolean for if the interface display the locales list # https - Is the application running in https mode # login_messages - Messages to present to the user pertaining to the login process # logout - Boolean of whether to display the login button # msg_code - Key for what we are currently doing in the login display (link_account, etc) # reset_pass - should be true if either resetpass or resetpass_sub is enabled (doesn't have to be both) USE DataURI; USE JSON; USE Wbr; SET disp_apps = { 'whostmgrd' => 'WHM', 'webmaild' => 'Webmail', 'cpaneld' => 'cPanel', }; SET disp_app = disp_apps.item(app_name) || 'cPanel'; SET app_images = { 'whostmgrd' => 'whm-logo_white.svg', 'webmaild' => 'webmail-logo.svg', 'cpaneld' => 'cpanel-logo.svg', }; # get app modules based on $app_name SET app_image = app_images.$app_name || app_images.cpaneld; SET app_image = MagicRevision(get_theme_url("images/" _ app_image)); #If msg_code is 'link_account' we already have a separate display notice so don't need to show it twice SET shownotice = logout || msg_code; SET shownotice = msg_code == 'link_account' ? 0 : shownotice; SET shownotice = msg_code == 'max_users_exceeded' ? 0 : shownotice; 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 = (goto_uri=='/') ? '_top' : '_self'; #Windows XP doesn't have the fancy arrows, so use ellipsis for now. SET more_locales_symbol = "…"; # Only run the display_locales function once by saving it into all_display_locales SET all_display_locales = display_locales; PROCESS "templates/external_auth_header.tmpl"; SET login_classes = []; IF reset_pass; login_classes.push('has-pw-reset'); END; UNLESS external_auth_modules; login_classes.push('no-external-auth-modules'); END; SET notice_style_ = logout ? 'success-notice' : notice_style ? notice_style : 'error-notice'; -%] [% MACRO ceil(n) GET n + (n - (n % (n + 1)) > 0 ? 1 : 0) FILTER format("%d"); %]
``` ### 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** ``` [% #---------------------------------------------------------------------- # Arguments received by this template: # This list may not be exhaustive, and other parameters may be added or available. # # action - Type of securty action being taken (setquestions, challenge) # app_name - What application is loading this interface (cpaneld, whostmgrd, webmaild) # error - Error being presented to the user # warning - Warning being presented to the user, possibly overriden in the template 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 = ''; SWITCH app_name; CASE 'cpaneld'; SET app = 'cPanel'; SET body_class = "cp"; CASE 'whostmgrd'; SET app = 'WHM'; SET body_class = "whm"; CASE DEFAULT; SET app = 'Webmail'; SET body_class = "wm"; END; SET title = locale.maketext('[_1] Login Security',app); SET app_images = { 'whostmgrd' => 'whm-logo_white.svg', 'webmaild' => 'webmail-logo.svg', 'cpaneld' => 'cpanel-logo.svg', }; SET app_image = app_images.$app_name || app_images.cpaneld; SET app_image = MagicRevision(get_theme_url("images/$app_image")); -%] [% title %]