Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support multiple named locales #39

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,13 @@

package com.squarespace.template;

import java.util.ArrayList;
import java.util.List;
import java.util.Locale;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.squarespace.cldrengine.api.Pair;
import com.squarespace.template.expr.ExprOptions;


Expand All @@ -37,6 +40,7 @@ public class CompilerExecutor {
private ObjectNode injectablesMap;
private StringBuilder buffer;
private Locale locale;
private List<Pair<String, Locale>> locales;
private LoggingHook loggingHook;
private CodeLimiter codeLimiter;
private boolean safeExecution;
Expand Down Expand Up @@ -85,6 +89,11 @@ public Context execute() throws CodeException {
if (locale != null) {
ctx.javaLocale(locale);
}
if (locales != null) {
for (Pair<String, Locale> entry : locales) {
ctx.localeManager().addLocale(entry._1, entry._2);
}
}
if (now != null) {
ctx.now(now);
}
Expand Down Expand Up @@ -185,6 +194,17 @@ public CompilerExecutor locale(Locale locale) {
return this;
}

/**
* Additional named locales that can be selected by formatters.
*/
public CompilerExecutor locale(String name, Locale locale) {
if (this.locales == null) {
this.locales = new ArrayList<>(2);
}
this.locales.add(Pair.of(name, locale));
return this;
}

/**
* Hook for logging exceptions that occur during execution.
*/
Expand Down
58 changes: 17 additions & 41 deletions core/src/main/java/com/squarespace/template/Context.java
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@
import com.fasterxml.jackson.databind.node.IntNode;
import com.fasterxml.jackson.databind.node.MissingNode;
import com.squarespace.cldrengine.CLDR;
import com.squarespace.cldrengine.api.CLocale;
import com.squarespace.template.expr.ExprOptions;


Expand All @@ -51,11 +50,7 @@ public class Context {

private static final String META_RIGHT = "}";

private Locale javaLocale;

private CLDR cldrengine;

private MessageFormats messageformats;
private LocaleManager localeManager;

private Compiler compiler;

Expand Down Expand Up @@ -111,7 +106,7 @@ public Context(JsonNode node, Locale locale) {
public Context(JsonNode node, StringBuilder buf, Locale locale) {
this.currentFrame = new Frame(null, node == null ? MissingNode.getInstance() : node);
this.buf = buf == null ? new StringBuilder() : buf;
this.javaLocale = locale == null ? Locale.US : locale;
this.localeManager = new LocaleManager(locale == null ? Locale.US : locale);
}

public boolean safeExecutionEnabled() {
Expand All @@ -136,55 +131,36 @@ public void exprOptions(ExprOptions options) {
this.exprOptions = options;
}

public Locale javaLocale() {
return javaLocale;
public LocaleManager localeManager() {
return this.localeManager;
}

public void javaLocale(Locale locale) {
this.javaLocale = locale;
public Locale javaLocale() {
return this.localeManager.get().locale();
}

public void now(Long value) {
this.now = value;
public void javaLocale(Locale locale) {
this.localeManager.setLocale(locale);
}

public Long now() {
return now;
public CLDR cldr() {
return this.localeManager.get().cldr();
}

// public void cldrLocale(CLDR.Locale locale) {
// this.cldrLocale = locale;
// }
//
// public CLDR.Locale cldrLocale() {
// return cldrLocale;
// }

public MessageFormats messageFormatter() {
if (this.messageformats == null) {
this.messageformats = new MessageFormats(this.cldr());
}
return this.messageformats;
}

public CLDR cldr() {
if (cldrengine == null) {
String tag = javaLocale != null ? this.javaLocale.toLanguageTag() : "en-US";
this.cldrengine = com.squarespace.cldrengine.CLDR.get(tag);
}
return cldrengine;
return this.localeManager.get().formatter();
}

public void cldrengine(CLDR cldr) {
this.cldrengine = cldr;
public void addLocale(String name, Locale locale) {
this.localeManager.addLocale(name, locale);
}

public void cldrengine(String id) {
this.cldrengine = CLDR.get(id);
public void now(Long value) {
this.now = value;
}

public void cldrengine(CLocale locale) {
this.cldrengine = CLDR.get(locale);
public Long now() {
return now;
}

/**
Expand Down
66 changes: 66 additions & 0 deletions core/src/main/java/com/squarespace/template/LocaleManager.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
package com.squarespace.template;

import java.util.HashMap;
import java.util.Locale;
import java.util.Map;

import com.squarespace.cldrengine.CLDR;

public class LocaleManager {

public static final String DEFAULT = "main";
private final Map<String, Entry> entries = new HashMap<>(2);

public LocaleManager() {
this.entries.put(DEFAULT, new Entry(Locale.US));
}

public LocaleManager(Locale locale) {
this.entries.put(DEFAULT, new Entry(locale));
}

public void setLocale(Locale locale) {
this.entries.put(DEFAULT, new Entry(locale));
}

public void addLocale(String name, Locale locale) {
this.entries.put(name, new Entry(locale));
}

public Entry get() {
return this.entries.get(DEFAULT);
}

public Entry get(String name) {
Entry entry = this.entries.get(name);
return entry == null ? this.entries.get(DEFAULT) : entry;
}

public static class Entry {

private final Locale locale;
private final CLDR cldr;
private MessageFormats formatter;

public Entry(Locale locale) {
this.locale = locale;
this.cldr = CLDR.get(locale);
}

public Locale locale() {
return this.locale;
}

public CLDR cldr() {
return this.cldr;
}

public MessageFormats formatter() {
if (this.formatter == null) {
this.formatter = new MessageFormats(this.cldr);
}
return this.formatter;
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -104,8 +104,8 @@ private String currency(List<Object> args, List<String> options) {
Decimal value = this.converter.asDecimal(decimalValue);
String code = this.converter.asString(currencyCode);
CurrencyType currency = CurrencyType.fromString(code);
CurrencyFormatOptions opts = OptionParsers.currency(options);
return cldr.Numbers.formatCurrency(value, currency, opts);
Options<CurrencyFormatOptions> opts = OptionParsers.currency(options);
return cldr.Numbers.formatCurrency(value, currency, opts.inner());
}

/**
Expand All @@ -121,8 +121,8 @@ private String datetime(List<Object> args, List<String> options) {
}
long epoch = node.asLong();
CalendarDate date = cldr.Calendars.toGregorianDate(epoch, zoneId);
DateFormatOptions opts = OptionParsers.datetime(options);
return cldr.Calendars.formatDate(date, opts);
Options<DateFormatOptions> opts = OptionParsers.datetime(options);
return cldr.Calendars.formatDate(date, opts.inner());
}

/**
Expand All @@ -137,8 +137,8 @@ private String decimal(List<Object> args, List<String> options) {
return "";
}
Decimal value = this.converter.asDecimal(node);
DecimalFormatOptions opts = OptionParsers.decimal(options);
return cldr.Numbers.formatDecimal(value, opts);
Options<DecimalFormatOptions> opts = OptionParsers.decimal(options);
return cldr.Numbers.formatDecimal(value, opts.inner());
}

/**
Expand All @@ -155,8 +155,8 @@ private String interval(List<Object> args, List<String> options) {
}
CalendarDate start = cldr.Calendars.toGregorianDate(v1.asLong(0), zoneId);
CalendarDate end = cldr.Calendars.toGregorianDate(v2.asLong(0), zoneId);
DateIntervalFormatOptions opts = OptionParsers.interval(options);
return cldr.Calendars.formatDateInterval(start, end, opts);
Options<DateIntervalFormatOptions> opts = OptionParsers.interval(options);
return cldr.Calendars.formatDateInterval(start, end, opts.inner());
}

private static class ArgConverter extends DefaultMessageArgConverter {
Expand Down