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.
- Create or use a localized data type (for example, "Demo.City" with the fields:
string
"Name",int
"Population",string
"Country") - Identify the fields you want to have updated across the languages (for example, "Population").
- Subscribe for the
OnAfterUpdate
event on the application startup. Please see "Application Startup" for the samples. - 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--; } } }
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.