[[_themes]] == Themes {project_name} provides theme support for web pages and emails. This allows customizing the look and feel of end-user facing pages so they can be integrated with your applications. image::images/login-sunrise.png[caption="",title="Login page with sunrise example theme"] === Theme Types A theme can provide one or more types to customize different aspects of {project_name}. The types available are: * Account - Account management * Admin - Admin console * Email - Emails * Login - Login forms * Welcome - Welcome page === Configure Theme All theme types, except welcome, are configured through the `Admin Console`. To change the theme used for a realm open the `Admin Console`, select your realm from the drop-down box in the top left corner. Under `Realm Settings` click `Themes`. NOTE: To set the theme for the `master` admin console you need to set the admin console theme for the `master` realm. To see the changes to the admin console refresh the page. To change the welcome theme you need to edit `standalone.xml`, `standalone-ha.xml`, or `domain.xml`. Add `welcomeTheme` to the theme element, for example: [source,xml] ---- ... custom-theme ... ---- If the server is running you need to restart the server for the changes to the welcome theme to take effect. === Default Themes {project_name} comes bundled with default themes in the server's root `themes` directory. To simplify upgrading you should not edit the bundled themes directly. Instead create your own theme that extends one of the bundled themes. === Creating a Theme A theme consists of: * HTML templates (https://freemarker.apache.org/[Freemarker Templates]) * Images * Message bundles * Stylesheets * Scripts * Theme properties Unless you plan to replace every single page you should extend another theme. Most likely you will want to extend the {project_name} theme, but you could also consider extending the base theme if you are significantly changing the look and feel of the pages. The base theme primarily consists of HTML templates and message bundles, while the {project_name} theme primarily contains images and stylesheets. When extending a theme you can override individual resources (templates, stylesheets, etc.). If you decide to override HTML templates bear in mind that you may need to update your custom template when upgrading to a new release. While creating a theme it's a good idea to disable caching as this makes it possible to edit theme resources directly from the `themes` directory without restarting {project_name}. To do this edit `standalone.xml`. For `theme` set `staticMaxAge` to `-1` and both `cacheTemplates` and `cacheThemes` to `false`: [source,xml] ---- -1 false false ... ---- Remember to re-enable caching in production as it will significantly impact performance. To create a new theme start by creating a new directory in the `themes` directory. The name of the directory becomes the name of the theme. For example to create a theme called `mytheme` create the directory `themes/mytheme`. Inside the theme directory create a directory for each of the types your theme is going to provide. For example to add the login type to the `mytheme` theme create the directory `themes/mytheme/login`. For each type create a file `theme.properties` which allows setting some configuration for the theme. For example to configure the theme `themes/mytheme/login` that we just created to extend the base theme and import some common resources create the file `themes/mytheme/login/theme.properties` with following contents: [source] ---- parent=base import=common/keycloak ---- You have now created a theme with support for the login type. To check that it works open the admin console. Select your realm and click on `Themes`. For `Login Theme` select `mytheme` and click `Save`. Then open the login page for the realm. You can do this either by login through your application or by opening the Account Management console (`/realms/{realm name}/account`). To see the effect of changing the parent theme, set `parent=keycloak` in `theme.properties` and refresh the login page. ==== Theme Properties Theme properties are set in the file `/theme.properties` in the theme directory. * parent - Parent theme to extend * import - Import resources from another theme * styles - Space-separated list of styles to include * locales - Comma-separated list of supported locales There are a list of properties that can be used to change the css class used for certain element types. For a list of these properties look at the theme.properties file in the corresponding type of the keycloak theme (`themes/keycloak//theme.properties`). You can also add your own custom properties and use them from custom templates. When doing so, you can substitute system properties or environment variables by using these formats: * `${some.system.property}` - for system properties * `${env.ENV_VAR}` - for environment variables. A default value can also be provided in case the system property or the environment variable is not found with `${foo:defaultValue}`. NOTE: If no default value is provided and there's no corresponding system property or environment variable, then nothing is replaced and you end up with the format in your template. Here's an example of what is possible: [source,properties] ---- javaVersion=${java.version} unixHome=${env.HOME:Unix home not found} windowsHome=${env.HOMEPATH:Windows home not found} ---- ==== Stylesheets A theme can have one or more stylesheets. To add a stylesheet create a file in the `/resources/css` directory of your theme. Then add it to the `styles` property in `theme.properties`. For example to add `styles.css` to the `mytheme` create `themes/mytheme/login/resources/css/styles.css` with the following content: [source,css] ---- .login-pf body { background: DimGrey none; } ---- Then edit `themes/mytheme/login/theme.properties` and add: [source] ---- styles=css/styles.css ---- To see the changes open the login page for your realm. You will notice that the only styles being applied are those from your custom stylesheet. To include the styles from the parent theme you need to load the styles from that theme as well. Do this by editing `themes/mytheme/login/theme.properties` and changing `styles` to: [source] ---- styles=node_modules/patternfly/dist/css/patternfly.css node_modules/patternfly/dist/css/patternfly-additions.css lib/zocial/zocial.css css/login.css css/styles.css ---- NOTE: To override styles from the parent stylesheets it's important that your stylesheet is listed last. ==== Scripts A theme can have one or more scripts, to add a script create a file in the `/resources/js` directory of your theme. Then add it to the `scripts` property in `theme.properties`. For example to add `script.js` to the `mytheme` create `themes/mytheme/login/resources/js/script.js` with the following content: [source,javascript] ---- alert('Hello'); ---- Then edit `themes/mytheme/login/theme.properties` and add: [source] ---- scripts=js/script.js ---- ==== Images To make images available to the theme add them to the `/resources/img` directory of your theme. These can be used from within stylesheets or directly in HTML templates. For example to add an image to the `mytheme` copy an image to `themes/mytheme/login/resources/img/image.jpg`. You can then use this image from within a custom stylesheet with: [source,css] ---- body { background-image: url('../img/image.jpg'); background-size: cover; } ---- Or to use directly in HTML templates add the following to a custom HTML template: [source,html] ---- ---- ==== Messages Text in the templates is loaded from message bundles. A theme that extends another theme will inherit all messages from the parent's message bundle and you can override individual messages by adding `/messages/messages_en.properties` to your theme. For example to replace `Username` on the login form with `Your Username` for the `mytheme` create the file `themes/mytheme/login/messages/messages_en.properties` with the following content: [source] ---- usernameOrEmail=Your Username ---- Within a message values like `{0}` and `{1}` are replaced with arguments when the message is used. For example {0} in `Log in to {0}` is replaced with the name of the realm. ==== Internationalization {project_name} supports internationalization. To enable internationalization for a realm see {adminguide_link}[{adminguide_name}]. This section describes how you can add your own language. To add a new language create the file `/messages/messages_.properties` in the directory of your theme. Then add it to the `locales` property in `/theme.properties`. For a language to be available to users the realms `login`, `account` and `email` theme has to support the language, so you need to add your language for those theme types. For example, to add Norwegian translations to the `mytheme` theme create the file `themes/mytheme/login/messages/messages_no.properties` with the following content: [source] ---- usernameOrEmail=Brukernavn password=Passord ---- All messages you don't provide a translation for will use the default English translation. Then edit `themes/mytheme/login/theme.properties` and add: [source] ---- locales=en,no ---- You also need to do the same for the `account` and `email` theme types. To do this create `themes/mytheme/account/messages/messages_no.properties` and `themes/mytheme/email/messages/messages_no.properties`. Leaving these files empty will result in the English messages being used. Then copy `themes/mytheme/login/theme.properties` to `themes/mytheme/account/theme.properties` and `themes/mytheme/email/theme.properties`. Finally you need to add a translation for the language selector. This is done by adding a message to the English translation. To do this add the following to `themes/mytheme/account/messages/messages_en.properties` and `themes/mytheme/login/messages/messages_en.properties`: [source] ---- locale_no=Norsk ---- By default message properties files should be encoded using ISO-8859-1. It's also possible to specify the encoding using a special header. For example to use UTF-8 encoding: [source] ---- # encoding: UTF-8 usernameOrEmail=.... ---- See <<_locale_selector,Locale Selector>> on details on how the current locale is selected. ==== HTML Templates {project_name} uses https://freemarker.apache.org/[Freemarker Templates] in order to generate HTML. You can override individual templates in your own theme by creating `/