OrchardCoreContrib.PoExtractor
OrchardCoreContrib.PoExtractor copied to clipboard
Workflow question
First of all, thanks for the effort you're putting in.
I've been using gettext style translations in Django and I'm considering using PO files for easier localisation into multiple languages. I see that the tool generates a POT (template) file, so I'm wondering if the workflow I am used to from Django is not applicable and what kind of workflow are you using?
In django, one uses makemessages to extract the translations to a file for a particular locale. e.g. django-admin makemessages -l sl would generate .po files for Slovene language.
One can then translate those messages, update code and when you run django-admin makemessages -l sl it just updates the translations with either additional context (msgctxt) or with new entries that are not yet translated but leaves the translations in the file.
Is this a feature that is on the roadmap? What kind of workflow are you using? Are you just generating the messages once and then... not anymore?
I can see two options:
- Use
extractpoto generate the template file - Use
msginitthe first time, to create the PO file - Use
msgmergeafter that to update the PO file with the newly found translations added to the POT file (generated byextractpocommand)
or
- Use
extractpoto generate the template file - Use Poedit (or similar) to update the translation file based on the generated file
Any feedback appreciated, thanks!
Thanks for the input, @skyflyer. We usually use this tool to extract the PO for Orchard Core localized strings. For more information, please check https://github.com/OrchardCMS/OrchardCore.Translations
For custom development, we could use the extractpo tool to extract the localized strings
BTW, we could add a locale option like what Django is doing nowadays, if you would like to propose a PR, I will glad to accept it
Thanks for the feedback!
I will look into it and if I decide to pursue this path, I will surely provide a PR. I'm currently still figuring out how make it work, since the msgctx provided by extractpo seems to be wrong. The views have it as Project.Name.Views.Home.Index, whereas the actual classname is AspNetCore.Views_Home_Index or AspNetCoreGeneratedDocument.Views_Home_Index. So currently, I need to remove all msgctxt entries from POT so that translations work (which is a not so great workaround).
A couple more observations and questions:
- running
extractpoglobal tool finds 343 strings - running from source code finds 4 strings (only in files ending with
.cs) even if I explicitly pass-t Razor(the difference being that the nuget package is older and it used to default to both processors). OK, I figured I need to pass--localizers T, otherwise the defaults are not taken into account. - both, the tool and the source from the main branch produce
msgctxtwith the project name included, e.g.msgctxt "ProjectName.Shared.Views.Shared._SelectLanguagePartial"where onlyViews.Shared._SelectLanguagePartialis what the context should be.
I'm wondering what the correct usage or approach is here. I suppose I'm using this wrong? Could you please advise?
I will, in the mean time, create a PR at least for the default localizers program argument... as I believe this to be a bug.
To summarize:
- the tool includes the project name in the
msgctxt- the project name is not included in the context when translations are being looked up - the code in the main branch does not have any default "localizers" (field names to look for)
So here is a "fix" that removes the project name from context (msgctxt) in the Razor CSHTML files: https://github.com/skyflyer/OrchardCoreContrib.PoExtractor/tree/msgctxt-without-project-name
All tests are passing (none are written for Razor) and I've tested it with deeply nested projects as well and it works (on my machine :)).
What are your thoughts? Am I using the PO localization infrastructure wrong, or is this fix in the right direction?
@hishamco, what are your thoughts on the workflow and proposed fix?
Why do you want to remove the project name from the context? We use it to distinguish between two identical localization strings that are located in multiple projects
Why do you want to remove the project name from the context? We use it to distinguish between two identical localization strings that are located in multiple projects
Because, if the project name is not removed, the translation is not found - the provider provides the context without the project name. Is this something which can be configured?
builder.Services.AddPortableObjectLocalization(options => {
options.ResourcesPath = "Localization";
});
There's only one option to configure.
Could you please write a unit test to break this?
I just looked at the Orchard code: The PO factory passes the context to the localizer and this context equals to Views.Home.Index (if the IViewLocalizer is injected into Home/Index.cshtml view.
With regards to unit test: there is little point in it, the way I see it, because you can put in it whatever you want - the way I understand it (and please, correct me if I'm wrong) is that OrchardCore localization factory decides what the context is - it is not up the extractor to decide what the context needs to be. At least that's my understanding.
If you look at the PortableObjectStringLocalizerFactory.Create method, it is called with ProjectName.Views.Home.Index as the baseName and ProjectName as the location arguments. And then, the location (project name) is removed from the resulting value that is passed as the context to the localizer instance.
Would it help if I prepare a simple repro website that uses PO localization so you can see for yourself?
PS: If it is just a unit test for the removal of the project name from the context (for the Razor part), that is another story - I can certainly write such unit test.
Would it help if I prepare a simple repro website that uses PO localization so you can see for yourself?
As I mentioned before, OrchardCore.Transaltions is the repo that uses the current tool
PS: If it is just a unit test for the removal of the project name from the context (for the Razor part), that is another story - I can certainly write such a unit test.
It would be useful, thanks
I created a pull request which includes two unit tests and a change to remove the project name from the .cshtml msgctx.
I created a sample project that this can be tested on: https://github.com/skyflyer/DotnetPoLocalizationDemo
The sample projects includes localization in .cshtml as well as localization in .cs (HomeController), which must preserve the project name (as it is part of the fully qualified class name).