mirror of
https://github.com/keycloak/keycloak.git
synced 2026-02-19 21:59:18 -06:00
added locale support to ClassLoaderTheme and FolderTheme
This commit is contained in:
@@ -31,10 +31,7 @@ import javax.ws.rs.core.UriBuilder;
|
|||||||
import javax.ws.rs.core.UriInfo;
|
import javax.ws.rs.core.UriInfo;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.util.HashMap;
|
import java.util.*;
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Properties;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
|
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
|
||||||
@@ -96,7 +93,7 @@ public class FreeMarkerAccountProvider implements AccountProvider {
|
|||||||
|
|
||||||
Properties messages;
|
Properties messages;
|
||||||
try {
|
try {
|
||||||
messages = theme.getMessages();
|
messages = theme.getMessages(Locale.GERMAN);
|
||||||
attributes.put("rb", messages);
|
attributes.put("rb", messages);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
logger.warn("Failed to load messages", e);
|
logger.warn("Failed to load messages", e);
|
||||||
|
|||||||
@@ -7,14 +7,7 @@ import org.keycloak.models.KeycloakSession;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.util.Collections;
|
import java.util.*;
|
||||||
import java.util.Comparator;
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.LinkedList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.ListIterator;
|
|
||||||
import java.util.Properties;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -228,11 +221,11 @@ public class ExtendingThemeManager implements ThemeProvider {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Properties getMessages() throws IOException {
|
public Properties getMessages(Locale locale) throws IOException {
|
||||||
Properties messages = new Properties();
|
Properties messages = new Properties();
|
||||||
ListIterator<Theme> itr = themes.listIterator(themes.size());
|
ListIterator<Theme> itr = themes.listIterator(themes.size());
|
||||||
while (itr.hasPrevious()) {
|
while (itr.hasPrevious()) {
|
||||||
Properties m = itr.previous().getMessages();
|
Properties m = itr.previous().getMessages(locale);
|
||||||
if (m != null) {
|
if (m != null) {
|
||||||
messages.putAll(m);
|
messages.putAll(m);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package org.keycloak.freemarker;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
|
import java.util.Locale;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -28,7 +29,7 @@ public interface Theme {
|
|||||||
|
|
||||||
public InputStream getResourceAsStream(String path) throws IOException;
|
public InputStream getResourceAsStream(String path) throws IOException;
|
||||||
|
|
||||||
public Properties getMessages() throws IOException;
|
public Properties getMessages(Locale locale) throws IOException;
|
||||||
|
|
||||||
public Properties getProperties() throws IOException;
|
public Properties getProperties() throws IOException;
|
||||||
|
|
||||||
|
|||||||
@@ -2,10 +2,13 @@ package org.keycloak.theme;
|
|||||||
|
|
||||||
import org.keycloak.freemarker.Theme;
|
import org.keycloak.freemarker.Theme;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
|
import java.util.Locale;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
|
import java.util.ResourceBundle;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
|
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
|
||||||
@@ -26,7 +29,7 @@ public class ClassLoaderTheme implements Theme {
|
|||||||
|
|
||||||
private String resourceRoot;
|
private String resourceRoot;
|
||||||
|
|
||||||
private String messages;
|
private String messageRoot;
|
||||||
|
|
||||||
private Properties properties;
|
private Properties properties;
|
||||||
|
|
||||||
@@ -43,7 +46,7 @@ public class ClassLoaderTheme implements Theme {
|
|||||||
|
|
||||||
this.templateRoot = themeRoot;
|
this.templateRoot = themeRoot;
|
||||||
this.resourceRoot = themeRoot + "resources/";
|
this.resourceRoot = themeRoot + "resources/";
|
||||||
this.messages = themeRoot + "messages/messages.properties";
|
this.messageRoot = themeRoot + "messages/";
|
||||||
this.properties = new Properties();
|
this.properties = new Properties();
|
||||||
|
|
||||||
URL p = classLoader.getResource(themeRoot + "theme.properties");
|
URL p = classLoader.getResource(themeRoot + "theme.properties");
|
||||||
@@ -102,9 +105,17 @@ public class ClassLoaderTheme implements Theme {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Properties getMessages() throws IOException {
|
public Properties getMessages(Locale locale) throws IOException {
|
||||||
Properties m = new Properties();
|
Properties m = new Properties();
|
||||||
URL url = classLoader.getResource(this.messages);
|
|
||||||
|
String message = null;
|
||||||
|
if(locale != null){
|
||||||
|
message = this.messageRoot + "messages_" + locale.toString() + ".properties";
|
||||||
|
}else{
|
||||||
|
message = this.messageRoot + "messages.properties";
|
||||||
|
}
|
||||||
|
|
||||||
|
URL url = classLoader.getResource(message);
|
||||||
if (url != null) {
|
if (url != null) {
|
||||||
m.load(url.openStream());
|
m.load(url.openStream());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import java.io.FileInputStream;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
|
import java.util.Locale;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -81,9 +82,17 @@ public class FolderTheme implements Theme {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Properties getMessages() throws IOException {
|
public Properties getMessages(Locale locale) throws IOException {
|
||||||
Properties m = new Properties();
|
Properties m = new Properties();
|
||||||
File file = new File(themeDir, "messages" + File.separator + "messages.properties");
|
|
||||||
|
String message = null;
|
||||||
|
if(locale != null){
|
||||||
|
message = "messages_" + locale.toString() + ".properties";
|
||||||
|
}else{
|
||||||
|
message = "messages.properties";
|
||||||
|
}
|
||||||
|
|
||||||
|
File file = new File(themeDir, "messages" + File.separator + message);
|
||||||
if (file.isFile()) {
|
if (file.isFile()) {
|
||||||
m.load(new FileInputStream(file));
|
m.load(new FileInputStream(file));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,118 @@
|
|||||||
|
logIn=Anmelden
|
||||||
|
logInTo=Anmelden bei
|
||||||
|
logInWith=Anmelden mit
|
||||||
|
noAccount=Neuer Benutzer?
|
||||||
|
register=Anmelden
|
||||||
|
registerWith=Anmelden mit
|
||||||
|
allRequired=Alle Felder sind erforderlich
|
||||||
|
alreadyHaveAccount=Haben Sie bereits ein Konto?
|
||||||
|
|
||||||
|
poweredByKeycloak=Powered by Keycloak
|
||||||
|
|
||||||
|
username=Benutzername
|
||||||
|
usernameOrEmail=Benutzername oder E-Mail
|
||||||
|
fullName=Voller Name
|
||||||
|
firstName=Vorname
|
||||||
|
lastName=Nachname
|
||||||
|
email=E-Mail
|
||||||
|
password=Passwort
|
||||||
|
rememberMe=Angemeldet bleiben
|
||||||
|
passwordConfirm=Passwort Bestätigen
|
||||||
|
passwordNew=Neues Passwort
|
||||||
|
passwordNewConfirm=Neues Passwort bestätigen
|
||||||
|
cancel=Abbrechen
|
||||||
|
accept=Akzeptieren
|
||||||
|
submit=Absenden
|
||||||
|
yes=Ja
|
||||||
|
no=Nein
|
||||||
|
|
||||||
|
authenticatorCode=Einmaliger Code
|
||||||
|
clientCertificate=Client Zertifikat
|
||||||
|
|
||||||
|
invalidUser=Ungültiger Benutzername oder Passwort.
|
||||||
|
invalidPassword=Ungültiger Benutzername oder Passwort.
|
||||||
|
invalidEmail=Invalid email address
|
||||||
|
accountDisabled=Account is disabled, contact admin
|
||||||
|
accountTemporarilyDisabled=Account is temporarily disabled, contact admin or try again later
|
||||||
|
expiredCode=Login timeout. Please login again
|
||||||
|
|
||||||
|
missingFirstName=Please specify first name
|
||||||
|
missingLastName=Please specify last name
|
||||||
|
missingEmail=Please specify email
|
||||||
|
missingUsername=Please specify username
|
||||||
|
missingPassword=Please specify password.
|
||||||
|
notMatchPassword=Passwords don't match
|
||||||
|
missingTotp=Please specify authenticator code
|
||||||
|
|
||||||
|
invalidPasswordExisting=Invalid existing password
|
||||||
|
invalidPasswordConfirm=Password confirmation doesn't match
|
||||||
|
invalidTotp=Invalid authenticator code
|
||||||
|
|
||||||
|
successTotp=Mobile authenticator configured.
|
||||||
|
successTotpRemoved=Mobile authenticator removed.
|
||||||
|
|
||||||
|
usernameExists=Username already exists
|
||||||
|
emailExists=Email already exists
|
||||||
|
|
||||||
|
federatedIdentityEmailExists=User with email already exists. Please login to account management to link the account.
|
||||||
|
federatedIdentityUsernameExists=User with username already exists. Please login to account management to link the account.
|
||||||
|
federatedIdentityDisabledRegistration=Registration of new users is not allowed. Please ask admin to register you and login to account management to link the account.
|
||||||
|
|
||||||
|
loginTitle=Log in to
|
||||||
|
loginOauthTitle=Temporary access.
|
||||||
|
loginOauthTitleHtml=Temporary access requested. Login to grant access.
|
||||||
|
loginForgot=Forgot
|
||||||
|
|
||||||
|
loginTotpTitle=Mobile Authenticator Setup
|
||||||
|
loginTotpStep1=Install <a href="https://fedorahosted.org/freeotp/" target="_blank">FreeOTP</a> or <a href="http://code.google.com/p/google-authenticator/" target="_blank">Google Authenticator</a> on your mobile
|
||||||
|
loginTotpStep2=Open the application and scan the barcode or enter the key
|
||||||
|
loginTotpStep3=Enter the one-time code provided by the application and click Submit to finish the setup
|
||||||
|
loginTotpOneTime=One-time code
|
||||||
|
|
||||||
|
loginProfileTitle=Update Account Information
|
||||||
|
loginProfileWarning=Your account is not enabled because you need to update your account information.
|
||||||
|
loginProfileWarningFollow=Please follow the steps below.
|
||||||
|
loginProfileError=Some required fields are empty or incorrect.
|
||||||
|
loginProfileErrorSteps=Please correct the fields in red.
|
||||||
|
|
||||||
|
oauthGrantTitle=OAuth Grant
|
||||||
|
oauthGrantTitleHtml=Temporary access requested
|
||||||
|
oauthGrantTerms=Keycloak Central Login and Google will use this information in accordance with their respective terms of service and privacy policies.
|
||||||
|
oauthGrantRequest=Do you grant these access privileges?
|
||||||
|
oauthGrantLoginRequest=Do you grant access?
|
||||||
|
|
||||||
|
emailVerifyTitle=Email verification
|
||||||
|
emailVerifyInstr=An email with instructions to verify your email address has been sent to you.
|
||||||
|
emailVerifyInstrQ=Haven't received a verification code in your email?
|
||||||
|
emailVerifyClick=Click here
|
||||||
|
emailVerifyResend=to re-send the email.
|
||||||
|
|
||||||
|
error=A system error has occured, contact admin
|
||||||
|
errorTitle=We're sorry...
|
||||||
|
errorTitleHtml=We're <strong>sorry</strong> ...
|
||||||
|
errorGenericMsg=Something happened and we could not process your request.
|
||||||
|
actionWarningHeader=Your account is not enabled.
|
||||||
|
actionTotpWarning=You need to set up Mobile Authenticator to activate your account.
|
||||||
|
actionProfileWarning=You need to update your user profile to activate your account.
|
||||||
|
actionPasswordWarning=You need to change your password to activate your account.
|
||||||
|
actionEmailWarning=You need to verify your email address to activate your account.
|
||||||
|
actionFollow=Please fill in the fields below.
|
||||||
|
|
||||||
|
errorKerberosLogin=Kerberos ticket not available. Authenticate with password.
|
||||||
|
|
||||||
|
successHeader=Success!
|
||||||
|
errorHeader=Error!
|
||||||
|
|
||||||
|
# Forgot password part
|
||||||
|
|
||||||
|
emailForgotHeader=Forgot Your Password?
|
||||||
|
backToLogin=« Back to Login
|
||||||
|
emailUpdateHeader=Update password
|
||||||
|
emailSent=You should receive an email shortly with further instructions.
|
||||||
|
emailSendError=Failed to send email, please try again later
|
||||||
|
emailError=Invalid email.
|
||||||
|
emailErrorInfo=Please, fill in the fields again.
|
||||||
|
emailInstruction=Enter your username or email address and we will send you instructions on how to create a new password.
|
||||||
|
|
||||||
|
accountUpdated=Your account has been updated
|
||||||
|
accountPasswordUpdated=Your password has been updated
|
||||||
@@ -0,0 +1,118 @@
|
|||||||
|
logIn=Log in
|
||||||
|
logInTo=Log in to
|
||||||
|
logInWith=Log in with
|
||||||
|
noAccount=New user?
|
||||||
|
register=Register
|
||||||
|
registerWith=Register with
|
||||||
|
allRequired=All fields are required
|
||||||
|
alreadyHaveAccount=Already have an account?
|
||||||
|
|
||||||
|
poweredByKeycloak=Powered by Keycloak
|
||||||
|
|
||||||
|
username=Username
|
||||||
|
usernameOrEmail=Username or email
|
||||||
|
fullName=Full name
|
||||||
|
firstName=First name
|
||||||
|
lastName=Last name
|
||||||
|
email=Email
|
||||||
|
password=Password
|
||||||
|
rememberMe=Remember me
|
||||||
|
passwordConfirm=Confirm password
|
||||||
|
passwordNew=New Password
|
||||||
|
passwordNewConfirm=New Password confirmation
|
||||||
|
cancel=Cancel
|
||||||
|
accept=Accept
|
||||||
|
submit=Submit
|
||||||
|
yes=Yes
|
||||||
|
no=No
|
||||||
|
|
||||||
|
authenticatorCode=One-time code
|
||||||
|
clientCertificate=Client Certificate
|
||||||
|
|
||||||
|
invalidUser=Invalid username or password.
|
||||||
|
invalidPassword=Invalid username or password.
|
||||||
|
invalidEmail=Invalid email address
|
||||||
|
accountDisabled=Account is disabled, contact admin
|
||||||
|
accountTemporarilyDisabled=Account is temporarily disabled, contact admin or try again later
|
||||||
|
expiredCode=Login timeout. Please login again
|
||||||
|
|
||||||
|
missingFirstName=Please specify first name
|
||||||
|
missingLastName=Please specify last name
|
||||||
|
missingEmail=Please specify email
|
||||||
|
missingUsername=Please specify username
|
||||||
|
missingPassword=Please specify password.
|
||||||
|
notMatchPassword=Passwords don't match
|
||||||
|
missingTotp=Please specify authenticator code
|
||||||
|
|
||||||
|
invalidPasswordExisting=Invalid existing password
|
||||||
|
invalidPasswordConfirm=Password confirmation doesn't match
|
||||||
|
invalidTotp=Invalid authenticator code
|
||||||
|
|
||||||
|
successTotp=Mobile authenticator configured.
|
||||||
|
successTotpRemoved=Mobile authenticator removed.
|
||||||
|
|
||||||
|
usernameExists=Username already exists
|
||||||
|
emailExists=Email already exists
|
||||||
|
|
||||||
|
federatedIdentityEmailExists=User with email already exists. Please login to account management to link the account.
|
||||||
|
federatedIdentityUsernameExists=User with username already exists. Please login to account management to link the account.
|
||||||
|
federatedIdentityDisabledRegistration=Registration of new users is not allowed. Please ask admin to register you and login to account management to link the account.
|
||||||
|
|
||||||
|
loginTitle=Log in to
|
||||||
|
loginOauthTitle=Temporary access.
|
||||||
|
loginOauthTitleHtml=Temporary access requested. Login to grant access.
|
||||||
|
loginForgot=Forgot
|
||||||
|
|
||||||
|
loginTotpTitle=Mobile Authenticator Setup
|
||||||
|
loginTotpStep1=Install <a href="https://fedorahosted.org/freeotp/" target="_blank">FreeOTP</a> or <a href="http://code.google.com/p/google-authenticator/" target="_blank">Google Authenticator</a> on your mobile
|
||||||
|
loginTotpStep2=Open the application and scan the barcode or enter the key
|
||||||
|
loginTotpStep3=Enter the one-time code provided by the application and click Submit to finish the setup
|
||||||
|
loginTotpOneTime=One-time code
|
||||||
|
|
||||||
|
loginProfileTitle=Update Account Information
|
||||||
|
loginProfileWarning=Your account is not enabled because you need to update your account information.
|
||||||
|
loginProfileWarningFollow=Please follow the steps below.
|
||||||
|
loginProfileError=Some required fields are empty or incorrect.
|
||||||
|
loginProfileErrorSteps=Please correct the fields in red.
|
||||||
|
|
||||||
|
oauthGrantTitle=OAuth Grant
|
||||||
|
oauthGrantTitleHtml=Temporary access requested
|
||||||
|
oauthGrantTerms=Keycloak Central Login and Google will use this information in accordance with their respective terms of service and privacy policies.
|
||||||
|
oauthGrantRequest=Do you grant these access privileges?
|
||||||
|
oauthGrantLoginRequest=Do you grant access?
|
||||||
|
|
||||||
|
emailVerifyTitle=Email verification
|
||||||
|
emailVerifyInstr=An email with instructions to verify your email address has been sent to you.
|
||||||
|
emailVerifyInstrQ=Haven't received a verification code in your email?
|
||||||
|
emailVerifyClick=Click here
|
||||||
|
emailVerifyResend=to re-send the email.
|
||||||
|
|
||||||
|
error=A system error has occured, contact admin
|
||||||
|
errorTitle=We're sorry...
|
||||||
|
errorTitleHtml=We're <strong>sorry</strong> ...
|
||||||
|
errorGenericMsg=Something happened and we could not process your request.
|
||||||
|
actionWarningHeader=Your account is not enabled.
|
||||||
|
actionTotpWarning=You need to set up Mobile Authenticator to activate your account.
|
||||||
|
actionProfileWarning=You need to update your user profile to activate your account.
|
||||||
|
actionPasswordWarning=You need to change your password to activate your account.
|
||||||
|
actionEmailWarning=You need to verify your email address to activate your account.
|
||||||
|
actionFollow=Please fill in the fields below.
|
||||||
|
|
||||||
|
errorKerberosLogin=Kerberos ticket not available. Authenticate with password.
|
||||||
|
|
||||||
|
successHeader=Success!
|
||||||
|
errorHeader=Error!
|
||||||
|
|
||||||
|
# Forgot password part
|
||||||
|
|
||||||
|
emailForgotHeader=Forgot Your Password?
|
||||||
|
backToLogin=« Back to Login
|
||||||
|
emailUpdateHeader=Update password
|
||||||
|
emailSent=You should receive an email shortly with further instructions.
|
||||||
|
emailSendError=Failed to send email, please try again later
|
||||||
|
emailError=Invalid email.
|
||||||
|
emailErrorInfo=Please, fill in the fields again.
|
||||||
|
emailInstruction=Enter your username or email address and we will send you instructions on how to create a new password.
|
||||||
|
|
||||||
|
accountUpdated=Your account has been updated
|
||||||
|
accountPasswordUpdated=Your password has been updated
|
||||||
@@ -17,10 +17,7 @@ import javax.mail.Session;
|
|||||||
import javax.mail.Transport;
|
import javax.mail.Transport;
|
||||||
import javax.mail.internet.InternetAddress;
|
import javax.mail.internet.InternetAddress;
|
||||||
import javax.mail.internet.MimeMessage;
|
import javax.mail.internet.MimeMessage;
|
||||||
import java.util.Date;
|
import java.util.*;
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Properties;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
|
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
|
||||||
@@ -82,7 +79,7 @@ public class FreeMarkerEmailProvider implements EmailProvider {
|
|||||||
ThemeProvider themeProvider = session.getProvider(ThemeProvider.class, "extending");
|
ThemeProvider themeProvider = session.getProvider(ThemeProvider.class, "extending");
|
||||||
Theme theme = themeProvider.getTheme(realm.getEmailTheme(), Theme.Type.EMAIL);
|
Theme theme = themeProvider.getTheme(realm.getEmailTheme(), Theme.Type.EMAIL);
|
||||||
|
|
||||||
String subject = theme.getMessages().getProperty(subjectKey);
|
String subject = theme.getMessages(Locale.GERMAN).getProperty(subjectKey);
|
||||||
String body = freeMarker.processTemplate(attributes, template, theme);
|
String body = freeMarker.processTemplate(attributes, template, theme);
|
||||||
|
|
||||||
send(subject, body);
|
send(subject, body);
|
||||||
|
|||||||
@@ -38,10 +38,7 @@ import javax.ws.rs.core.UriBuilder;
|
|||||||
import javax.ws.rs.core.UriInfo;
|
import javax.ws.rs.core.UriInfo;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.util.HashMap;
|
import java.util.*;
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Properties;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -173,7 +170,7 @@ public class FreeMarkerLoginFormsProvider implements LoginFormsProvider {
|
|||||||
|
|
||||||
Properties messages;
|
Properties messages;
|
||||||
try {
|
try {
|
||||||
messages = theme.getMessages();
|
messages = theme.getMessages(Locale.GERMAN);
|
||||||
attributes.put("rb", messages);
|
attributes.put("rb", messages);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
logger.warn("Failed to load messages", e);
|
logger.warn("Failed to load messages", e);
|
||||||
|
|||||||
Reference in New Issue
Block a user