# Extending FreeMarkerLoginFormsProvider for custom theme attributes

**URL:** <https://forum.keycloak.org/t/extending-freemarkerloginformsprovider-for-custom-theme-attributes/15401>\
**Category:** Extending the server\
**Tags:** upgrading\
**Created:** [May 6, 2022, 12:24pm UTC](https://forum.keycloak.org/t/extending-freemarkerloginformsprovider-for-custom-theme-attributes/15401 "2022-05-06T12:24:52Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![cedricguindon](https://yyz2.discourse-cdn.com/free1/user_avatar/forum.keycloak.org/cedricguindon/32/2670_2.png) [@cedricguindon](https://forum.keycloak.org/u/cedricguindon)\
**Post date:** [May 6, 2022, 12:24pm UTC](https://forum.keycloak.org/t/extending-freemarkerloginformsprovider-for-custom-theme-attributes/15401/1 "2022-05-06T12:24:52Z")

</div>

Hello

I’m currently exploring the upgrade from major 16 to 17 and trying to figure out if it will work with our custom services.

After some finagling, i’ve managed to get pretty much everything to work except the following feature which we really need.

I have a custom SPI that extends FreeMarkLoginFormsProvider, i’m extending it in order to add attributes to the createCommonAttributes method, which then let’s me add new attributes to the theme, the attributes are coming form the realm attributes.  
(Everything would be much simpler if the ftl files had access to realm attributes, but they dont)

But the problem is that in order to extend this class, i needed to add a custom spi in the standalone file as such:

```auto
embed-server --server-config=standalone-ha.xml
/subsystem=keycloak-server/spi=login:add()
/subsystem=keycloak-server/spi=login/provider=freemarker:add(enabled="false")
/subsystem=keycloak-server/spi=login/provider=csps-freemarker-login-messages:add(enabled="true")
stop-embedded-server

```

The above is not possible anymore in keycloak 17 and up since jboss-cli.sh is no longer in the bin folder of keycloak.

I’m wondering, is extending the theme and adding new attributes that can be fetched from the ftl files is still possible through the FreeMarkerLoginFormsProvider class in keycloak 17 and up?

Here’s my class for the interested

```auto
public class CustomFreeMarkerLoginFormsProvider extends FreeMarkerLoginFormsProvider {

    public CustomFreeMarkerLoginFormsProvider(KeycloakSession session, FreeMarkerUtil freeMarker) {
        super(session, freeMarker);
    }

    @Override
    protected void createCommonAttributes(Theme theme, Locale locale, Properties messagesBundle,
            UriBuilder baseUriBuilder, LoginFormsPages page) {
        super.createCommonAttributes(theme, locale, messagesBundle, baseUriBuilder, page);

        if (realm != null) {
            // Setting the messages and title from the realm attributes.
            if ("fr".equals(locale.toString().toLowerCase())) {
                attributes.put("dangerMessage", realm.getAttribute("dangerMessageFrench"));
                attributes.put("warningMessage", realm.getAttribute("warningMessageFrench"));
                attributes.put("infoMessage", realm.getAttribute("infoMessageFrench"));
                attributes.put("dangerMessageTitle", realm.getAttribute("dangerMessageTitleFrench"));
                attributes.put("warningMessageTitle", realm.getAttribute("warningMessageTitleFrench"));
                attributes.put("infoMessageTitle", realm.getAttribute("infoMessageTitleFrench"));
            } else {
                attributes.put("dangerMessage", realm.getAttribute("dangerMessageEnglish"));
                attributes.put("warningMessage", realm.getAttribute("warningMessageEnglish"));
                attributes.put("infoMessage", realm.getAttribute("infoMessageEnglish"));
                attributes.put("dangerMessageTitle", realm.getAttribute("dangerMessageTitleEnglish"));
                attributes.put("warningMessageTitle", realm.getAttribute("warningMessageTitleEnglish"));
                attributes.put("infoMessageTitle", realm.getAttribute("infoMessageTitleEnglish"));
            }

            // Getting the CSPS maintenance mode execution config.
            AuthenticatorConfigModel authenticatorConfig = realm
                    .getAuthenticatorConfigByAlias("CSPS maintenance mode execution config");

            if (authenticatorConfig != null) {
                Boolean maintenance = Boolean.parseBoolean(authenticatorConfig.getConfig().get("maintenance"));
                if (maintenance) {
                    // The maintenance config is enabled, setting a theme attribute.
                    attributes.put("maintenanceModeEnabled", maintenance);
                }
            }
        }
    }
}

```

As you can see, i’m setting up attributes that are fetched from the realm attributes. Then my ftl files can access the attributes this way:

```auto
<@dangerMessage?interpret />

```

---

<div class="post-metadata">

**Author:** ![cedricguindon](https://yyz2.discourse-cdn.com/free1/user_avatar/forum.keycloak.org/cedricguindon/32/2670_2.png) [@cedricguindon](https://forum.keycloak.org/u/cedricguindon)\
**Post date:** [May 6, 2022, 12:29pm UTC](https://forum.keycloak.org/t/extending-freemarkerloginformsprovider-for-custom-theme-attributes/15401/2 "2022-05-06T12:29:25Z")

</div>

I’ve found this

> **[Configuring providers - Keycloak](https://www.keycloak.org/server/configuration-provider)**
>
> Keycloak is an open source identity and access management solution

I’ll give it a try and post some updates

---

<div class="post-metadata">

**Author:** ![cedricguindon](https://yyz2.discourse-cdn.com/free1/user_avatar/forum.keycloak.org/cedricguindon/32/2670_2.png) [@cedricguindon](https://forum.keycloak.org/u/cedricguindon)\
**Post date:** [May 10, 2022, 12:41pm UTC](https://forum.keycloak.org/t/extending-freemarkerloginformsprovider-for-custom-theme-attributes/15401/3 "2022-05-10T12:41:26Z")

</div>

The above seems to have done the trick.

I’ve modified my init script to start keycloak with the following 2 attributes:

```auto
/opt/keycloak/bin/kc.sh "${keycloak_cmd_arguments[@]}" --spi-login-freemarker-enabled=false --spi-login-csps-freemarker-login-messages-enabled=true

```

This starts keycloak with the SPI being updated.  
The theme can now access the variables.

---

<div class="post-metadata">

**Author:** ![mkopeyka](https://yyz2.discourse-cdn.com/free1/user_avatar/forum.keycloak.org/mkopeyka/32/790_2.png) [@mkopeyka](https://forum.keycloak.org/u/mkopeyka)\
**Post date:** [June 24, 2024, 10:46pm UTC](https://forum.keycloak.org/t/extending-freemarkerloginformsprovider-for-custom-theme-attributes/15401/4 "2024-06-24T22:46:52Z")

</div>

I’m trying to migrate from keycloak 20.0.2 to keycloak 25 and this parameter doesn’t work anymore

```auto
--spi-login-provider=freemarkerExt

```

I see this error when I try to open login page

```auto
ERROR [org.keycloak.services.error.KeycloakErrorHandler] (executor-thread-1) Uncaught server error: java.lang.NullPointerException: Cannot invoke "org.keycloak.forms.login.LoginFormsProvider.setAuthenticationSession(org.keycloak.sessions.AuthenticationSessionModel)" because the return value of "org.keycloak.models.KeycloakSession.getProvider(java.lang.Class)" is null
        at org.keycloak.protocol.AuthorizationEndpointBase.createAuthenticationSession(AuthorizationEndpointBase.java:214)

```

These parameters don’t help, the same error

```auto
--spi-login-freemarker-enabled=false --spi-login-freemarkerExt-enabled=true

```

---

<div class="post-metadata">

**Author:** ![madgeorge](https://avatars.discourse-cdn.com/v4/letter/m/f07891/32.png) [@madgeorge](https://forum.keycloak.org/u/madgeorge)\
**Post date:** [July 1, 2024, 10:51pm UTC](https://forum.keycloak.org/t/extending-freemarkerloginformsprovider-for-custom-theme-attributes/15401/5 "2024-07-01T22:51:41Z")

</div>

I am having the same issue! If you have found a workaround please share it !

---

<div class="post-metadata">

**Author:** ![mkopeyka](https://yyz2.discourse-cdn.com/free1/user_avatar/forum.keycloak.org/mkopeyka/32/790_2.png) [@mkopeyka](https://forum.keycloak.org/u/mkopeyka)\
**Post date:** [July 1, 2024, 11:15pm UTC](https://forum.keycloak.org/t/extending-freemarkerloginformsprovider-for-custom-theme-attributes/15401/6 "2024-07-01T23:15:42Z")

</div>

> The following logic is used to determine the default provider:
> 
> 1. The explicitly configured default provider
> 2. The provider with the highest order (providers with order ⇐ 0 are ignored)
> 3. The provider with the id set to `default`

so you need to override `getOrder` method in your factory.

```auto
    @Override
    public int order() {
        return 1;
    }

```

---

<div class="post-metadata">

**Author:** ![michael.carter.kbr](https://yyz2.discourse-cdn.com/free1/user_avatar/forum.keycloak.org/michael.carter.kbr/32/10324_2.png) [@michael.carter.kbr](https://forum.keycloak.org/u/michael.carter.kbr)\
**Post date:** [July 3, 2024, 2:27pm UTC](https://forum.keycloak.org/t/extending-freemarkerloginformsprovider-for-custom-theme-attributes/15401/7 "2024-07-03T14:27:20Z")

</div>

See my reply to [Inject dynamic variable from backend java to freemarker template - #3 by michael.carter.kbr](https://forum.keycloak.org/t/inject-dynamic-variable-from-backend-java-to-freemarker-template/26711/3)
