Skip to content

Commit

Permalink
feat: add programatic access to labels in Agama (#10313)
Browse files Browse the repository at this point in the history
* docs: add FAQ entry for labels lookup from Java #10254

Signed-off-by: jgomer2001 <[email protected]>

* feat: allow access to i18n labels from code #10254

Signed-off-by: jgomer2001 <[email protected]>

---------

Signed-off-by: jgomer2001 <[email protected]>
Co-authored-by: YuriyZ <[email protected]>
  • Loading branch information
jgomer2001 and yuriyz authored Dec 3, 2024
1 parent ccb376c commit 1e91d9b
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 11 deletions.
16 changes: 15 additions & 1 deletion docs/janssen-server/developer/agama/faq.md
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ More advanced bean lookup capabilities are provided by method `instance` of [thi

### How to implement localization?

This topic is covered [here](./advanced-usages.md#localization).
This topic is covered [here](./advanced-usages.md#localization-and-internationalization).

### How to modify the built-in error pages?

Expand Down Expand Up @@ -178,6 +178,20 @@ See the examples in the Looping section of the [language reference](../../../aga

You can assign this value to a variable at the top of your loop declaration. See the examples in the Looping section of the [language reference](../../../agama/language-reference.md#looping).

### How to access localization labels from Java code?

In Freemarker, [localization](./advanced-usages.md#localization-and-internationalization) labels are accessed using the `${labels(key, ...)}` notation. The following would be a Java equivalent:

```
import io.jans.agama.engine.service.LabelsService;
...
lbls = io.jans.service.cdi.util.CdiUtil.bean(LabelsService.class);
String label = lbls.get("<label key>", ... optional extra params);
```

Note the localization context (language, country, etc.) used in such a call is based on the HTTP request that is taking place when the code is invoked.

### Can Agama code be called from Java?

No. These two languages are supposed to play roles that should not be mixed, check [here](./agama-best-practices.md#about-flow-design).
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,26 @@ public class LabelsService implements TemplateMethodModelEx {
//letters, digits, hypens, or sharp signs. Finally right bracket optionally followed by horizontal space
//A string matching the regex is used mark the beginning of a specific-locale section in a labels file
private static final Pattern SECTION_PATT = Pattern.compile("^\\[[ \\t]*([\\w-#]+)[ \\t]*\\][ \\t]*$");

@Inject
private Logger logger;

@Inject
private EngineConfig econf;

private Map<String, Map<String, Properties>> labelsMap; //Map<path id, Map<locale id, ....

public String get(String key, Object... args) {

Pair<String, Locale> p = getLocalizedLabel(key, CdiUtil.bean(WebContext.class).getLocale());
String label = p.getFirst();

if (label != null && args.length > 0) {
label = formatMessage(label, p.getSecond(), args);
}
return Objects.toString(label);

}

public Object exec(List args) throws TemplateModelException {

Expand Down Expand Up @@ -77,14 +89,7 @@ public Object exec(List args) throws TemplateModelException {
subArgs[i] = arg;
}
}
try {
MessageFormat mf = new MessageFormat(label);
Optional.ofNullable(p.getSecond()).ifPresent(mf::setLocale);
label = mf.format(subArgs, new StringBuffer(), null).toString();
} catch (Exception e) {
logger.error(e.getMessage(), e);
label = "error!";
}
label = formatMessage(label, p.getSecond(), subArgs);
}

return new SimpleScalar(Objects.toString(label)); //return "null" to avoid template render crash
Expand Down Expand Up @@ -172,6 +177,19 @@ private Pair<String, Locale> getLocalizedLabel(String key, Locale locale) {

}

private String formatMessage(String pattern, Locale locale, Object[] args) {

try {
MessageFormat mf = new MessageFormat(pattern);
Optional.ofNullable(locale).ifPresent(mf::setLocale);
return mf.format(args, new StringBuffer(), null).toString();
} catch (Exception e) {
logger.error(e.getMessage(), e);
return "error!";
}

}

private Properties propertiesFromSection(List<String> section) {

String cat = section.stream().reduce("", (a, b) -> a + "\n" + b );
Expand Down
2 changes: 1 addition & 1 deletion jans-casa/plugins/email_2fa/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@
<Plugin-Provider>Gluu Inc.</Plugin-Provider>
<Plugin-Class>io.jans.casa.plugins.emailotp.EmailOtpPlugin</Plugin-Class>
<Plugin-Description>
A plugin to enroll e-mail as a 2FA Credential
A plugin that registers a new authentication method so OTP via e-mail can be used as a 2FA credential
</Plugin-Description>
<Plugin-License>Apache 2</Plugin-License>
<Logger-Name>io.jans.casa.plugins</Logger-Name>
Expand Down

0 comments on commit 1e91d9b

Please sign in to comment.