Badgerati / Pode

Pode is a Cross-Platform PowerShell web framework for creating REST APIs, Web Sites, and TCP/SMTP servers
https://badgerati.github.io/Pode
MIT License
830 stars 92 forks source link

Enhanced Internationalization Support (i18n) #1320

Closed mdaneri closed 2 months ago

mdaneri commented 3 months ago

Description of the Change

Enhanced Internationalization Support (i18n)

Related Issue

1285

Badgerati commented 3 months ago

I'll go through this one when I've got a good chunk of time free, possibly this weekend. I have had some additional thoughts on how we might make localisation a base feature in Pode as well, which other people can re-use - such as Pode.Web.

For example, having strings available as $locale:<key>. When I go through this, I'll see if we can merge the two localisations ideas, or if they're distinctly separate features.

mdaneri commented 3 months ago

Personally, I'll keep it separate. Pode.Web requirements are a bit different. You want the user to be able to i18n their application. In the context of Pode, it's more of a system thing. Sure, we can implement something that allows the user to i18n everything inside a Route, but it should differ from the exception message generated by Pode.

I load the language in Pode.psm1 as first thing and assign the content to $global:msgTable. But we can add an additional variable for the user to use

mdaneri commented 3 months ago

I've no idea why it's failing on Ubuntu. I tried on Centos and works fine

mdaneri commented 3 months ago

Looks like the global message variable is not injected inside the runspace

mdaneri commented 3 months ago

I tried to convert the Pode.psd1 to a hashtable

@{
  noCertificateFoundExceptionMessage = "No certificate could be found in {0}{1} for '{2}'"
  incompatiblePodeDllExceptionMessage = "An existing incompatible Pode.DLL version {0} is loaded. Version {1} is required. Open a new Powershell/pwsh session and retry."
  noOpenApiUrlSuppliedExceptionMessage = "No OpenAPI URL supplied for {0}."
  noPathSuppliedForRouteExceptionMessage = "No Path supplied for the Route."
  invalidJsonJwtExceptionMessage = "Invalid JSON value found in JWT"
....

This is the error

Import-LocalizedData: The following error occurred while PowerShell was loading the 'C:\Users\m_dan\Documents\GitHub\Pode\src\Locales\en\Pode.psd1' script data file: At line:48 char:104 + … SE connection Name is required either from -Name or $WebEvent.Sse.Nam … +                                                    
   ~~~~~~~~~ A
variable that cannot be referenced in restricted language mode or a Data section is being referenced. Variables that can be referenced include the following: $PSCulture, $PSUICulture, $true, $false, $null.  At line:135 char:63 + … ForUsingVariableNotFoundExceptionMessage = "Value for '$using ={0}' c … +           
~~~~~~ A variable that cannot be referenced in restricted language mode or a Data section is being referenced. Variables that can be referenced include the following: $PSCulture, $PSUICulture, $true, $false, $null..

Import-LocalizedData wantsConvertFrom-StringData -StringData

mdaneri commented 3 months ago

I added some documentation to the Tutorial/Basic part. But I think to write also a getting started paragraph

Badgerati commented 3 months ago

I tried to convert the Pode.psd1 to a hashtable

@{
  noCertificateFoundExceptionMessage = "No certificate could be found in {0}{1} for '{2}'"
  incompatiblePodeDllExceptionMessage = "An existing incompatible Pode.DLL version {0} is loaded. Version {1} is required. Open a new Powershell/pwsh session and retry."
  noOpenApiUrlSuppliedExceptionMessage = "No OpenAPI URL supplied for {0}."
  noPathSuppliedForRouteExceptionMessage = "No Path supplied for the Route."
  invalidJsonJwtExceptionMessage = "Invalid JSON value found in JWT"
....

This is the error

Import-LocalizedData: The following error occurred while PowerShell was loading the 'C:\Users\m_dan\Documents\GitHub\Pode\src\Locales\en\Pode.psd1' script data file: At line:48 char:104 + … SE connection Name is required either from -Name or $WebEvent.Sse.Nam … +                                                    
   ~~~~~~~~~ A
variable that cannot be referenced in restricted language mode or a Data section is being referenced. Variables that can be referenced include the following: $PSCulture, $PSUICulture, $true, $false, $null.  At line:135 char:63 + … ForUsingVariableNotFoundExceptionMessage = "Value for '$using ={0}' c … +           
~~~~~~ A variable that cannot be referenced in restricted language mode or a Data section is being referenced. Variables that can be referenced include the following: $PSCulture, $PSUICulture, $true, $false, $null..

Import-LocalizedData wantsConvertFrom-StringData -StringData

I've just tested this myself, and reproduced the error. It's because the $WebEvent variable in the following wasn't being escaped:

sseConnectionNameRequiredExceptionMessage = An SSE connection Name is required, either from -Name or $WebEvent.Sse.Name

In mine hashtable conversion:

sseConnectionNameRequiredExceptionMessage = "An SSE connection Name is required, either from -Name or `$WebEvent.Sse.Name"

Escaping the variables then allows the module to load and work without error

mdaneri commented 3 months ago

I missed It. I’ll try again. I’ll convert everything after I add all the messages

mdaneri commented 3 months ago

Question. Do you think the listener requires localization? I was looking the code, but I’m not seeing anything interesting that required to be localized

mdaneri commented 2 months ago

Semaphore is translated correctly It's the English language that uses a strange 2 words (traffic light) for a semaphore :) Semaphore definition in English https://www.merriam-webster.com/dictionary/semaphore

Scheduler instead has some issue

I'm working to fix the Italian translation because I speak Italian, but for the other language, we have to ask for help from the community on Discord

Badgerati commented 2 months ago

Semaphore is translated correctly It's the English language that uses a strange 2 words (traffic light) for a semaphore :) Semaphore definition in English https://www.merriam-webster.com/dictionary/semaphore

Fair enough!

mdaneri commented 2 months ago

I made en-gb the international English language. I thought to create a 3rd English resource file just for international, but there are no words that we use that differ from the GB ones

Italian psd1 is good to go

mdaneri commented 2 months ago

let me know what you want to do we the other languages

Badgerati commented 2 months ago

All looks good to me :)

For the other languages outside of EN/IT: I have run them all through Google Translate, and they did all come back seemingly valid. If we want that extra level of assurance, we can ask on Discord if anyone is able to review the translations they know.

Otherwise, I happy to approve/merge if there's nothing else to commit

mdaneri commented 2 months ago

I don't have anything to add here. The only thing that remain is to ask for help with the translation.