Skip to content

Instantly share code, notes, and snippets.

@jamiepollock
Last active July 29, 2020 08:24
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save jamiepollock/5440e7d3c12fceaa4134 to your computer and use it in GitHub Desktop.
Save jamiepollock/5440e7d3c12fceaa4134 to your computer and use it in GitHub Desktop.
A uSync custom DictionaryHandler which only imports items if they're missing. It will not overwrite any existing authored translations.
using Jumoo.uSync.BackOffice;
using Jumoo.uSync.BackOffice.Handlers;
using Jumoo.uSync.BackOffice.Helpers;
using Jumoo.uSync.Core;
using Jumoo.uSync.Core.Extensions;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Xml.Linq;
using Umbraco.Core;
using Umbraco.Core.Logging;
using Umbraco.Core.Models;
using Umbraco.Core.Services;
namespace My.Website.Handlers
{
public class CreateOnlyDictionaryHandler : uSyncBaseHandler<IDictionaryItem>, ISyncHandler
{
private readonly DictionaryHandler _inner;
private readonly ILocalizationService _localizationService;
public string SyncFolder { get { return Constants.Packaging.DictionaryItemNodeName; } }
public CreateOnlyDictionaryHandler()
{
_inner = new DictionaryHandler();
_localizationService = ApplicationContext.Current.Services.LocalizationService;
}
public int Priority { get { return uSyncConstants.Priority.DictionaryItems + 1; } }
public string Name { get { return "uSync: CreateOnlyDictionaryHandler"; } }
public IEnumerable<uSyncAction> ExportAll(string folder)
{
LogHelper.Info<DictionaryHandler>("Exporting all Dictionary Items");
var actions = new List<uSyncAction>();
var _languageService = ApplicationContext.Current.Services.LocalizationService;
foreach (var item in _languageService.GetRootDictionaryItems())
{
if (item != null)
{
actions.Add(ExportToDisk(item, folder));
}
}
return actions;
}
public void RegisterEvents() { }
public uSyncAction ExportToDisk(IDictionaryItem item, string folder)
{
if (item == null)
{
return uSyncAction.Fail(Path.GetFileName(folder), typeof(IDictionaryItem), "item not set");
}
try
{
var attempt = uSyncCoreContext.Instance.DictionarySerializer.Serialize(item);
var filename = string.Empty;
if (attempt.Success)
{
filename = uSyncIOHelper.SavePath(folder, SyncFolder, item.ItemKey.ToSafeAlias());
uSyncIOHelper.SaveNode(attempt.Item, filename);
}
return uSyncActionHelper<XElement>.SetAction(attempt, filename);
}
catch (Exception ex)
{
return uSyncAction.Fail(item.ItemKey, item.GetType(), ChangeType.Export, ex);
}
}
public override SyncAttempt<IDictionaryItem> Import(string filePath, bool force = false)
{
var languages = _localizationService.GetAllLanguages();
var node = XElement.Load(filePath);
var rootItem = default(IDictionaryItem);
var didRootItemImport = TryImportItem(node, languages, out rootItem);
var didChildrenImport = TryImportChildren(node, rootItem, languages);
var didAnythingChange = didRootItemImport || didChildrenImport;
var changeType = didAnythingChange ? ChangeType.Import : ChangeType.NoChange;
return SyncAttempt<IDictionaryItem>.Succeed(rootItem.ItemKey, rootItem, changeType);
}
private bool TryImportItem(XElement node, IEnumerable<ILanguage> languages, out IDictionaryItem dictionaryItem, Guid? parent = null)
{
var wasImported = false;
var itemKey = node.NameFromNode();
if (_localizationService.DictionaryItemExists(itemKey))
{
dictionaryItem = _localizationService.GetDictionaryItemByKey(itemKey);
}
else
{
dictionaryItem = _localizationService.CreateDictionaryItemWithIdentity(itemKey, parent);
foreach (var valueNode in node.Elements("Value"))
{
var languageId = valueNode.Attribute("LanguageCultureAlias").Value;
var language = languages.FirstOrDefault(x => x.IsoCode == languageId);
if (language != null)
{
_localizationService.AddOrUpdateDictionaryValue(dictionaryItem, language, valueNode.Value);
}
}
_localizationService.Save(dictionaryItem);
wasImported = true;
}
return wasImported;
}
private bool TryImportChildren(XElement node, IDictionaryItem rootItem, IEnumerable<ILanguage> languages)
{
var children = node.Elements("DictionaryItem");
var haveAnyChildrenImported = false;
var haveAnyChildrensChildrenImported = false;
foreach (var child in children)
{
var childDictionaryItem = default(IDictionaryItem);
var didChildImport = TryImportItem(child, languages, out childDictionaryItem, rootItem.Key);
var didChildsChildrenImport = TryImportChildren(child, childDictionaryItem, languages);
if (haveAnyChildrenImported == false)
{
haveAnyChildrenImported = didChildImport;
}
if (haveAnyChildrensChildrenImported)
{
haveAnyChildrensChildrenImported = didChildsChildrenImport;
}
}
return haveAnyChildrenImported || haveAnyChildrensChildrenImported;
}
public override uSyncAction ReportItem(string file)
{
var node = XElement.Load(file);
var update = uSyncCoreContext.Instance.DictionarySerializer.IsUpdate(node);
var action = uSyncActionHelper<IDictionaryItem>.ReportAction(update, node.NameFromNode(), "Dictionary Items often get their order mixed up");
return action;
}
}
}
<?xml version="1.0" encoding="utf-8"?>
<uSyncBackOfficeSettings xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<Import>false</Import>
<ExportAtStartup>false</ExportAtStartup>
<ExportOnSave>false</ExportOnSave>
<WatchForFileChanges>false</WatchForFileChanges>
<ArchiveVersions>false</ArchiveVersions>
<Folder>~/uSync/data/</Folder>
<ArchiveFolder>~/uSync/Archive/</ArchiveFolder>
<BackupFolder>~/uSync/Backup/</BackupFolder>
<MaxArchiveVersionCount>0</MaxArchiveVersionCount>
<Handlers>
<HandlerConfig Name="uSync: DataTypeHandler" Enabled="true" />
<HandlerConfig Name="uSync: TemplateHandler" Enabled="true" />
<HandlerConfig Name="uSync: ContentTypeHanlder" Enabled="true" />
<HandlerConfig Name="uSync: MediaTypeHandler" Enabled="true" />
<HandlerConfig Name="uSync: LanguageHandler" Enabled="true" />
<HandlerConfig Name="uSync: MacroHandler" Enabled="true" />
<!-- Default uSync: DictionaryHandler must be set to Enabled="false" as by default a handler is enabled -->
<HandlerConfig Name="uSync: DictionaryHandler" Enabled="false" />
<HandlerConfig Name="uSync: CreateOnlyDictionaryHandler" Enabled="true" />
</Handlers>
</uSyncBackOfficeSettings>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment