Data FAQ

How can I update a field across languages?

I am working with websites in multiple languages. When using localized data types, I have to manually update the same field across the languages with the same value (such as a phone number).

Can I, instead, have this field automatically updated with the same value across languages?

Answer:

Yes, you can. You should subscribe to an data update event, then in its handler, iterate the active languages and update the field in each language.

  1. Create or use a localized data type (for example, "Demo.City" with the fields: string "Name", int "Population", string "Country")
  2. Identify the fields you want to have updated across the languages (for example, "Population").
  3. Subscribe for the OnAfterUpdate event on the application startup. Please see "Application Startup" for the samples.
  4. Update the field across languages in the event handler iterating through other languages with Composite.Data.DataLocalizationFacade.ActiveLocalizationCultures.
using System;
using System.Globalization;
using System.Linq;

using Composite.Core.Application;
using Composite.Data;
using Composite.Data.Types;
using Composite.Data.ProcessControlled;

namespace Samples
{
	[ApplicationStartup]
	public class UpdateGlobalFields
	{
		public UpdateGlobalFields()
		{

		}

		public static void OnBeforeInitialize()
		{

		}

		public static void OnInitialized()
		{
			DataEvents<Samples.City>.OnAfterUpdate += new DataEventHandler(OnAfterUpdateHandler);
		}

		private static void OnAfterUpdateHandler(object sender, DataEventArgs dataEventArgs)
		{
			if (LocalizedDataUpdateManager.IsBeingUpdated)
				return;

			// make sure we won't update endlessly
			using (new LocalizedDataUpdateManager())
			{
				Samples.City updatedCity = (Samples.City)dataEventArgs.Data;

				// make sure we deal with a localized data type
				if (updatedCity is ILocalizedControlled)
				{
					foreach (CultureInfo ci in DataLocalizationFacade.ActiveLocalizationCultures)
					{
						// make sure we don't update the data item in the current language
						if ((updatedCity as ILocalizedControlled).CultureName == ci.Name)
							continue;

						using (DataConnection connection = new DataConnection(ci))
						{
							Samples.City city =
								(from c in connection.Get<Samples.City>()
								 where c.Id == updatedCity.Id
								 select c).FirstOrDefault();

							// make sure we update an existing item
							if (city != null)
							{
								city.Population = updatedCity.Population;
								connection.Update<Samples.City>(city);
							}
						}
					}
				}
			}
		}
	}

	internal class LocalizedDataUpdateManager : IDisposable
	{
		[ThreadStatic]
		private static int _counter = 0;

		public static bool IsBeingUpdated
		{
			get
			{
				return _counter > 0;
			}
		}

		public LocalizedDataUpdateManager()
		{
			_counter++;
		}

		public void Dispose()
		{
			_counter--;
		}
	}
}

Download the source

Note: In the sample above, we are using an internal class LocalizedDataUpdateManager to make sure that the field update across the languages will fire no more update events. Otherwise, it might lead to the endless update loop.