Showing posts with label xlf. Show all posts
Showing posts with label xlf. Show all posts

Monday, 11 March 2013

Share localization files between Windows Phone and Windows 8

    As I wrote in my previous post I am getting back with a post on how to share the localization files between Windows Phone and Windows 8. This should be a simple task, but in the current version of the Windows Phone SDK and Windows 8 it cannot be easily done. The target is to have only one of the two projects (Windows Phone or Windows 8) that manages the localized (in this sample I am only taking in consideration localized strings but the concept can be easily extended) and use it in the other project. Also I wanted to use the Multilingual App Toolkit to easily manage the translations inside the project.
    First let's see what we have:
  • Windows Phone + Multilingual App Toolkit
    1. The main resource file is called AppResources.resx and is inside the Resources folder 
    2. The AppResources.resx automatically generates the AppResources class
    3. The files generated by the Multilingual App Toolkit for the Windows Phone project are also inside the "\Resources" folder and the name look like AppResources.[culture].xlf
    4. We have a class called LocalizedStrings.cs that helps us with the binding inside xaml files
  • Windows 8 + Multilingual App Toolkit
    •  The main resource file is called Resources.resw and it is inside the \strings\[Default language] folder
    • The Resources.resw doesn't have .cs class in code behind generated (it uses the ResourceLoader class to load the localized values). We can also have values with "." like MainButton.Text to directly use inside xaml with the x:Uid.
    • The files generated by the Multilingual App Toolkit for Windows 8 are inside the "\MultilingualResources" folder and the names are [AppName]_[culture].xlf
    So we cannot directly use the files from one project to another.  There are a lot of differences but the couples (AppResources.resx, Resources.resw) and all the (AppResources.[culture].xlf, [AppName]_[culture].xlf) have different names but share very similar structure (they share most of the structure). 

     My approach and idea is to automatically generate the set of localized files needed by one solution directly from the set of files of the other project at compilation time. As source I have chosen the Windows Phone resource files (the other way around is more difficult as we could have resources not supported by Windows Phone). In order to automatically generate the resource files I have created a console application that would be run as a Post-build event on the Windows Phone project and write the necessary files to the Windows 8 project. the Windows 8 project build will be set to depend on the Windows Phone project this way we will always have updated resources when we run it. The console application needs three parameters/inputs: the folder of the Windows Phone project (source), the folder of the Windows 8 project (destination), and the name of the Windows 8 project as we will need it when we generate the [AppName]_[culture].xlf files for the Windows 8 project. The console application also automatically generates the AppResources.cs class inside the Windows 8 projects which is a class similar to the one used by Windows Phone. The source code for the Console Application is also included in case you need to do some changes and also the full sample.
     So let's see what would be the steps you will have to make if you want to use the solution.
  1. Create a Windows Phone application (in the attached sample the project WindowsPhoneApp). Using the Tools menu enable the Multilingual App Toolkit and using right-click on the project name select "Add translation languages..." to support more languages (in the sample is italian)
  2. Create the Windows 8 projects (in the attached sample the project called WindowsStoreApp). Create the the folder structure \strings\en and add the file Resources.resw to it. Inside the Package.appxmanifest set the default language as en. Now use the Tools menu and enable the Multilingual App Toolkit on the Windows 8 project and add the same languages that you have added to the Windows Phone Project. 
    If later you want to add another language support remember to add it to both Windows 8 and Windows Phone projects.
    This is how our solution looks :
    two different projects each of one with its localization part. Now we will set that the Windows 8 project build depends on the Windows Phone project and set the post-build action of the Windows Phone project to be:

    $(SolutionDir)ConvertAppResources\$(OutDir)ConvertAppResources.exe "$(SolutionDir)WindowsPhoneApp" "$(SolutionDir)WindowsStoreApp" WindowsStoreApp

    where ConvertAppResources is the project that converts the resources. We pass 3 parameters to the console application:
    1. the folder of the Windows Phone application which is the source - "$(SolutionDir)WindowsPhoneApp"
    2. the folder of the Windows 8 app which is the destination - "$(SolutionDir)WindowsStoreApp"
    3. the name of the Windows 8 app- WindowsStoreApp
    In our case the console application will generate and overwrite Resources.resw, WindowsStoreApp_it.xlf and WindowsStoreApp_qps-ploc.xlf. It will also generate the file AppResources.cs in the Windows 8 application folder which you will have to include in the project after the first compilation of the Windows Phone application.
    To keep things even more similar to Windows Phone method I have added the class:

     using Localization;  
    namespace WindowsStoreApp
    {
    /// <summary>
    /// Provides access to string resources.
    /// </summary>
    public class LocalizedStrings
    {
    private static AppResources _localizedResources = new AppResources();
    public AppResources LocalizedResources { get { return _localizedResources; } }
    }

    }

    and inside App.xaml added the resource:

     <Application.Resources>  
    <ResourceDictionary>
    <local:LocalizedStrings x:Key="LocalizedStrings"/>
    <ResourceDictionary.MergedDictionaries>
    <!--
    Styles that define common aspects of the platform look and feel
    Required by Visual Studio project and item templates
    -->
    <ResourceDictionary Source="Common/StandardStyles.xaml"/>
    </ResourceDictionary.MergedDictionaries>
    </ResourceDictionary>
    </Application.Resources>

    This way you could easily bind in Windows Phone style and even reuse xaml and cs that you already have from your Windows Phone project:
    Xaml Binding
      <Button Content="{Binding Path=LocalizedResources.ButtonText, Source={StaticResource LocalizedStrings}}" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="517,302,0,0" Height="100" Width="283" Click="Button_Click"/>  
    and/or code-behind:
     MessageDialog md = new MessageDialog(AppResources.ButtonMessage);  

    If you want to know more on how the conversion works look inside Program.cs. The steps I do is save the Resx to Resw and generate the class AppResources.cs. After that for every .xlf file in the Windows Phone Resources folder  I generate and write the corresponding Windows 8 .xlf file (there are some conversions involved). If you want you don't have to add the project ConvertAppResources to your solution but only add the output .exe file to one of the projects and be very careful when you write the post-build action command.

    Once everything is setup-ed you will only have to modify the Windows Phone resource strings and the Windows 8 ones will get updated. If you want to use specific Windows 8 resources you can add more resource files and use the ResourceLoader to load them - for example if you've added the file Errors.resw to the \strings\en folder of the Windows 8 project you will access it like this:

                    var resourceLoader = new ResourceLoader("Errors");
                    this.Scenario5TextBlock.Text = resourceLoader.GetString("InvalidOperation");


    Be careful:

    • before adding the post-build action verify that the localization of both Windows Phone and Windows 8 project work (independent from each other) 
    • if the post-build command is not right the Windows 8 application will not get the updated resources when you compile the windows phone project
    • the Window 8 project has to depend on the Windows Phone project this way you will be sure that Windows 8 gets the updated resources
    • modify ONLY the Windows Phone .resx and .xlf files

    Some limitations of the Multilingaul App Toolkit:

    • If you modify the Resx file and add a new resource you will have compile the project before you will see the new string in the .xlf files
    • If you are modifying the Resx file for a resource that you have already localized when you compile you will loose the localization and you will have to modify the .xlf files again.  


    Let me know if you have problems understanding or making it work (I don't think that I was really good at explaining the process but the hack works).


    SOURCE CODE

    NAMASTE

    Thursday, 7 March 2013

    Easily localize your Windows Phone applications using the Multilingual App Toolkit

      Great news for Windows Phone developers. Today Microsoft released an updated version of its Multilingual App Toolkit for Visual Studio 2012 that supports also Windows Phone projects (the previous version only supported Windows Store projects). You can download the Visual Studio Extension from HERE. The extension itself is multilingual:
       So why is this extension so great in my opinion? As you probably know Windows Phone projects in Visual Studio already support multilingual localization for the applications based on .resw files. The Multilingual App Toolkit adds support for localization industry-standard XLIFF file format and also connects with the Microsoft Translator for quick translation suggestions.
      Lets have a quick looks on how it works. After you have installed the extension you will find a new menu entry inside the Visual Studio 2012 Tools menu with which you can enable or disable the Multilingual App Toolkit for your Windows Phone project.

     Once you have enabled the Multilingual App Toolkit Visual Studio added the XLIFF support and also generates the AppResources.qps-ploc.xlf which is the pseudo-language engine that helps identify translation issues during development. 
       From this moment you will USE ONLY the AppResources.resx file to add new resource strings and the extension (at compilation) will add the missing strings to the corresponding .xlf file. 
        To add new languages to your application you will only have to select the desired language as supported in the project Properties inside the Application section. Once a language is selected the extension automatically generates the corresponding Xlf file.

        You can then double click on the xlf file and Visual Studio will open the Multilingual Editor that enablesyou to edit the translation. If you add new strings to your AppResources.resx file remember to compile the project before opening the .xlf file or you will not see the newly added strings.

      Now with these 3-4 easy simple steps we have localized our application. You can use the the Microsoft Translator in order to have some suggestions but you should always double-check the translation in order to avoid strange translations and situations ("My Application" in italian is translated as "La mia domanda" which actually means My question).


      If you are building a test application remember to add the binding to the resource strings inside your .xaml and .cs files ({Binding Path=LocalizedResources.ApplicationTitle, Source={StaticResource LocalizedStrings}}" Style="{StaticResource PhoneTextNormalStyle} for Xaml or AppResources.value for .cs  )
     Some words about the AppResources.qps-ploc.xlf pseudo language file. Pseudo Language is an artificial modification of the software product intended to simulate real language localization. The pseudo language can be used to detect potential localizability issues or bugs early in the project cycle, before the actual localization starts. For more details about localizability testing with Pseudo Language see Localizability Testing. Inside Visual Studio if you right click on the Pseudo Language file you can select the Generate pseudo translations. 

    In order to test it you will have to set the qps-ploc culture for the Application UI. Just add these 3 lines to your Application constructor (but remember to take them out when you don't need them anymore):

      public App()  
    {
    var ci = new System.Globalization.CultureInfo("qps-ploc");
    Thread.CurrentThread.CurrentCulture = ci;
    Thread.CurrentThread.CurrentUICulture = ci;


     More details on how to use the Multilingual App Toolkit can be found HERE.

     It is really great that Microsoft is migrating the localization of the apps to an open standard. I will get back to this subject with a post on how to share the same xlf files between windows phone and windows 8 projects)

    NAMASTE