Skip to content

Instantly share code, notes, and snippets.

@lambda125
Created September 24, 2015 13:48
Show Gist options
  • Save lambda125/7f7cedddfda009329305 to your computer and use it in GitHub Desktop.
Save lambda125/7f7cedddfda009329305 to your computer and use it in GitHub Desktop.
Cross-platform Text localisation for mobile apps - F# version (RESX + T4 + C# + F#)
// For a sample resx, and the ResX-ResW converter T4 template,
// see: https://gist.github.com/krishna-nadiminti/844fe77c9722374a2fb5
namespace Money.Common.UI.Resources
type IResourceLoader =
abstract GetResource: string -> string
abstract IsLocalisedResource: string -> bool
module Strings =
//A layer of abstraction to keep the loader seperate from a class that is accessible as a singleton.
//The class name matches the tt file name
let get key =
Cirrious.CrossCore.Mvx.Resolve<IResourceLoader>().GetResource key
module AppTileLabels =
let SquareTile1_ExpensesText = Strings.get "AppTileLabels_SquareTile1_ExpensesText"
let SquareTile1_SpentMonthText = Strings.get "AppTileLabels_SquareTile1_SpentMonthText"
let SquareTile1_SpentText = Strings.get "AppTileLabels_SquareTile1_SpentText"
let SquareTile1_SpentWeekText = Strings.get "AppTileLabels_SquareTile1_SpentWeekText"
let WideTile1_RecentTransactionsHeading = Strings.get "AppTileLabels_WideTile1_RecentTransactionsHeading"
let NumberOfItems = Strings.get "AppTileLabels_NumberOfItems"
module ButtonLabels =
let Add = Strings.get "ButtonLabels_Add"
let Clear = Strings.get "ButtonLabels_Clear"
let ClearAll = Strings.get "ButtonLabels_ClearAll"
//and so on...
<#@ template debug="true" hostspecific="true" language="C#" #>
<#@ assembly name="System.Core" #>
<#@ assembly name="System.Xml" #>
<#@ assembly name="System.Xml.Linq" #>
<#@ import namespace="System.Collections.Generic" #>
<#@ import namespace="System.IO" #>
<#@ import namespace="System.Linq" #>
<#@ import namespace="System.Text.RegularExpressions" #>
<#@ import namespace="System.Xml.Linq" #>
<#@ output extension=".generated.fs" #>
<#
var resxFileName = Host.TemplateFile.Replace(".tt", ".resx");
IEnumerable<string> resourceNames = XElement.Load(resxFileName).Descendants("data").Select(x => x.Attribute("name").Value);
var resourcesByClass =
resourceNames.GroupBy(k => k.Contains("_") ? k.Substring(0, k.IndexOf("_")) : Path.GetFileNameWithoutExtension(resxFileName))
.ToDictionary(@group => @group.Key, groupValue => groupValue);
var mainClassName = Path.GetFileNameWithoutExtension(Host.TemplateFile);
#>
namespace Money.Common.UI.Resources
type IResourceLoader =
abstract GetResource: string -> string
abstract IsLocalisedResource: string -> bool
module <#=mainClassName#> =
//A layer of abstraction to keep the loader seperate from a class that is accessible as a singleton.
//The class name matches the tt file name
let get key =
Cirrious.CrossCore.Mvx.Resolve<IResourceLoader>().GetResource key
<#
foreach (var resourceKey in resourcesByClass.Keys)
{
#>
module <#=resourceKey#> =
<#
var resourcesForThisClass = resourcesByClass[resourceKey];
foreach (var resource in resourcesForThisClass)
{
var propertyName = resource.Substring(resource.IndexOf("_") + 1);
#>
let <#=propertyName#> = <#=mainClassName#>.get "<#=resource#>"
<#
}
}
#>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment