quarkusio / quarkus

Quarkus: Supersonic Subatomic Java.
https://quarkus.io
Apache License 2.0
13.82k stars 2.69k forks source link

Add support for i18n to Qute templating engine #7665

Closed esteveavi closed 2 years ago

esteveavi commented 4 years ago

Description Add support for i18n to Qute templating engine

Implementation ideas Use different localized files to inject i18n texts in the rendering engine: qute_i18n_en-GB.properties qute_i18n_es-ES.properties

In the template: {i18n.subject}

Call: return appointmentConfirmationMail .to(to) .subject(subject) // the template looks like: Hello {name}! .data("branchName", branchName) .locale("es_ES") .replyTo(replyTo) .send()

quarkusbot commented 4 years ago

/cc @mkouba

mkouba commented 4 years ago

I think that the i18n support should be build on top java.util.ResourceBundle, if possible.

Currently, the simplest solution (at least in the JVM mode) would be to pass an instance of ResourceBundle created by java.util.ResourceBundle.getBundle(String, Locale) and access the localized messages through {bundle.getString('my.message')}. We would need some tweaks for native image though.

Also a simple extension like this

@TemplateExtension(matchName = ANY)
static String get(ResourceBundle bundle, String key) {
    return bindle.getString(key);
}

should work even now: {bundle['my.message']}.

gsmet commented 4 years ago

If we do that, please let's make the properties UTF-8 encoded. Otherwise, this quickly is a nightmare.

esteveavi commented 4 years ago

Martin,

Tried your approach:

ResourceBundle bundle = ResourceBundle.getBundle("i18n.messages", new Locale("es", "ES"));

return appointmentConfirmationMail .to(to) .subject(subject) .data("appointmentCode", "CODE") .data("branchName", branchName) .data("serviceName", serviceName) .data("appointmentDatetime", appointmentDatetime.format(DateTimeFormatter.ISO_LOCAL_DATE_TIME)) .data("bundle", bundle) .replyTo(replyTo) .send();

Then in the mail template: <span style="line-height: 28px; font-size: 24px;">Gràcies per confiar en nosaltres! {bundle.getString("mail.confirmation.body.thankyou")}

Result:

<span style="line-height: 28px; font-size: 24px;">Gràcies per confiar en nosaltres!

NOT_FOUND

It seems it doesn't work.

Thank you.

On Mon, Mar 9, 2020 at 11:13 AM Guillaume Smet notifications@github.com wrote:

If we do that, please let's make the properties UTF-8 encoded. Otherwise, this quickly is a nightmare.

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/quarkusio/quarkus/issues/7665?email_source=notifications&email_token=AAEREWQF3WY7NT7ONY2SXDLRGS6LNA5CNFSM4LDNGJZ2YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEOGPLZY#issuecomment-596440551, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAEREWTYON4GHE5QT33APJDRGS6LNANCNFSM4LDNGJZQ .

-- Esteve Avilés

mkouba commented 4 years ago

@esteveavi JVM mode or native image? I have to admit that I did not test this yet. Is the correct ResourceBundle instance found?

esteveavi commented 4 years ago

Jvm. ResourceBundle resolves successfully.

On Mon, 9 Mar 2020 at 16:45, Martin Kouba notifications@github.com wrote:

@esteveavi https://github.com/esteveavi JVM mode or native image? I have to admit that I did not test this yet. Is the correct ResourceBundle instance found?

— You are receiving this because you were mentioned.

Reply to this email directly, view it on GitHub https://github.com/quarkusio/quarkus/issues/7665?email_source=notifications&email_token=AAEREWWJUE53KMFV5EQRLF3RGUFLJA5CNFSM4LDNGJZ2YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEOHYZSY#issuecomment-596610251, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAEREWSNI55QNW7VTTPLE4LRGUFLJANCNFSM4LDNGJZQ .

-- Esteve Avilés

mkouba commented 4 years ago

@esteveavi Ah, sorry. This could not work out of the box because we only use reflection fallback resolver to access properties. For a method with params you would either have to add an extension method similar to the one from my previous comment or add @TemplateData(target=java.util.ResourceBundle.class,properties=false) to some application class.

esteveavi commented 4 years ago

Martin, I can't make it work. I need to switch between locales:

this.bundle = ResourceBundle.getBundle("i18n.messages", new Locale( "es", "ES"));

Best regards,

On Tue, Mar 10, 2020 at 1:07 PM Martin Kouba notifications@github.com wrote:

@esteveavi https://github.com/esteveavi Ah, sorry. This could not work out of the box because we only use reflection fallback resolver to access properties. For a method with params you would either have to add an extension method similar to the one from my previous comment or add @TemplateData(target=java.util.ResourceBundle.class,properties=false) to some application class.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/quarkusio/quarkus/issues/7665?email_source=notifications&email_token=AAEREWRC5NFYWP7M5F4SZSDRGYUQRA5CNFSM4LDNGJZ2YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEOLESNA#issuecomment-597051700, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAEREWXGBXJWVVFG3WNSYRDRGYUQRANCNFSM4LDNGJZQ .

