Closed eXplowar closed 10 months ago
Perhaps it needs clarifying, but it's one FluentBundle
per language. If languages are similar, they can be handled by a single bundle, but I've yet to implement fallback languages.
Edit: also, what do you mean by enumerations
? Could you please provide a sketch of what you want to do? Like basic folder structure, and how enumerations related to .ftl
files?
@eXplowar I hope you haven't missed my reply. I would love to help you, but I need a bit more clarification.
@Ygg01, thank you for your attention to my issue. I creating an example. Later put his her.
what do you mean by enumerations Enum's
Basic folder structure for translations:
thank you for your attention to my issue.
No worries, I'm here to try to help!
That's a very peculiar pattern you have chosen for your project. Usually, translations are divided per language. For example, SS14 uses it for localization, and they have an entirely different structure.
This has the benefits that you can see what languages are available by scanning children folders of Translation
(i.e. en-US
, ru-RU
in below example), and just adding all subfolders of said translation to a bundle.
E.g. their structure goes something like this
Translations
|
+-- en-US
| |
| +-- cities.ftl
| |
| +-- common.ftl
| |
| +-- invoiceException.ftl
| |
| +-- Enum
| |
| +-- invoice.ftl
| |
| +-- payment.ftl
|
+-- ru-RU
|
... // mirrored structure
At the end of the day, files are just a logical separator, for ease of organization, all resources for a given language are dumped into the same Dictionary
.
You could theoretically have a big all in one translation file. E.g.
Translations
|
+-- en-US
| |
| +-- all_translations.ftl
|
+-- ru-RU
|
+-- all_translations.ftl
But it might be too challenging to navigate. Again, it depends on how you want to structure it.
Another thing to note if you find yourself with following pattern:
Entity = My entity
Entity-description = My entity description
Perhaps the better option would be to use fluent attributes
Entity = My Entity
.description = My Entity description
EDIT: I think I see what you mean. Having translations side by side would ease translation effort.
However, I'm not sure how could I help you? What would make your life easier?
@Ygg01, thanks for cool and detailed answer.
That's a very peculiar pattern you have chosen for your project. Usually, translations are divided per language. For example, SS14 uses it for localization, and they have an entirely different structure.
Perhaps. I will try take solusion from SS14. Thanks for alternative example.
At the end of the day, files are just a logical separator, for ease of organization, all resources for a given language are dumped into the same Dictionary.
I see that this is exactly how Linguini is designed. But tell me, won’t there be a problem if I have, say, both Invoice and Payment enums with similar "Paid" values? E.g. Invoice.Paid and Payment.Paid. The fact is that in the ftl-file that I write for them, the key has a value that matches the value of the enum, in our case Paid. I need this so that my extension method can find the translation by enum value. It seems to me that I will have to make a prefix to the key that corresponds to the name Enum... Perhaps this is not a big problem, and I will still make the prefix, it’s just that without it the ftl-file, which relates to some enum, is served a little more conveniently.
Perhaps the better option would be to use fluent attributes
Thanks for the information about fluent attributes.
But tell me, won’t there be a problem if I have, say, both Invoice and Payment enums with similar "Paid" values?
Yes. They would collide, and depending on how you insert a resource, it would either error out or just overwrite.
Keep in mind Fluent is a way to replace .properties
like translation resources. Each translation key is expected to be unique in application. I.e. Invoiced.Paid
and Payment.Paid
would become keys like Invoice-Paid
and Payment-Paid
. You could use reflection or some other convention to transform a call to Invoice
for Paid
string into an Invoice-Paid
id.
// assume this is a field in some internal helper class
public LinguiniBundle bundle;
public bool TryGetLocalization(string? classPrefix, string loc, IDictionary<string, IFluentType>? args, out string? message)
{
var id = classPrefix == null ? loc : $"{classPrefix}-{loc}";
// Note: `out _` is ignoring all errors, don't do this in actual code.
bundle.TryGetMessage(id, args, out _, out message)
}
EDIT: However, it would still require your translations to be written as Invoice-Paid
Good afternoon. There are about fifty enumerations in my ASP.NET Core Web API project. For each such enumeration, I have allocated ten language ftl files. Plus separate ftl contexts for general translations, separate ftl's for Exceptions. Everything is neatly arranged in folders. This ensures ease of translation management.
How to use Linguini correctly with this project structure?