Taking a break from my posts on PowerShell this week, I would like to retouch a topic that I talked about before in my post Localization With Angular-GetText. In that post I talk about how to localize your angular application using PoEdit to add your translations. If you have a large number of people developing your application or a lot of languages to update this can cause friction. I got to thinking that there had to be a better way of doing this. There just had to be a way to automate this to reduce the amount of friction during the development process.
You have to first annotate your code with the Translate attribute. Then you must perform the Grunt extract method to update your translation catalog file (*.pot). Next, you must open each translation file (*.po) inside PoEdit, update from catalog, and clear out the guesses that PoEdit does.
Note: PoEdit will perform this guesswork even if you have Translation Memory turned off!
Finally, you must enter the translation into every translation file and save it.
Once you have completed entering the translation for every word that needed to be translated, you must perform the grunt compile operation to update your translations.js file that your application is referencing. Let’s look at the steps:
- Annotate Application
- Run ‘Grunt Extract’
- Open first translation file in PoEdit
- Update translation file from Catalog file
- Remove the unwanted or fuzzy translation from the translation file
- Enter the correct translation for each word
- Save the translation file
- Repeat steps 3 – 7 for each translation file
- Run ‘Grunt Compile’ to build the translations.js file
If you plan on supporting the basic four languages in your application (English, Spanish, French, German), then you will end up performing a minimum of 23 steps just because you adding only 1 more item to be translated. The more translations you have to update in each file, the longer it will take. I have found in practice that this takes a lot of time away from the developer. If he or she is spending their time on performing this repetitive action, they tend to resist this and finally not doing it. This leads to translations getting missed and your application will show a lot of “MISSING” tags being shown when the debug mode is turned on.
There had to be a better way, so I came up with a more automated approach. I wanted to be able to have the computer perform all of these operations for me, because that’s what computers are good at. The only part of the process that really required human intervention was placing the actual translation into to the individual translation files. While I made no illusion that I could replace a human being for this part of the process, I was able to get a basic and approximate translation from an on-line translation service such as Bing Translator, Google Translate, BabelFish, etc. The problem was, how can I automate the calls to one of these services to solve my problem. A while back I created a Language Translation tool that would help me update my Microsoft String Resource files. That project was created to allow Visual Studio developers to globalize their software, and can be found here.
Here is a sample of the code that I’m using to connect to Google’s translation service to get the basic translation from.
Next I took this and wrote a utility around it that would read an updated catalog file and then get the translation utilizing the engine above. Next is open the existing translation files and then update the existing blank translations as well as create the new ones needed. Once all of the translation files are updated then it would need compiled back into the system.
This is good, but not quite good enough for me. So I decided to incorporated my new tool into my Visual Studio build process.
Here is a snippet of the project file XML to show what it looks like inside the project file.
Now let’s review the steps and see what we have gained by doing all of this work. Let’s review the steps needed:
- Annotate Application
- Build The Solution
That is a substantial improvement in productivity!
Is this the only way to perform your translations?
No, you can feel free to come up with your own approach, I did this and it worked at my company.
Should you rely on the automated translations?
Not at all, automated translations WILL be wrong from time to time or use the wrong word for the context. You should have a professional translation service review your application and your translations to make sure that you can give your customer the best possible customer experience.
If you would like to see the complete source code to the Automated Translation project, then visit me on GitHub at Dacke/AutomatedTranslation. Take a look at the source code and maybe you can help me improve it!
Until next time; Keep Calm and Automate…
OK, placing the “grunt extract” in my pre-build step might not have been the best solution. It was designed to demonstrate an example of the process rather than the full process itself. I’ve since changed this up a little bit as I found that running the grunt task a bit tedious when I didn’t need to do it. I’ve created a PowerShell script that will do the job for me.
I need to build the solution and I can do that using MSBuild.exe from the command line. I needed the PowerShell script to run this process for all of the solutions that make up my application. My solutions use NuGet packages to manage the references for various third party components. The build script will need to restore those before the build process is called.
Now that the NuGet packages are restored, we can move on to the rest of the script that will call the build process for the solutions.
Execute Grunt Task
Remember that we have two different grunt tasks that we want to call; extract and compile. I’ve created a function that will allow us to do both operations depending on the parameters passed in.
Putting All Together
Now that we have all of our functions in place, it’s now time to put it all together.
Note: The ExecuteAutomatedTranslationTask function is basically a duplicate of the ExecuteGruntTask method with the exception that it calls the Automated Translation program we built in the first portion of our post.
You can also include things like Unit Tests and Karma Testing in your PowerShell script as well. This can ensure that your code is the best it can be before you check your code into the software repository. I hope that this update helps make your development environment more productive. Until next time, keep up the good work!
I’ve taken this idea forward and created an Automated Translation Tool that I have shared with all of you. The package can be found on Microsoft’s NuGet server here. I’ve also written about it here. If you are looking for the source code you can look at my repo on GitHub. Take a look at it, heck even fork the repo and help me make the tool better. I look forward to your pull requests!