microsoft / AL

Home of the Dynamics 365 Business Central AL Language extension for Visual Studio Code. Used to track issues regarding the latest version of the AL compiler and developer tools available in the Visual Studio Code Marketplace or as part of the AL Developer Preview builds for Dynamics 365 Business Central.
MIT License
732 stars 243 forks source link

Un-maintainable logic behind the XLF trans-unit IDs #4361

Open JavierFuentes opened 5 years ago

JavierFuentes commented 5 years ago

Is your feature request related to a problem? Please describe. The logic under XLF trans-unit IDs is un-maintainable in the context of day to day updating our business code in our Business Central OnPremise instance.

For example, I have a Label inside a Table with its translation from English to Spanish...

After a revision, I refactor this Label to a Codeunit where I had others translated Labels inside a couple of procedures...

The result is that all the other Labels inside Codeunit have now a different ID in .g.xlf file, and therefore, this translations don't work anymore unless I recode all this too.

image

Describe the solution you'd like The trans-unit IDs shouldn't change never because breaks any previous translations you have.

Our native language is Spanish, but, because the compiler sets "en-US" by default in .g.xlf we can't set Captions and Labels in .AL files in Spanish hoping to translate the strings into English in an additional way from time to time without our users being affected.

It would be interesting to be able to indicate "es" as the native language of the App in app.json so that the Captions, Labels and other strings could be written in Spanish in AL code and the compiler would automatically generate a file .es.xlf instead of the file .g.xlf that now generates irremediably.

In this way, we would translate the translations from Spanish to other languages like English and not vice versa.

Additional context AL Language: 2.0.48254 Business Central: ES Dynamics NAV 13.0 (24630) OnPremise

atoader commented 5 years ago

Hi @JavierFuentes ! The unit-id is composed by concatenating the (Type + Hash(Name)) of all the symbols from the containing application object to the label location. This means that if you rename the codeunit, the ID will change, if you rename the method containing a label as a local variable, the ID will change, if you rename the label, the ID will change. We completely agree that this can be improved and we are planning on working on this in the future!

Your second point is also valid. I will mark this thread so that we consider it for future enhancements.

crodriguezinn commented 5 years ago

Hi @JavierFuentes,

We are a Spanish software development company (Innova Advanced Consulting) and we have created a solution to translate the translations in a simple way.

The behavior that you detail we found when we started to create solutions and decided to create a solution for translations.

If you are interested in the application you can search it in the Microsoft AppSource. It's BC Translate.

https://appsource.microsoft.com/es-es/product/dynamics-365-business-central/PUBID.innovationconsulting%7CAID.bctranslate%7CPAPPID.1b726e7f-61e4-47cd-8097-996641e97fb4?tab=Overview

It is also available to install in dockers on the portal https://www.innovaonline.es.

JavierFuentes commented 5 years ago

Hi @atoader, thanks for considering the idea of making changes to avoid this problem and also for hosting the idea of being able to configure our language as the primary language of the app and then translate it from it.

@crodriguezinn, I've seen your translation solution for BC and it looks very good... I congratulate you for the quality of your development and we may get to use it if at any time we use BC for a real project in my company in the future, because at the moment translations are a pain in OnPremises environment.

crodriguezinn commented 5 years ago

Hi @JavierFuentes ,

Thank for your comments.

The OnPremise and Cloud version use the same xliff files. Our solution has been create for BC Cloud and BC Docker, so you can use a BC Docker and create your translations files for OnPremise. This is our recomendation, use BC Docker for create your translations for Cloud, OnPremise, etc.

You can install BC docker and donwload the solution from portal https://www.innovaonline.es.

JavierFuentes commented 5 years ago

Hi @atoader, after starting with a semi-real project, I realized that the problem of maintaining translations goes beyond ...

I think that the translation files should only refer to each exact and different text string in the project and not the context of the Object-Field-Property-etc in which they have been included in our code...

For example, it is easy to imagine, the creation of a new Custom Field in a set of tables with exactly the same Name and Caption (Table36, T110, T112, T114 & T116 or Table38, T120, T122 & T124) ... we must now translate the same text strings successively times with the risk of doing it differently when the work is done manually.

Another easy-to-understand example is that since it is not possible at the moment to configure the Tooltip of a field at the level of Tables (I can not imagine why), it is necessary to do it at the level of Pages, the Tooltip of that same field.

Assuming that the text strings are accurate, it must be translated over and over and over again instead of making a single valid translation for all occurrences that may occur throughout our code ...

The last example that comes to mind is a set of Reports of similar structure (Invoices, Credit Memos and so ...) in which Columns based on Variables with Caption appear in all of them with the same text strings to show a greater cohesion to the end user ...

I know that the XLIFF format is a standard, but its use seems unfeasible in our OnPremise context of Daily and Internal Software Maintenance.

Surely there are other ways to translate each text string only once.

domelche commented 4 years ago

Hi, @atoader!

The unit-id is composed by concatenating the (Type + Hash(Name)) of all the symbols from the containing application object to the label location.

Could you please specify, what exactly do you mean by Hash() function? I want to be able to generate unit-ids on my own, is that even possible?

cr998 commented 3 years ago

I am also interested, someone who knows what hash function is used to generate the "trans-unit"?

garyguo1986 commented 3 years ago

I am also interested, someone who knows what hash function is used to generate the "trans-unit"?

I also have the problem because it difficult to mapping translatation line with object

sigurpallviggo commented 2 years ago

@garyguo1986 @cr998 @domelche

I believe they use a hash method used in the .NET compiler platform Roslyn. https://github.com/dotnet/roslyn/blob/main/src/Compilers/Core/Portable/InternalUtilities/Hash.cs

The hash method written in typescript:

export function HashObjectName(objectName: string): number {
  const buffer = Buffer.from(objectName, "utf16le");
  let hash = 0x811c9dc5; // 2166136261
  for (let i = 0; i < buffer.length; i++) {
    hash = hash ^ buffer[i];
    hash += (hash << 24) + (hash << 8) + (hash << 7) + (hash << 4) + (hash << 1);
  }
  hash = hash & 0xffffffff;
  return hash + 2147483647;
}
cr998 commented 1 year ago

Seems to be solved, this issue may be closed @JavierFuentes