-- Esteve Avilés

esteveavi commented 4 years ago

ok,

Make it work with something like this:

@RequestScoped

public class MailerService {

private static final Logger logger = LogManager.getLogger (MailerService.class);

@Inject

@ResourcePath(value="mail/appointment/v1/newAppointment")

MailTemplate appointmentConfirmationMail;

@ConfigProperty(name = "mail.appointment.replyto")

String replyTo;

private ResourceBundle bundle;

public CompletionStage sendAppointmentConfirmationMail(

String to,

String subject,

String branchName,

String serviceName,

LocalDateTime appointmentDatetime) {

this.bundle = ResourceBundle.getBundle("i18n.messages", new Locale( "es", "ES"));

logger.debug(" - Test mail bundle result: {} ", bundle.getString( "mail.confirmation.body.thankyou"));

return appointmentConfirmationMail

.to(to)

.subject(subject)

// the template looks like: Hello {name}!

.data("appointmentCode", "CODE")

.data("branchName", branchName)

.data("serviceName", serviceName)

.data("appointmentDatetime", appointmentDatetime.format(DateTimeFormatter. ISO_LOCAL_DATE_TIME))

.data("bundle", bundle)

.replyTo(replyTo)

.send();

}

@TemplateExtension

static String i18Text(ResourceBundle bundle, String key) {

*return* bundle.getString(key);

}

}

On Sat, Mar 14, 2020 at 7:49 AM Esteve Avilés eavilesa@gmail.com wrote:

Martin, I can't make it work. I need to switch between locales:

this.bundle = ResourceBundle.getBundle("i18n.messages", new Locale( "es", "ES"));

Best regards,

On Tue, Mar 10, 2020 at 1:07 PM Martin Kouba notifications@github.com wrote:

@esteveavi https://github.com/esteveavi Ah, sorry. This could not work out of the box because we only use reflection fallback resolver to access properties. For a method with params you would either have to add an extension method similar to the one from my previous comment or add @TemplateData(target=java.util.ResourceBundle.class,properties=false) to some application class.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/quarkusio/quarkus/issues/7665?email_source=notifications&email_token=AAEREWRC5NFYWP7M5F4SZSDRGYUQRA5CNFSM4LDNGJZ2YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEOLESNA#issuecomment-597051700, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAEREWXGBXJWVVFG3WNSYRDRGYUQRANCNFSM4LDNGJZQ .

-- Esteve Avilés

-- Esteve Avilés

mkouba commented 4 years ago

Why do you store the bundle in MailerService.bundle? data("bundle", ResourceBundle.getBundle("i18n.messages", new Locale("es", "ES"))) should work.

Anyway, the i18Text extension method looks good and is more efficient than generating a resolver for the whole ResourceBundle class.

nimo23 commented 4 years ago

In JSF I18N can be made with i18n.properties files. Maybe Qute can adapt from it?

gsmet commented 4 years ago

@mkouba btw, there are a few neat ideas in this project: https://projectfluent.org/ .

mkouba commented 4 years ago

@gsmet "translation resources used by Fluent is called FTL" seems like a name conflict with FreeMarker ;-). Anyway, thanks for the tip!

mkouba commented 4 years ago

For the record - in Quarkus 1.7.0 there will be Type-safe Message Bundles powered by Qute.

tlvenn commented 4 years ago

Hi @mkouba, any pointer as to how to set the locale that should be used with a given template using the new Type safe Message bundles with Qute ? I have a language filter which will decide which language should be used to render a given RestEasy request but I have no clue on how to pass down this to Qute.

Is there an attribute I can set on a given template to force the locale for example ?

Thanks in advance

mkouba commented 4 years ago

@tlvenn Yes, you can set an attribute of a template instance via TemplateInstance#setAttribute(); the key is locale or MessageBundles.ATTRIBUTE_LOCALE, see for example https://github.com/quarkusio/quarkus/blob/master/extensions/qute/deployment/src/test/java/io/quarkus/qute/deployment/i18n/MessageBundleTest.java#L73

tlvenn commented 4 years ago

Thanks !

batashi commented 4 years ago

Can we expect something here soon?

mkouba commented 4 years ago

@batashi As mentioned in https://github.com/quarkusio/quarkus/issues/7665#issuecomment-653549750 we implemented the type-safe message bundles. No further work is planned in this area. Feel free to contribute ;-).

tlvenn commented 4 years ago

@mkouba unless I am missing something, it seems like it's impossible to set the locale for an email template ?

mkouba commented 4 years ago

@tlvenn I don't think so, file a new issue pls.

mkouba commented 2 years ago

I'm going to close this one. Feel free to file new issues with concrete ideas/proposals.