diff --git a/docbook/reference/en/en-US/modules/themes.xml b/docbook/reference/en/en-US/modules/themes.xml
index cd59f382ad..10b2417a46 100755
--- a/docbook/reference/en/en-US/modules/themes.xml
+++ b/docbook/reference/en/en-US/modules/themes.xml
@@ -181,6 +181,12 @@ import=common/keycloak
messages/messages.properties inside your theme folder and add the following content:
username=Your Username
+
+ For the admin console, there is a second resource bundle named admin-messages.properties.
+ This resource bundle is converted to JSON and shipped to the console to be processed by
+ angular-translate. It is found in the same directory as messages.properties and can be overridden
+ in the same way as described above.
+
Modifying HTML
diff --git a/forms/common-themes/src/main/resources/theme/base/admin/angular-messages/common_de.properties b/forms/common-themes/src/main/resources/theme/base/admin/angular-messages/common_de.properties
deleted file mode 100644
index 2ad35ba6d2..0000000000
--- a/forms/common-themes/src/main/resources/theme/base/admin/angular-messages/common_de.properties
+++ /dev/null
@@ -1,6 +0,0 @@
-enabled=de Enabled
-name=de Name
-save=de Save
-cancel=de Cancel
-onText=AN
-offText=AUS
\ No newline at end of file
diff --git a/forms/common-themes/src/main/resources/theme/base/admin/angular-messages/common_en.properties b/forms/common-themes/src/main/resources/theme/base/admin/angular-messages/common_en.properties
deleted file mode 100644
index 7b6c509091..0000000000
--- a/forms/common-themes/src/main/resources/theme/base/admin/angular-messages/common_en.properties
+++ /dev/null
@@ -1,6 +0,0 @@
-enabled=Enabled
-name=Name
-save=Save
-cancel=Cancel
-onText=ON
-offText=OFF
\ No newline at end of file
diff --git a/forms/common-themes/src/main/resources/theme/base/admin/angular-messages/realm-settings_de.properties b/forms/common-themes/src/main/resources/theme/base/admin/messages/admin-messages_de.properties
similarity index 92%
rename from forms/common-themes/src/main/resources/theme/base/admin/angular-messages/realm-settings_de.properties
rename to forms/common-themes/src/main/resources/theme/base/admin/messages/admin-messages_de.properties
index 2643771c26..7721290988 100644
--- a/forms/common-themes/src/main/resources/theme/base/admin/angular-messages/realm-settings_de.properties
+++ b/forms/common-themes/src/main/resources/theme/base/admin/messages/admin-messages_de.properties
@@ -1,3 +1,12 @@
+# Common messages
+enabled=de Enabled
+name=de Name
+save=de Save
+cancel=de Cancel
+onText=AN
+offText=AUS
+
+# Realm settings
realm-detail.enabled.tooltip=de Users and clients can only access a realm if it's enabled
registrationAllowed=de User registration
registrationAllowed.tooltip=de Enable/disable the registration page. A link for registration will show on login page too.
diff --git a/forms/common-themes/src/main/resources/theme/base/admin/angular-messages/realm-settings_en.properties b/forms/common-themes/src/main/resources/theme/base/admin/messages/admin-messages_en.properties
similarity index 92%
rename from forms/common-themes/src/main/resources/theme/base/admin/angular-messages/realm-settings_en.properties
rename to forms/common-themes/src/main/resources/theme/base/admin/messages/admin-messages_en.properties
index 227c2f113d..bb66578f72 100644
--- a/forms/common-themes/src/main/resources/theme/base/admin/angular-messages/realm-settings_en.properties
+++ b/forms/common-themes/src/main/resources/theme/base/admin/messages/admin-messages_en.properties
@@ -1,3 +1,12 @@
+# Common messages
+enabled=Enabled
+name=Name
+save=Save
+cancel=Cancel
+onText=ON
+offText=OFF
+
+# Realm settings
realm-detail.enabled.tooltip=Users and clients can only access a realm if it's enabled
registrationAllowed=User registration
registrationAllowed.tooltip=Enable/disable the registration page. A link for registration will show on login page too.
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/AdminConsole.java b/services/src/main/java/org/keycloak/services/resources/admin/AdminConsole.java
index 31b1d22b76..2f845e0a8c 100755
--- a/services/src/main/java/org/keycloak/services/resources/admin/AdminConsole.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/AdminConsole.java
@@ -285,8 +285,7 @@ public class AdminConsole {
map.put("resourceUrl", Urls.themeRoot(baseUri) + "/admin/" + adminTheme);
map.put("resourceVersion", Version.RESOURCES_VERSION);
- ThemeProvider themeProvider = session.getProvider(ThemeProvider.class, "extending");
- Theme theme = themeProvider.getTheme(realm.getAdminTheme(), Theme.Type.ADMIN);
+ Theme theme = getTheme();
map.put("properties", theme.getProperties());
@@ -298,6 +297,11 @@ public class AdminConsole {
}
}
+ private Theme getTheme() throws IOException {
+ ThemeProvider themeProvider = session.getProvider(ThemeProvider.class, "extending");
+ return themeProvider.getTheme(realm.getAdminTheme(), Theme.Type.ADMIN);
+ }
+
@GET
@Path("{indexhtml: index.html}") // this expression is a hack to get around jaxdoclet generation bug. Doesn't like index.html
public Response getIndexHtmlRedirect() {
@@ -314,14 +318,14 @@ public class AdminConsole {
}
try {
- Properties msgs = AdminMessagesLoader.getMessages(lang);
+ Properties msgs = AdminMessagesLoader.getMessages(getTheme(), lang);
if (msgs.isEmpty()) {
logger.warn("Message bundle not found for language code '" + lang + "'");
- msgs = AdminMessagesLoader.getMessages("en"); // fall back to en
+ msgs = AdminMessagesLoader.getMessages(getTheme(), "en"); // fall back to en
}
if (msgs.isEmpty()) logger.fatal("Message bundle not found for language code 'en'");
-
+
return msgs;
} catch (IOException e) {
throw new RuntimeException(e);
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/AdminMessagesLoader.java b/services/src/main/java/org/keycloak/services/resources/admin/AdminMessagesLoader.java
index 709cb12684..df0ce27352 100644
--- a/services/src/main/java/org/keycloak/services/resources/admin/AdminMessagesLoader.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/AdminMessagesLoader.java
@@ -22,11 +22,13 @@ import java.io.FileInputStream;
import java.io.FilenameFilter;
import java.io.IOException;
import java.util.HashMap;
+import java.util.Locale;
import java.util.Map;
import java.util.Properties;
+import org.keycloak.freemarker.Theme;
/**
- * Simple loader for message bundles consumed by angular-translate.
+ * Simple loader and cache for message bundles consumed by angular-translate.
*
* Note that these bundles are converted to JSON before being shipped to the UI.
* Also, the content should be formatted such that it can be interpolated by
@@ -35,59 +37,18 @@ import java.util.Properties;
* @author Stan Silvert ssilvert@redhat.com (C) 2015 Red Hat Inc.
*/
public class AdminMessagesLoader {
- private static final String CONFIG_DIR = System.getProperty("jboss.server.config.dir");
- private static final String BUNDLE_DIR = CONFIG_DIR + "/themes/base/admin/angular-messages/";
-
private static final Map allMessages = new HashMap();
- static Properties getMessages(String locale) throws IOException {
- Properties messages = allMessages.get(locale);
+ static Properties getMessages(Theme theme, String strLocale) throws IOException {
+ String allMessagesKey = theme.getName() + "_" + strLocale;
+ Properties messages = allMessages.get(allMessagesKey);
if (messages != null) return messages;
- return loadMessages(locale);
- }
+ Locale locale = new Locale(strLocale);
+ messages = theme.getMessages("admin-messages", locale);
+ if (messages == null) return new Properties();
- private static Properties loadMessages(String locale) throws IOException {
- Properties masterMsgs = new Properties();
-
- for (File file : getBundlesForLocale(locale)) {
- try (FileInputStream msgStream = new FileInputStream(file)){
- Properties propsFromFile = new Properties();
- propsFromFile.load(msgStream);
- checkForDups(masterMsgs, propsFromFile, file, locale);
- masterMsgs.putAll(propsFromFile);
- }
- }
-
- allMessages.put(locale, masterMsgs);
- return masterMsgs;
- }
-
- private static void checkForDups(Properties masterMsgs, Properties propsFromFile, File file, String locale) {
- for (String prop : propsFromFile.stringPropertyNames()) {
- if (masterMsgs.getProperty(prop) != null) {
- String errorMsg = "Message bundle " + file.getName() + " contains key '" + prop;
- errorMsg += "', which already exists in another bundle for " + locale + " locale.";
- throw new RuntimeException(errorMsg);
- }
- }
- }
-
- private static File[] getBundlesForLocale(String locale) {
- File bundleDir = new File(BUNDLE_DIR);
- return bundleDir.listFiles(new LocaleFilter(locale));
- }
-
- private static class LocaleFilter implements FilenameFilter {
- private final String locale;
-
- public LocaleFilter(String locale) {
- this.locale = locale;
- }
-
- @Override
- public boolean accept(File dir, String name) {
- return name.endsWith("_" + locale + ".properties");
- }
+ allMessages.put(allMessagesKey, messages);
+ return messages;
}
}