diff --git a/src/Umbraco.Core/StringExtensions.cs b/src/Umbraco.Core/StringExtensions.cs index 6a2784cc98..93a35b95e2 100644 --- a/src/Umbraco.Core/StringExtensions.cs +++ b/src/Umbraco.Core/StringExtensions.cs @@ -48,8 +48,8 @@ namespace Umbraco.Core internal static bool DetectIsJson(this string input) { input = input.Trim(); - return input.StartsWith("{") && input.EndsWith("}") - || input.StartsWith("[") && input.EndsWith("]"); + return (input.StartsWith("{") && input.EndsWith("}")) + || (input.StartsWith("[") && input.EndsWith("]")); } internal static string ReplaceNonAlphanumericChars(this string input, char replacement) diff --git a/src/Umbraco.Web.UI.Client/lib/umbraco/Extensions.js b/src/Umbraco.Web.UI.Client/lib/umbraco/Extensions.js index a01782de12..b70a6b12bc 100644 --- a/src/Umbraco.Web.UI.Client/lib/umbraco/Extensions.js +++ b/src/Umbraco.Web.UI.Client/lib/umbraco/Extensions.js @@ -320,5 +320,16 @@ }; } + if (!String.prototype.detectIsJson) { + + /** Rudimentary check to see if the string is a json encoded string */ + String.prototype.detectIsJson = function () { + if ((this.startsWith("{") && this.endsWith("}")) || (this.startsWith("[") || this.endsWith("]"))) { + return true; + } + return false; + }; + } + })(); \ No newline at end of file diff --git a/src/Umbraco.Web.UI.Client/src/views/common/dialogs/insertmacro.controller.js b/src/Umbraco.Web.UI.Client/src/views/common/dialogs/insertmacro.controller.js index 758ad70254..6b46dcd6d8 100644 --- a/src/Umbraco.Web.UI.Client/src/views/common/dialogs/insertmacro.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/common/dialogs/insertmacro.controller.js @@ -31,8 +31,29 @@ function InsertMacroController($scope, entityResource, macroResource, umbPropEdi return item.alias == key; }); if (prop) { - //we need to unescape values as they have most likely been escaped while inserted - prop.value = _.unescape(val); + + if (_.isString(val)) { + //we need to unescape values as they have most likely been escaped while inserted + val = _.unescape(val); + + //detect if it is a json string + if (val.detectIsJson()) { + try { + //Parse it to json + prop.value = angular.fromJson(val); + } + catch (e) { + // not json + prop.value = val; + } + } + else { + prop.value = val; + } + } + else { + prop.value = val; + } } }); @@ -49,8 +70,21 @@ function InsertMacroController($scope, entityResource, macroResource, umbPropEdi //create a dictionary for the macro params var paramDictionary = {}; _.each($scope.macroParams, function (item) { + + var val = item.value; + + if (!_.isString(item.value)) { + try { + val = angular.toJson(val); + } + catch (e) { + // not json + } + } + //each value needs to be xml escaped!! since the value get's stored as an xml attribute - paramDictionary[item.alias] = _.escape(item.value); + paramDictionary[item.alias] = _.escape(val); + }); //need to find the macro alias for the selected id diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/entitypicker/entitypicker.controller.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/entitypicker/entitypicker.controller.js index 48d122c9b2..925da536b7 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/entitypicker/entitypicker.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/entitypicker/entitypicker.controller.js @@ -33,7 +33,9 @@ function entityPicker($scope, entityResource) { else { //if it's multiple, change the value to an array if ($scope.model.config.multiple === "1") { - $scope.model.value = $scope.model.value.split(','); + if (_.isString($scope.model.value)) { + $scope.model.value = $scope.model.value.split(','); + } } } } diff --git a/src/Umbraco.Web/umbraco.presentation/helper.cs b/src/Umbraco.Web/umbraco.presentation/helper.cs index 5b05f52b82..19c0604ff2 100644 --- a/src/Umbraco.Web/umbraco.presentation/helper.cs +++ b/src/Umbraco.Web/umbraco.presentation/helper.cs @@ -1,5 +1,6 @@ using System; using System.Collections; +using System.Linq; using System.Text.RegularExpressions; using System.Web; using Umbraco.Core; @@ -70,23 +71,53 @@ namespace umbraco return attributeValue; } + /// + /// This method will parse the attribute value to look for some special syntax such as + /// [@requestKey] + /// [%sessionKey] + /// [#pageElement] + /// [$recursiveValue] + /// + /// + /// + /// + /// + /// You can even apply fallback's separated by comma's like: + /// + /// [@requestKey],[%sessionKey] + /// + /// public static string parseAttribute(IDictionary pageElements, string attributeValue) { // Check for potential querystring/cookie variables - if (attributeValue.Length > 3 && attributeValue.Substring(0, 1) == "[") + // SD: not sure why we are checking for len 3 here? + if (attributeValue.Length > 3 && attributeValue.StartsWith("[")) { - string[] attributeValueSplit = (attributeValue).Split(','); - foreach (string attributeValueItem in attributeValueSplit) + var attributeValueSplit = (attributeValue).Split(','); + + //before proceeding, we don't want to process anything here unless each item starts/ends with a [ ] + // this is because the attribute value could actually just be a json array like [1,2,3] which we don't want to parse + + if (attributeValueSplit.All(x => + //must end with [ + x.EndsWith("]") && + //must start with [ and a special char + (x.StartsWith("[@") || x.StartsWith("[%") || x.StartsWith("[#") || x.StartsWith("[$"))) == false) + { + return attributeValue; + } + + foreach (var attributeValueItem in attributeValueSplit) { attributeValue = attributeValueItem; // Check for special variables (always in square-brackets like [name]) - if (attributeValueItem.Substring(0, 1) == "[" && - attributeValueItem.Substring(attributeValueItem.Length - 1, 1) == "]") + if (attributeValueItem.StartsWith("[") && + attributeValueItem.EndsWith("]")) { // find key name - string keyName = attributeValueItem.Substring(2, attributeValueItem.Length - 3); - string keyType = attributeValueItem.Substring(1, 1); + var keyName = attributeValueItem.Substring(2, attributeValueItem.Length - 3); + var keyType = attributeValueItem.Substring(1, 1); switch (keyType) {