OrchardCMS / OrchardCore

Orchard Core is an open-source modular and multi-tenant application framework built with ASP.NET Core, and a content management system (CMS) built on top of that framework.
https://orchardcore.net
BSD 3-Clause "New" or "Revised" License
7.41k stars 2.39k forks source link

Translate a dynamic content #3607

Open hishamco opened 5 years ago

hishamco commented 5 years ago

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

sebastienros commented 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?

hishamco commented 5 years ago

Yep I saw the latest meeting it was interested .. I like your idea may be I add some if there's

sebastienros commented 5 years ago

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.

hishamco commented 5 years ago

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

hishamco commented 5 years ago

According to my talk with Seb in gitter the new design for dynamic localization will be:

1- Designing dynamic localization infrastructure APIs

2- 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)

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"

4- 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?

sebastienros commented 5 years ago

Some clarifications:

hishamco commented 5 years ago

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 ...

jrestall commented 5 years ago

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.

sebastienros commented 5 years ago

@jrestall should be doable, you'll have to provide the PR for the graphql support ;)

sebastienros commented 5 years ago

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.

hishamco commented 5 years ago

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

hishamco commented 5 years ago

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

jrestall commented 5 years ago

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.

hishamco commented 5 years ago

Sounds good

hishamco commented 5 years ago

IMHO the caching in IDataLocalizer will be an issue here unless we are doing sort of cache invalidation mechanism

hishamco commented 4 years ago

@sebastienros what's the plan for this? should be a part of 1.0.0 release or not

hishamco commented 3 years ago

Some of my thoughts about the admin screen:

Content Fields:

  1. Summary Content Types - Article Summary en
  2. Summary Content Types - Article résumé fr
  3. Summary Content Types - Article resumen es ....
Skrypt commented 3 years ago

Yeah, I agree with you that First PR should also provide some UI. Will review the PR tomorrow to see where we are at.

Skrypt commented 3 years ago

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.

hishamco commented 2 years ago

@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?

hishamco commented 2 years ago

IMHO we need another param along side with name in the localizer itself to make this happen

sebastienros commented 2 years ago

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.

hishamco commented 2 years ago

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?

sebastienros commented 2 years ago

If someone uses PO file ...

The context is used even if the data is stored in the database.

hishamco commented 2 years ago

Yes, I already used, but I confused by your last phrase. Anyway I will keep you updated on this