sunng87 / handlebars-rust

Rust templating with Handlebars

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Handling localization for data?

HiImJulien opened this issue · comments

Hey there!

I have two email templates A and B. A is indented for an international audience whereas B is targeted at a German audience.

Both templates provide a placeholder to set the date of the generated email. The backend represents the timestamp using chrono::DateTime<Utc>. This results in strings such as 2023-10-11T22:11:27.902255300Z whereas strings such as 11.10.2023 or 10/11/2023 are desired. Strings such as 11th March 23 would also be a possibility.

My current workaround is to pass a localized string, which requires the backend to have knowledge of the preferred format.

Is it possible to control the serialization process (with
handlebars or the rhai extensions) to achieve a desired outcome?

Thanks in advance!

Hi @HiImJulien , I would recommend your current solution too. Because template engine has no context about user's preference, it's not possible to format the date in helper unless you give user's preference as data to template. It will be identical to do it in backend. (Note that template rendering also happens in backend).

My bad, it's less about the user preference than the "template preference". Would it be possible to access the underlying value using a helper e.g.:

{{ formatDate varDate 'de' }}

or

{{ formatDate varDate 'en' }}

or even

{{ formatDate varDate '%d.%m.%y' }}?

Or is the data serialized before the helper can access them?

I see. Thank you for clarification. But before we send data into template's rendering process, it has to be converted to serde_json::Value types so it's impossible to retain chrono::DateTime and you still need to do it in backend code.

you still need to do it in backend code.

And I again, I failed to express my intent clearly 😅.
I understand, that the procedure still runs in the "backend"; it doesn't matter to me. However, it's important for me to control form the template how it's being formatted in the end.

I think I have an idea for an workaround:


The basic idea is to use the serde's serialize_with attribute to transform the date to a numeric timestamp or an object (either Value::Number or Value::Object).

Then create a custom helper to_date_str with two parameters timestamp and format. I.e. the following pseudo code:

fn to_date_str(timestamp: i64, fmt: String) -> String {
    let datetime = DateTime::from_timestamp(timestamp);
    return datetime.format(fmt);
}

This would allow me to do something like this

{{ to_date_str email.date "DD.MM.YYYY" }}

What confuses me, however, is when you are taking a look at the example. On line 10, there is this line:

handlebars_helper!(date: |dt: OffsetDateTime| dt.format(&parse("[year]-[month]-[day]").unwrap()).unwrap());

How can the helper access a value of type OffsetDateTime? Or can I use any type as long as it's deserializable?