From 07c714fd11d7eb37f97fec3e24ccf44617329a11 Mon Sep 17 00:00:00 2001 From: engern Date: Sat, 21 Nov 2015 11:33:46 +0100 Subject: [PATCH 1/5] Fixes U4-7424 Add the possibilty to change the error message when a macro partial view fails to render. --- src/Umbraco.Web.UI/umbraco/config/lang/en.xml | 1 + src/Umbraco.Web.UI/umbraco/config/lang/en_us.xml | 1 + src/Umbraco.Web/umbraco.presentation/macro.cs | 9 ++++++++- 3 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/Umbraco.Web.UI/umbraco/config/lang/en.xml b/src/Umbraco.Web.UI/umbraco/config/lang/en.xml index 582bb077ef..7ffa57eaec 100644 --- a/src/Umbraco.Web.UI/umbraco/config/lang/en.xml +++ b/src/Umbraco.Web.UI/umbraco/config/lang/en.xml @@ -301,6 +301,7 @@ NOTE! Even though CodeMirror is enabled by configuration, it is disabled in Internet Explorer because it's not stable enough. Please fill both alias and name on the new property type! There is a problem with read/write access to a specific file or folder + Error loading Partial View script (file: %0%) Please enter a title Please choose a type You're about to make the picture larger than the original size. Are you sure that you want to proceed? diff --git a/src/Umbraco.Web.UI/umbraco/config/lang/en_us.xml b/src/Umbraco.Web.UI/umbraco/config/lang/en_us.xml index c9dcd1554a..b5a686eec1 100644 --- a/src/Umbraco.Web.UI/umbraco/config/lang/en_us.xml +++ b/src/Umbraco.Web.UI/umbraco/config/lang/en_us.xml @@ -302,6 +302,7 @@ NOTE! Even though CodeMirror is enabled by configuration, it is disabled in Internet Explorer because it's not stable enough. Please fill both alias and name on the new property type! There is a problem with read/write access to a specific file or folder + Error loading Partial View script (file: %0%) Please enter a title Please choose a type You're about to make the picture larger than the original size. Are you sure that you want to proceed? diff --git a/src/Umbraco.Web/umbraco.presentation/macro.cs b/src/Umbraco.Web/umbraco.presentation/macro.cs index 53bdaaa9de..4797709fde 100644 --- a/src/Umbraco.Web/umbraco.presentation/macro.cs +++ b/src/Umbraco.Web/umbraco.presentation/macro.cs @@ -24,6 +24,7 @@ using Umbraco.Core.IO; using Umbraco.Core.Logging; using Umbraco.Core.Macros; using Umbraco.Core.Models; +using Umbraco.Core.Services; using Umbraco.Core.Xml.XPath; using Umbraco.Core.Profiling; using umbraco.interfaces; @@ -322,7 +323,13 @@ namespace umbraco Exception = e, Behaviour = UmbracoConfig.For.UmbracoSettings().Content.MacroErrorBehaviour }; - return GetControlForErrorBehavior("Error loading Partial View script (file: " + ScriptFile + ")", macroErrorEventArgs); + + var errorMessage = ApplicationContext.Current.Services.TextService.Localize("errors/macroErrorLoadingPartialView",new[]{ScriptFile}); + if (errorMessage.Equals("[macroErrorLoadingPartialView]")) // This check can be removed when key is added to every language file + { + errorMessage = "Error loading Partial View script (file: " + ScriptFile + ")"; + } + return GetControlForErrorBehavior(errorMessage, macroErrorEventArgs); }; using (DisposableTimer.DebugDuration("Executing Partial View: " + Model.TypeName)) From 44ebd8d9ea781fb46fa8b7de87e9470659b1c2dd Mon Sep 17 00:00:00 2001 From: Sebastiaan Janssen Date: Tue, 15 Dec 2015 12:18:23 +0100 Subject: [PATCH 2/5] Proper formatting of this file, only whitespace changes --- src/Umbraco.Web/umbraco.presentation/macro.cs | 268 +++++++++--------- 1 file changed, 134 insertions(+), 134 deletions(-) diff --git a/src/Umbraco.Web/umbraco.presentation/macro.cs b/src/Umbraco.Web/umbraco.presentation/macro.cs index b1b18b07d5..a5ed603529 100644 --- a/src/Umbraco.Web/umbraco.presentation/macro.cs +++ b/src/Umbraco.Web/umbraco.presentation/macro.cs @@ -63,7 +63,7 @@ namespace umbraco private readonly StringBuilder _content = new StringBuilder(); private const string MacrosAddedKey = "macrosAdded"; public IList Exceptions = new List(); - + protected static ISqlHelper SqlHelper { get { return Application.SqlHelper; } @@ -158,7 +158,7 @@ namespace umbraco public macro(string alias) { Macro m = Macro.GetByAlias(alias); - Model = new MacroModel(m); + Model = new MacroModel(m); } public MacroModel Model { get; set; } @@ -169,7 +169,7 @@ namespace umbraco } public static macro GetMacro(int id) - { + { return new macro(id); } @@ -200,9 +200,9 @@ namespace umbraco { if (this.Model != null) { - DistributedCache.Instance.RemoveMacroCache(this); + DistributedCache.Instance.RemoveMacroCache(this); } - + //this always returned false... hrm. oh well i guess we leave it like that return false; } @@ -254,7 +254,7 @@ namespace umbraco /// An event that is raised just before the macro is rendered allowing developers to modify the macro before it executes. /// public static event TypedEventHandler MacroRendering; - + /// /// Raises the MacroRendering event /// @@ -282,7 +282,7 @@ namespace umbraco using (DisposableTimer.DebugDuration(macroInfo)) { - TraceInfo("renderMacro", macroInfo, excludeProfiling:true); + TraceInfo("renderMacro", macroInfo, excludeProfiling: true); StateHelper.SetContextValue(MacrosAddedKey, StateHelper.GetContextValue(MacrosAddedKey) + 1); @@ -302,12 +302,12 @@ namespace umbraco { var renderFailed = false; var macroType = Model.MacroType != MacroTypes.Unknown - ? (int) Model.MacroType + ? (int)Model.MacroType : MacroType; switch (macroType) { - case (int) MacroTypes.PartialView: + case (int)MacroTypes.PartialView: //error handler for partial views, is an action because we need to re-use it twice below Func handleError = e => @@ -324,7 +324,7 @@ namespace umbraco Behaviour = UmbracoConfig.For.UmbracoSettings().Content.MacroErrorBehaviour }; - var errorMessage = ApplicationContext.Current.Services.TextService.Localize("errors/macroErrorLoadingPartialView",new[]{ScriptFile}); + var errorMessage = ApplicationContext.Current.Services.TextService.Localize("errors/macroErrorLoadingPartialView", new[] { ScriptFile }); if (errorMessage.Equals("[macroErrorLoadingPartialView]")) // This check can be removed when key is added to every language file { errorMessage = "Error loading Partial View script (file: " + ScriptFile + ")"; @@ -334,7 +334,7 @@ namespace umbraco using (DisposableTimer.DebugDuration("Executing Partial View: " + Model.TypeName)) { - TraceInfo("umbracoMacro", "Partial View added (" + Model.TypeName + ")", excludeProfiling:true); + TraceInfo("umbracoMacro", "Partial View added (" + Model.TypeName + ")", excludeProfiling: true); try { var result = LoadPartialViewMacro(Model); @@ -369,13 +369,13 @@ namespace umbraco break; } - case (int) MacroTypes.UserControl: + case (int)MacroTypes.UserControl: using (DisposableTimer.DebugDuration("Executing UserControl: " + Model.TypeName)) { try { - TraceInfo("umbracoMacro", "Usercontrol added (" + Model.TypeName + ")", excludeProfiling:true); + TraceInfo("umbracoMacro", "Usercontrol added (" + Model.TypeName + ")", excludeProfiling: true); // Add tilde for v4 defined macros if (string.IsNullOrEmpty(Model.TypeName) == false && @@ -412,8 +412,8 @@ namespace umbraco break; } } - - case (int) MacroTypes.CustomControl: + + case (int)MacroTypes.CustomControl: using (DisposableTimer.DebugDuration("Executing CustomControl: " + Model.TypeName + "." + Model.TypeAssembly)) { @@ -453,10 +453,10 @@ namespace umbraco break; } } - case (int) MacroTypes.XSLT: + case (int)MacroTypes.XSLT: macroControl = LoadMacroXslt(this, Model, pageElements, true); - break; - case (int) MacroTypes.Script: + break; + case (int)MacroTypes.Script: //error handler for partial views, is an action because we need to re-use it twice below Func handleMacroScriptError = e => @@ -512,7 +512,7 @@ namespace umbraco break; } } - case (int) MacroTypes.Unknown: + case (int)MacroTypes.Unknown: default: if (GlobalSettings.DebugMode) { @@ -608,9 +608,9 @@ namespace umbraco CacheItemPriority.NotRemovable, new TimeSpan(0, 0, Model.CacheDuration), () => DateTime.Now); - + } - + } } } @@ -752,7 +752,7 @@ namespace umbraco switch (model.MacroType) { case MacroTypes.XSLT: - return string.Concat("~/xslt/", model.Xslt); + return string.Concat("~/xslt/", model.Xslt); case MacroTypes.Python: case MacroTypes.Script: return string.Concat("~/macroScripts/", model.ScriptName); @@ -760,7 +760,7 @@ namespace umbraco return model.ScriptName; //partial views are saved with the full virtual path case MacroTypes.UserControl: return model.TypeName; //user controls saved with the full virtual path - case MacroTypes.CustomControl: + case MacroTypes.CustomControl: case MacroTypes.Unknown: default: return "/" + model.TypeName; @@ -784,7 +784,7 @@ namespace umbraco { switch (model.MacroType) { - case MacroTypes.XSLT: + case MacroTypes.XSLT: case MacroTypes.Python: case MacroTypes.Script: case MacroTypes.PartialView: @@ -805,12 +805,12 @@ namespace umbraco CacheItemPriority.Default, new CacheDependency(IOHelper.MapPath(SystemDirectories.Xslt + "/" + XsltFile)), () => + { + using (var xslReader = new XmlTextReader(IOHelper.MapPath(SystemDirectories.Xslt.EnsureEndsWith('/') + XsltFile))) { - using (var xslReader = new XmlTextReader(IOHelper.MapPath(SystemDirectories.Xslt.EnsureEndsWith('/') + XsltFile))) - { - return CreateXsltTransform(xslReader, GlobalSettings.DebugMode); - } - }); + return CreateXsltTransform(xslReader, GlobalSettings.DebugMode); + } + }); } public void UpdateMacroModel(Hashtable attributes) @@ -891,7 +891,7 @@ namespace umbraco if (!canNavigate) { - // get master xml document + // get master xml document var cache = UmbracoContext.Current.ContentCache.InnerCache as Umbraco.Web.PublishedCache.XmlPublishedCache.PublishedContentCache; if (cache == null) throw new Exception("Unsupported IPublishedContentCache, only the Xml one is supported."); XmlDocument umbracoXml = cache.GetXml(UmbracoContext.Current, UmbracoContext.Current.InPreviewMode); @@ -932,9 +932,9 @@ namespace umbraco { try { - var transformed = canNavigate - ? GetXsltTransformResult(macroNavigator, contentNavigator, xsltFile) // better? - : GetXsltTransformResult(macroXml, xsltFile); // document + var transformed = canNavigate + ? GetXsltTransformResult(macroNavigator, contentNavigator, xsltFile) // better? + : GetXsltTransformResult(macroXml, xsltFile); // document var result = CreateControlsFromText(transformed); return result; @@ -943,7 +943,7 @@ namespace umbraco { Exceptions.Add(e); LogHelper.WarnWithException("Error parsing XSLT file", e); - + var macroErrorEventArgs = new MacroErrorEventArgs { Name = Model.Name, Alias = Model.Alias, ItemKey = Model.Xslt, Exception = e, Behaviour = UmbracoConfig.For.UmbracoSettings().Content.MacroErrorBehaviour }; var macroControl = GetControlForErrorBehavior("Error parsing XSLT file: \\xslt\\" + XsltFile, macroErrorEventArgs); //if it is null, then we are supposed to throw the (original) exception @@ -953,8 +953,8 @@ namespace umbraco throw; } return macroControl; - } - } + } + } } catch (Exception e) { @@ -972,7 +972,7 @@ namespace umbraco } return macroControl; } - } + } } // gets the control for the macro, using GetXsltTransform methods for execution @@ -1053,12 +1053,12 @@ namespace umbraco XsltArgumentList xslArgs; using (DisposableTimer.DebugDuration("Adding XSLT Extensions")) - { + { xslArgs = AddXsltExtensions(); var lib = new library(); xslArgs.AddExtensionObject("urn:umbraco.library", lib); } - + // Add parameters if (parameters == null || !parameters.ContainsKey("currentPage")) { @@ -1074,8 +1074,8 @@ namespace umbraco using (DisposableTimer.DebugDuration("Executing XSLT transform")) { xslt.Transform(macroXml.CreateNavigator(), xslArgs, tw); - } - return TemplateUtilities.ResolveUrlsFromTextString(tw.ToString()); + } + return TemplateUtilities.ResolveUrlsFromTextString(tw.ToString()); } // gets the result of the xslt transform with no parameters - Navigator mode @@ -1135,7 +1135,7 @@ namespace umbraco return XsltExtensionsResolver.Current.XsltExtensions .ToDictionary(x => x.Namespace, x => x.ExtensionObject); } - + /// /// Returns an XSLT argument list with all XSLT extensions added, /// both predefined and configured ones. @@ -1149,9 +1149,9 @@ namespace umbraco { string extensionNamespace = "urn:" + extension.Key; xslArgs.AddExtensionObject(extensionNamespace, extension.Value); - TraceInfo("umbracoXsltExtension", - String.Format("Extension added: {0}, {1}", - extensionNamespace, extension.Value.GetType().Name)); + TraceInfo("umbracoXsltExtension", + String.Format("Extension added: {0}, {1}", + extensionNamespace, extension.Value.GetType().Name)); } return xslArgs; @@ -1169,12 +1169,12 @@ namespace umbraco // if no value is passed, then use the current "pageID" as value var contentId = macroPropertyValue == string.Empty ? UmbracoContext.Current.PageId.ToString() : macroPropertyValue; - TraceInfo("umbracoMacro", - "Xslt node adding search start (" + macroPropertyAlias + ",'" + - macroPropertyValue + "')"); - + TraceInfo("umbracoMacro", + "Xslt node adding search start (" + macroPropertyAlias + ",'" + + macroPropertyValue + "')"); + //TODO: WE need to fix this so that we give control of this stuff over to the actual parameter editors! - + switch (macroPropertyType) { case "contentTree": @@ -1204,7 +1204,7 @@ namespace umbraco macroXmlNode.AppendChild(currentNode); - break; + break; case "contentAll": macroXmlNode.AppendChild(macroXml.ImportNode(umbracoXml.DocumentElement, true)); @@ -1212,33 +1212,33 @@ namespace umbraco case "contentRandom": XmlNode source = umbracoXml.GetElementById(contentId); - if (source != null) - { - var sourceList = source.SelectNodes("node|*[@isDoc]"); - if (sourceList.Count > 0) - { - int rndNumber; - var r = library.GetRandom(); - lock (r) - { - rndNumber = r.Next(sourceList.Count); - } - var node = macroXml.ImportNode(sourceList[rndNumber], true); - // remove all sub content nodes - foreach (XmlNode n in node.SelectNodes("node|*[@isDoc]")) - node.RemoveChild(n); + if (source != null) + { + var sourceList = source.SelectNodes("node|*[@isDoc]"); + if (sourceList.Count > 0) + { + int rndNumber; + var r = library.GetRandom(); + lock (r) + { + rndNumber = r.Next(sourceList.Count); + } + var node = macroXml.ImportNode(sourceList[rndNumber], true); + // remove all sub content nodes + foreach (XmlNode n in node.SelectNodes("node|*[@isDoc]")) + node.RemoveChild(n); - macroXmlNode.AppendChild(node); - } - else - TraceWarn("umbracoMacro", - "Error adding random node - parent (" + macroPropertyValue + - ") doesn't have children!"); - } - else - TraceWarn("umbracoMacro", - "Error adding random node - parent (" + macroPropertyValue + - ") doesn't exists!"); + macroXmlNode.AppendChild(node); + } + else + TraceWarn("umbracoMacro", + "Error adding random node - parent (" + macroPropertyValue + + ") doesn't have children!"); + } + else + TraceWarn("umbracoMacro", + "Error adding random node - parent (" + macroPropertyValue + + ") doesn't exists!"); break; case "mediaCurrent": @@ -1259,14 +1259,14 @@ namespace umbraco // add parameters to the macro parameters collection private void AddMacroParameter(ICollection parameters, NavigableNavigator contentNavigator, NavigableNavigator mediaNavigator, - string macroPropertyAlias,string macroPropertyType, string macroPropertyValue) + string macroPropertyAlias, string macroPropertyType, string macroPropertyValue) { // if no value is passed, then use the current "pageID" as value var contentId = macroPropertyValue == string.Empty ? UmbracoContext.Current.PageId.ToString() : macroPropertyValue; - TraceInfo("umbracoMacro", - "Xslt node adding search start (" + macroPropertyAlias + ",'" + - macroPropertyValue + "')"); + TraceInfo("umbracoMacro", + "Xslt node adding search start (" + macroPropertyAlias + ",'" + + macroPropertyValue + "')"); // beware! do not use the raw content- or media- navigators, but clones !! @@ -1322,15 +1322,15 @@ namespace umbraco if (node != null) { nav = contentNavigator.CloneWithNewRoot(node.Id.ToString(CultureInfo.InvariantCulture)); - parameters.Add(new MacroNavigator.MacroParameter(macroPropertyAlias, nav, 0)); + parameters.Add(new MacroNavigator.MacroParameter(macroPropertyAlias, nav, 0)); } else throw new InvalidOperationException("Iterator contains non-INavigableContent elements."); } else - TraceWarn("umbracoMacro", - "Error adding random node - parent (" + macroPropertyValue + - ") doesn't have children!"); + TraceWarn("umbracoMacro", + "Error adding random node - parent (" + macroPropertyValue + + ") doesn't have children!"); } else TraceWarn("umbracoMacro", @@ -1353,31 +1353,31 @@ namespace umbraco #endregion - /// - /// Renders a Partial View Macro - /// - /// - /// - internal ScriptingMacroResult LoadPartialViewMacro(MacroModel macro) - { - var retVal = new ScriptingMacroResult(); - IMacroEngine engine = null; - - engine = MacroEngineFactory.GetEngine(PartialViewMacroEngine.EngineName); - var ret = engine.Execute(macro, GetCurrentNode()); + /// + /// Renders a Partial View Macro + /// + /// + /// + internal ScriptingMacroResult LoadPartialViewMacro(MacroModel macro) + { + var retVal = new ScriptingMacroResult(); + IMacroEngine engine = null; - // if the macro engine supports success reporting and executing failed, then return an empty control so it's not cached - if (engine is IMacroEngineResultStatus) - { - var result = engine as IMacroEngineResultStatus; - if (!result.Success) - { - retVal.ResultException = result.ResultException; - } - } - retVal.Result = ret; - return retVal; - } + engine = MacroEngineFactory.GetEngine(PartialViewMacroEngine.EngineName); + var ret = engine.Execute(macro, GetCurrentNode()); + + // if the macro engine supports success reporting and executing failed, then return an empty control so it's not cached + if (engine is IMacroEngineResultStatus) + { + var result = engine as IMacroEngineResultStatus; + if (!result.Success) + { + retVal.ResultException = result.ResultException; + } + } + retVal.Result = ret; + return retVal; + } public ScriptingMacroResult loadMacroScript(MacroModel macro) { @@ -1410,7 +1410,7 @@ namespace umbraco retVal.Result = ret; return retVal; } - + /// /// Loads a custom or webcontrol using reflection into the macro object /// @@ -1439,8 +1439,8 @@ namespace umbraco if (!File.Exists(currentAss)) return new LiteralControl("Unable to load user control because is does not exist: " + fileName); asm = Assembly.LoadFrom(currentAss); - - TraceInfo("umbracoMacro", "Assembly file " + currentAss + " LOADED!!"); + + TraceInfo("umbracoMacro", "Assembly file " + currentAss + " LOADED!!"); } catch { @@ -1449,7 +1449,7 @@ namespace umbraco ".dll"))); } - TraceInfo("umbracoMacro", string.Format("Assembly Loaded from ({0}.dll)", fileName)); + TraceInfo("umbracoMacro", string.Format("Assembly Loaded from ({0}.dll)", fileName)); type = asm.GetType(controlName); if (type == null) return new LiteralControl(string.Format("Unable to get type {0} from assembly {1}", @@ -1477,8 +1477,8 @@ namespace umbraco { var prop = type.GetProperty(mp.Key); if (prop == null) - { - TraceWarn("macro", string.Format("control property '{0}' doesn't exist or aren't accessible (public)", mp.Key)); + { + TraceWarn("macro", string.Format("control property '{0}' doesn't exist or aren't accessible (public)", mp.Key)); continue; } @@ -1514,17 +1514,17 @@ namespace umbraco } } - /// - /// Loads an usercontrol using reflection into the macro object - /// - /// Filename of the usercontrol - ie. ~wulff.ascx - /// - /// The page elements. - /// - public Control loadUserControl(string fileName, MacroModel model, Hashtable pageElements) + /// + /// Loads an usercontrol using reflection into the macro object + /// + /// Filename of the usercontrol - ie. ~wulff.ascx + /// + /// The page elements. + /// + public Control loadUserControl(string fileName, MacroModel model, Hashtable pageElements) { - Mandate.ParameterNotNullOrEmpty(fileName, "fileName"); - Mandate.ParameterNotNull(model, "model"); + Mandate.ParameterNotNullOrEmpty(fileName, "fileName"); + Mandate.ParameterNotNull(model, "model"); try { @@ -1548,13 +1548,13 @@ namespace umbraco TraceInfo(LoadUserControlKey, string.Format("Usercontrol added with id '{0}'", oControl.ID)); - AddCurrentNodeToControl(oControl); + AddCurrentNodeToControl(oControl); UpdateControlProperties(oControl, model); return oControl; } catch (Exception e) { - LogHelper.WarnWithException(string.Format("Error creating usercontrol ({0})", fileName), true, e); + LogHelper.WarnWithException(string.Format("Error creating usercontrol ({0})", fileName), true, e); throw; } } @@ -1594,7 +1594,7 @@ namespace umbraco private static void TraceWarn(string category, string message, bool excludeProfiling = false) { if (HttpContext.Current != null) - HttpContext.Current.Trace.Warn(category, message); + HttpContext.Current.Trace.Warn(category, message); //Trace out to profiling... doesn't actually profile, just for informational output. if (excludeProfiling == false) @@ -1606,9 +1606,9 @@ namespace umbraco } private static void TraceWarn(string category, string message, Exception ex, bool excludeProfiling = false) - { - if (HttpContext.Current != null) - HttpContext.Current.Trace.Warn(category, message, ex); + { + if (HttpContext.Current != null) + HttpContext.Current.Trace.Warn(category, message, ex); //Trace out to profiling... doesn't actually profile, just for informational output. if (excludeProfiling == false) @@ -1617,7 +1617,7 @@ namespace umbraco { } } - } + } public static string renderMacroStartTag(Hashtable attributes, int pageId, Guid versionId) { @@ -1685,7 +1685,7 @@ namespace umbraco { return "Cannot render macro content in the rich text editor when the application is running in a Partial Trust environment"; } - + string tempAlias = (attributes["macroalias"] != null) ? attributes["macroalias"].ToString() : attributes["macroAlias"].ToString(); @@ -1875,7 +1875,7 @@ namespace umbraco var pageId = UmbracoContext.Current.PageId; content = pageId.HasValue ? UmbracoContext.Current.ContentCache.GetById(pageId.Value) : null; } - + return content == null ? null : LegacyNodeHelper.ConvertToNode(content); } From d069da8a4ff27538cf61059bed96bbbbdd6d40ca Mon Sep 17 00:00:00 2001 From: Sebastiaan Janssen Date: Tue, 15 Dec 2015 12:51:03 +0100 Subject: [PATCH 3/5] Make LocalizedTextService fall back to en-GB if the key is not found in the current file --- .../Services/LocalizedTextService.cs | 28 +++++++++++++------ 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/src/Umbraco.Core/Services/LocalizedTextService.cs b/src/Umbraco.Core/Services/LocalizedTextService.cs index cc789434f8..1e8d170b89 100644 --- a/src/Umbraco.Core/Services/LocalizedTextService.cs +++ b/src/Umbraco.Core/Services/LocalizedTextService.cs @@ -254,23 +254,35 @@ namespace Umbraco.Core.Services return "[" + key + "]"; } - var cultureSource = xmlSource[culture].Value; - - var xpath = area.IsNullOrWhiteSpace() - ? string.Format("//key [@alias = '{0}']", key) - : string.Format("//area [@alias = '{0}']/key [@alias = '{1}']", area, key); - - var found = cultureSource.XPathSelectElement(xpath); + var found = FindTranslation(xmlSource, culture, area, key); if (found != null) { return ParseTokens(found.Value, tokens); } + + // Fall back to English by default if we can't find the key + found = FindTranslation(xmlSource, new CultureInfo("en-GB"), area, key); + if (found != null) + return ParseTokens(found.Value, tokens); - //NOTE: Based on how legacy works, the default text does not contain the area, just the key + // If it can't be found in either file, fall back to the default, showing just the key in square brackets + // NOTE: Based on how legacy works, the default text does not contain the area, just the key return "[" + key + "]"; } + private XElement FindTranslation(IDictionary> xmlSource, CultureInfo culture, string area, string key) + { + var cultureSource = xmlSource[culture].Value; + + var xpath = area.IsNullOrWhiteSpace() + ? string.Format("//key [@alias = '{0}']", key) + : string.Format("//area [@alias = '{0}']/key [@alias = '{1}']", area, key); + + var found = cultureSource.XPathSelectElement(xpath); + return found; + } + /// /// Parses the tokens in the value /// From 80f597a7eb0e8bf5d773536665ac38b5dd39bbfe Mon Sep 17 00:00:00 2001 From: Sebastiaan Janssen Date: Tue, 15 Dec 2015 12:51:45 +0100 Subject: [PATCH 4/5] U4-7424 - Also update all other errors displayed in the frontend --- src/Umbraco.Web.UI/umbraco/config/lang/en.xml | 5 ++++ .../umbraco/config/lang/en_us.xml | 5 ++++ src/Umbraco.Web/umbraco.presentation/macro.cs | 26 +++++++++++-------- 3 files changed, 25 insertions(+), 11 deletions(-) diff --git a/src/Umbraco.Web.UI/umbraco/config/lang/en.xml b/src/Umbraco.Web.UI/umbraco/config/lang/en.xml index 7ffa57eaec..7c89e7f746 100644 --- a/src/Umbraco.Web.UI/umbraco/config/lang/en.xml +++ b/src/Umbraco.Web.UI/umbraco/config/lang/en.xml @@ -302,6 +302,11 @@ Please fill both alias and name on the new property type! There is a problem with read/write access to a specific file or folder Error loading Partial View script (file: %0%) + Error loading userControl '%0%' + Error loading customControl (Assembly: %0%, Type: '%1%') + Error loading MacroEngine script (file: %0%) + "Error parsing XSLT file: %0% + "Error reading XSLT file: %0% Please enter a title Please choose a type You're about to make the picture larger than the original size. Are you sure that you want to proceed? diff --git a/src/Umbraco.Web.UI/umbraco/config/lang/en_us.xml b/src/Umbraco.Web.UI/umbraco/config/lang/en_us.xml index b5a686eec1..2a86fa458b 100644 --- a/src/Umbraco.Web.UI/umbraco/config/lang/en_us.xml +++ b/src/Umbraco.Web.UI/umbraco/config/lang/en_us.xml @@ -303,6 +303,11 @@ Please fill both alias and name on the new property type! There is a problem with read/write access to a specific file or folder Error loading Partial View script (file: %0%) + Error loading userControl '%0%' + Error loading customControl (Assembly: %0%, Type: '%1%') + Error loading MacroEngine script (file: %0%) + "Error parsing XSLT file: %0% + "Error reading XSLT file: %0% Please enter a title Please choose a type You're about to make the picture larger than the original size. Are you sure that you want to proceed? diff --git a/src/Umbraco.Web/umbraco.presentation/macro.cs b/src/Umbraco.Web/umbraco.presentation/macro.cs index a5ed603529..e14cef4eb1 100644 --- a/src/Umbraco.Web/umbraco.presentation/macro.cs +++ b/src/Umbraco.Web/umbraco.presentation/macro.cs @@ -304,6 +304,7 @@ namespace umbraco var macroType = Model.MacroType != MacroTypes.Unknown ? (int)Model.MacroType : MacroType; + var textService = ApplicationContext.Current.Services.TextService; switch (macroType) { @@ -324,11 +325,7 @@ namespace umbraco Behaviour = UmbracoConfig.For.UmbracoSettings().Content.MacroErrorBehaviour }; - var errorMessage = ApplicationContext.Current.Services.TextService.Localize("errors/macroErrorLoadingPartialView", new[] { ScriptFile }); - if (errorMessage.Equals("[macroErrorLoadingPartialView]")) // This check can be removed when key is added to every language file - { - errorMessage = "Error loading Partial View script (file: " + ScriptFile + ")"; - } + var errorMessage = textService.Localize("errors/macroErrorLoadingPartialView", new[] { ScriptFile }); return GetControlForErrorBehavior(errorMessage, macroErrorEventArgs); }; @@ -401,7 +398,8 @@ namespace umbraco Behaviour = UmbracoConfig.For.UmbracoSettings().Content.MacroErrorBehaviour }; - macroControl = GetControlForErrorBehavior("Error loading userControl '" + Model.TypeName + "'", macroErrorEventArgs); + var errorMessage = textService.Localize("errors/macroErrorLoadingUsercontrol", new[] { Model.TypeName }); + macroControl = GetControlForErrorBehavior(errorMessage, macroErrorEventArgs); //if it is null, then we are supposed to throw the (original) exception // see: http://issues.umbraco.org/issue/U4-497 at the end if (macroControl == null) @@ -442,7 +440,8 @@ namespace umbraco Behaviour = UmbracoConfig.For.UmbracoSettings().Content.MacroErrorBehaviour }; - macroControl = GetControlForErrorBehavior("Error loading customControl (Assembly: " + Model.TypeAssembly + ", Type: '" + Model.TypeName + "'", macroErrorEventArgs); + var errorMessage = textService.Localize("errors/macroErrorLoadingCustomControl", new[] { Model.TypeAssembly, Model.TypeName }); + macroControl = GetControlForErrorBehavior(errorMessage, macroErrorEventArgs); //if it is null, then we are supposed to throw the (original) exception // see: http://issues.umbraco.org/issue/U4-497 at the end if (macroControl == null) @@ -474,7 +473,8 @@ namespace umbraco Behaviour = UmbracoConfig.For.UmbracoSettings().Content.MacroErrorBehaviour }; - return GetControlForErrorBehavior("Error loading MacroEngine script (file: " + ScriptFile + ")", macroErrorEventArgs); + var errorMessage = textService.Localize("errors/macroErrorLoadingMacroEngineScript", new[] { ScriptFile }); + return GetControlForErrorBehavior(errorMessage, macroErrorEventArgs); }; using (DisposableTimer.DebugDuration("Executing MacroEngineScript: " + ScriptFile)) @@ -923,7 +923,8 @@ namespace umbraco "

