Using FreeMarkerUtil missing the 'msg' bean

So, within a custom SPI I’m using FreeMarkerUtil to fetch a ftl file within the SPI ie. get the translated string programmatically and then send it to an API.

In this case, my ftl file looks very simple - its just one line e.g.

${msg("someKey")}

But for some reason, this breaks with the error

Caused by: freemarker.core.InvalidReferenceException: The following has evaluated to null or missing:
==> msg [in template "my-file.ftl"]

Any chances I can fix this by “autowiring” a msg bean when doing this – or is there some other way I can programmatically get a translated string from resource files?

The MessageBean is not magically available, you have to care about it yourself in your custom SPI.
See for example here in FreeMarkerLoginFormsProvider: keycloak/FreeMarkerLoginFormsProvider.java at 395bd447f2d5e05254d6150cc720874d9452fea4 · keycloak/keycloak · GitHub

I see that in FreeMarkerLoginFormsProvider, the MessageFormatterMethod gets injected as “msg” but from the current implementation of FreeMarkerUtil, it looks impossible to do it manually.

Any suggestions on how I can provide the MessageFormatterMethod implementation and inject it into the template that I’m processing with FreeMarkerUtil?

I got this done by actually doing what above comments suggest – manually instantiated and injected the MessageFormatterMethod into the ftl templates.

This can be done with something like:

      Properties properties = new Properties();
      properties.putAll(theme.getMessages(locale));
      String message = freeMarker.processTemplate(new HashMap<>() {
        {
          put("someCustomVar", someCustomVar);
          put("msg", new MessageFormatterMethod(locale, properties));
        }
      }, "some-template-name.ftl", theme);

Then the translations using the msg method within the freemarker template will work, like so

${msg("someKey")}