Open hishamco opened 5 years ago
Have you watched the most recent meeting where I explained the two potential designs, and the second one more specifically that I think is better? Meaning having a screen that shows all the detected dynamically localized strings and organizes them in categories?
Yep I saw the latest meeting it was interested .. I like your idea may be I add some if there's
To detect the missing localized strings, we need a custom interface (like IStringLocalizer and IHtmlLocalizer) like IDynamicStringLocalizer
. By calling this service for dynamic strings, we can do
D["The content is {ContentType}", typeDefinition.ContentType]
We can let the user enter custom strings, and we also can create translation strings providers that can tell the admin page what strings are available. For instance, ContentTypeTranslationProvider
which would return all content types, for the "ContentType" category.
The current implementation is return the same localization string if its missing which is the default behavior AFAIK in AspNetCore, so we can use LocalizedString.ResourceNotFound
property to collect the missing resources in ContentTypeDefinitionDataLocalizer
and list them in the admin per content type
According to my talk with Seb in gitter the new design for dynamic localization will be:
1- Designing dynamic localization infrastructure APIs
IStringLocalizer
and IHtmlLocalizer
, let us say IDataLocalizer
or IDynamicStringLocalizer
ILocalizationDataProvider
as a contract for providing the localization strings that will come from different places: content types, content fields .. ect2- Implementing localization strings providers The content for this localizer would be only for strings that are provided dynamically in the admin, like the content type names, the dynamic menu items, the field names (anything that is entered by a user)
ContentTypeLocalizationDataProvider
that will get all the available content types, and return them as string, same for content field names, admin menu items ... ect@T["This is a content type named {0}", D[contentType.Name"]]
3- Defining the localization strings As a translator, I want to be presented this list of strings, and their context, such that I can provide translations for each "supported culture"
ILocalizationDataProvider
and display these in the screen4- Loading & Storing the localization strings The admin screen is one way to provide the strings, but:
@sebastienros is there anything you need to add or shall I share my thought about the above points if there's?
Some clarifications:
ContentTypeLocalizationDataProvider
is only to provide the list of values that need to be translated, it's confusing that you mention it in your first section. But it's reassuring that you mention the actual interface (ILocalizaationDataProvider) in point 3@T["This is a content type named {0}", D[contentType.Name"]]
where T
is an IHtmlLocalizer
and D
is a DataLocalizer
.ContentTypeLocalizationDataProvider is only to provide the list of values that need to be translated
You're right, seems I add it in the wrong place, it nothing but an implementation details to provide a list of content types to be translated
"Localizer is HTML encoded". No, it is not
It's my fault I forgot to say "Not" :)
if we need to use a dynamic localization as part of a translated string, this will be done like this: @T["This is a content type named {0}", D[contentType.Name"]] where T is an IHtmlLocalizer and D is a DataLocalizer.
Right, seems what I mention is the part to use the data localization only
thanks a lot of your clarification, I already started one a PR for this, I will keep you on the loop ...
I'm really excited about this functionality. I'm thinking I'll be able to use the new admin screens to localize the text in my ReactJS site by making the localized strings available via GraphQL.
@jrestall should be doable, you'll have to provide the PR for the graphql support ;)
For the editor view, I assume we should not care about plurals as these are only single properties. Same in the API. So very simple, like StringLocalizer.
I assume we should not care about plurals as these are only single properties
While we are working on a dynamic data we can't expect what the plurals form are, unless we 're sure there's no case that requires a pluralization
I'm thinking I'll be able to use the new admin screens to localize the text in my ReactJS site by making the localized strings available via GraphQL.
@sebastienros is that mean we're not rely on the database only? while the localization string could come from many data sources
I'm thinking I'll be able to use the new admin screens to localize the text in my ReactJS site by making the localized strings available via GraphQL.
@sebastienros is that mean we're not rely on the database only? while the localization string could come from many data sources
No, I don't think so. I'll use a tool to scan the ReactJS codebase for strings and then output them to a recipe file so that they can be imported to the database.
Sounds good
IMHO the caching in IDataLocalizer
will be an issue here unless we are doing sort of cache invalidation mechanism
@sebastienros what's the plan for this? should be a part of 1.0.0 release or not
Some of my thoughts about the admin screen:
Categorize the screen according the ILocaliationDataProvider
implementations say
Content Types:
Content Fields:
Yeah, I agree with you that First PR should also provide some UI. Will review the PR tomorrow to see where we are at.
We have also Content Parts Fields in Content Types so I wonder if we should create a UI treeview to translate these also. These Content Parts are reusable on different Content Types so they could be translated only once.
So in the UI we could translate Content Types and Content Parts on the same lines. Need to read the code to analyze and see if it makes sense because we have a "Context" on these translations right?
Also, just looked at the code and didn't see any ILocalizationDataProvider for Content Parts.
Edit : I'm guessing right now that a Content Part is treated as a Content Type simply.
@sebastienros regarding the DataLocalizer
that we talked about, how it knows the context, in PO there type associated with IStringLocalizer<T>
will help to look for the resource, but here there's no need to pass a type parameter
So inD["Article"]
how it will knows that Article
is content type, menu or ... etc?
IMHO we need another param along side with name in the localizer itself to make this happen
Yes, it needs an extra argument for the context, but it has nothing to do with PO files, even though one could use a PO file for that.
but it has nothing to do with PO files, even though one could use a PO file for that
The context will be useful everywhere. If someone uses PO file as storge for dynamic data the context will be help to distinguish between content types, fields and so on similar to the database, am I right?
If someone uses PO file ...
The context is used even if the data is stored in the database.
Yes, I already used, but I confused by your last phrase. Anyway I will keep you updated on this
This is so hot!! I'm interested to make a prototype for it. The case here that there are many dynamic strings are not localization such as content definition display name, admin menu .. etc. We need to provide a way to localise them without breaking the current sites or database mechanism
Design steps
First PR
DataLocalizer
should read the data from the database as: Key, Context, Value(s) and CultureOrchardCore.DataLocalization
Module as a separated feature that can be enabled or disabledContentTypeLocalizationDataProvider
&ContentFieldLocalizationDataProvider
as implementation ofILocalizationDataProvider
to provide a strings that needs translations from both content types and content fieldsSecond PR
MenuItemLocalizationDataProvider
Third PR