" + HttpContext.Current.Server.HtmlEncode(outerXml) + "

"); } - + + var textService = ApplicationContext.Current.Services.TextService; try { var xsltFile = getXslt(XsltFile); @@ -945,7 +946,9 @@ namespace umbraco LogHelper.WarnWithException("Error parsing XSLT file", e); var macroErrorEventArgs = new MacroErrorEventArgs { Name = Model.Name, Alias = Model.Alias, ItemKey = Model.Xslt, Exception = e, Behaviour = UmbracoConfig.For.UmbracoSettings().Content.MacroErrorBehaviour }; - var macroControl = GetControlForErrorBehavior("Error parsing XSLT file: \\xslt\\" + XsltFile, macroErrorEventArgs); + + var errorMessage = textService.Localize("errors/macroErrorParsingXSLTFile", new[] { XsltFile }); + var macroControl = GetControlForErrorBehavior(errorMessage, macroErrorEventArgs); //if it is null, then we are supposed to throw the (original) exception // see: http://issues.umbraco.org/issue/U4-497 at the end if (macroControl == null && throwError) @@ -963,7 +966,8 @@ namespace umbraco // Invoke any error handlers for this macro var macroErrorEventArgs = new MacroErrorEventArgs { Name = Model.Name, Alias = Model.Alias, ItemKey = Model.Xslt, Exception = e, Behaviour = UmbracoConfig.For.UmbracoSettings().Content.MacroErrorBehaviour }; - var macroControl = GetControlForErrorBehavior("Error reading XSLT file: \\xslt\\" + XsltFile, macroErrorEventArgs); + var errorMessage = textService.Localize("errors/macroErrorReadingXSLTFile", new[] { XsltFile }); + var macroControl = GetControlForErrorBehavior(errorMessage + XsltFile, macroErrorEventArgs); //if it is null, then we are supposed to throw the (original) exception // see: http://issues.umbraco.org/issue/U4-497 at the end if (macroControl == null && throwError) From eacc7f7fb3c987a5bcb15849988abeece56a6fe8 Mon Sep 17 00:00:00 2001 From: Sebastiaan Janssen Date: Tue, 15 Dec 2015 13:50:19 +0100 Subject: [PATCH 5/5] Whoops, was supposed to be en-US by default --- src/Umbraco.Core/Services/LocalizedTextService.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Umbraco.Core/Services/LocalizedTextService.cs b/src/Umbraco.Core/Services/LocalizedTextService.cs index 1e8d170b89..886fa47cbf 100644 --- a/src/Umbraco.Core/Services/LocalizedTextService.cs +++ b/src/Umbraco.Core/Services/LocalizedTextService.cs @@ -262,7 +262,7 @@ namespace Umbraco.Core.Services } // Fall back to English by default if we can't find the key - found = FindTranslation(xmlSource, new CultureInfo("en-GB"), area, key); + found = FindTranslation(xmlSource, new CultureInfo("en-US"), area, key); if (found != null) return ParseTokens(found.Value, tokens);