Extending Contour, multilingual countries prevalue source 5
A question that got my attention this week is what would be the best way to add a multilingual list of countries to a Contour form.
So this post explains how you can extend contour with a custom prevalue source type
The data
Of course we need the multilingual data, after some research I found the Unicode Common Locale Data Repository http://cldr.unicode.org/ it’s basically a collection of xml files with locale data, including a list a countries
The Code
The code is pretty simply it just uses the current culture the fetch the correct xml file (falling back to English if a culture xml isn’t found) and then it loops trough the territory nodes found in the xml.
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Web;
using System.Xml;
using Umbraco.Forms.Core;
namespace Contour.Addons.Countries
{
public class PrevalueSource : FieldPreValueSourceType
{
public PrevalueSource()
{
this.Id = new Guid("9ED6C6D7-16A7-4087-A75D-B936D6FAE5A9");
this.Name = "List of countries";
this.Description = "Multilingual list of countries (http://unicode.org/ files need to be in /app_data/countrydata/)";
}
public override List<Exception> ValidateSettings()
{
var ex = new List<Exception>();
if (!File.Exists(HttpContext.Current.Server.MapPath("/App_Data/CountryData/common/main/en.xml")))
ex.Add(new Exception("Unicode Common Locale Data Repository not found, please download from http://cldr.unicode.org and place in /app_data/countrydata/ directory"));
return ex;
}
public override List<PreValue> GetPreValues(Field field)
{
var pvs = new List<PreValue>();
var d = new XmlDocument();
if (File.Exists(HttpContext.Current.Server.MapPath(
string.Format("/App_Data/CountryData/common/main/{0}.xml",
CultureInfo.CurrentCulture.TwoLetterISOLanguageName))))
{
d.Load(HttpContext.Current.Server.MapPath(
string.Format("/App_Data/CountryData/common/main/{0}.xml",
CultureInfo.CurrentCulture.TwoLetterISOLanguageName)));
}
else
{
d.Load(HttpContext.Current.Server.MapPath(
"/App_Data/CountryData/common/main/en.xml"));
}
var countries = new List<KeyValuePair<string, string>>();
foreach (XmlNode c in d.SelectNodes("//territory [string-length(string(@type)) < 3]"))
countries.Add(new KeyValuePair<string, string>(c.Attributes["type"].Value, c.InnerText));
countries.Sort((firstPair, nextPair) => String.Compare(firstPair.Value, nextPair.Value, StringComparison.Ordinal));
int sort = 0;
foreach (var c in countries)
{
PreValue pv = new PreValue();
pv.Id = c.Key;
pv.Value = c.Value;
if (field != null)
pv.Field = field.Id;
pv.SortOrder = sort;
pvs.Add(pv);
sort++;
}
return pvs;
}
}
}
Code is available on bitbucket https://bitbucket.org/starfighter83/contour.addons.country
The package
The countries prevalue source is available as a package and can be used on your current Contour projects http://our.umbraco.org/projects/backoffice-extensions/contour-countries