From e4df2f42054e517eb39b47bc381abc5f0ef068da Mon Sep 17 00:00:00 2001 From: Jeavon Date: Thu, 3 Oct 2019 17:46:18 +0100 Subject: [PATCH 01/40] Add ability for editors to search for media items by file name as well as node name. --- src/Umbraco.Examine/MediaValueSetBuilder.cs | 34 +++++++++++++++++-- .../UmbracoExamine/IndexInitializer.cs | 11 +++++- .../Models/Mapping/EntityMapDefinition.cs | 9 +++++ src/Umbraco.Web/Search/UmbracoTreeSearcher.cs | 1 + 4 files changed, 51 insertions(+), 4 deletions(-) diff --git a/src/Umbraco.Examine/MediaValueSetBuilder.cs b/src/Umbraco.Examine/MediaValueSetBuilder.cs index 3839d008b3..e6e7d620d9 100644 --- a/src/Umbraco.Examine/MediaValueSetBuilder.cs +++ b/src/Umbraco.Examine/MediaValueSetBuilder.cs @@ -1,9 +1,12 @@ -using Examine; +using System; +using Examine; using System.Collections.Generic; using System.Linq; +using Newtonsoft.Json; using Umbraco.Core; using Umbraco.Core.Models; using Umbraco.Core.PropertyEditors; +using Umbraco.Core.PropertyEditors.ValueConverters; using Umbraco.Core.Services; using Umbraco.Core.Strings; @@ -13,14 +16,16 @@ namespace Umbraco.Examine { private readonly UrlSegmentProviderCollection _urlSegmentProviders; private readonly IUserService _userService; + private readonly IRuntimeState _runtimeState; public MediaValueSetBuilder(PropertyEditorCollection propertyEditors, UrlSegmentProviderCollection urlSegmentProviders, - IUserService userService) + IUserService userService, IRuntimeState runtimeState) : base(propertyEditors, false) { _urlSegmentProviders = urlSegmentProviders; _userService = userService; + _runtimeState = runtimeState; } /// @@ -29,6 +34,28 @@ namespace Umbraco.Examine foreach (var m in media) { var urlValue = m.GetUrlSegment(_urlSegmentProviders); + + var umbracoFilePath = string.Empty; + var umbracoFile = string.Empty; + + var umbracoFileSource = m.GetValue(Constants.Conventions.Media.File); + + if (umbracoFileSource.DetectIsJson()) + { + var cropper = JsonConvert.DeserializeObject(m.GetValue(Constants.Conventions.Media.File)); + if (cropper != null) + { + umbracoFilePath = cropper.Src; + } + } + else + { + umbracoFilePath = umbracoFileSource; + } + + var uri = new Uri(_runtimeState.ApplicationUrl.GetLeftPart(UriPartial.Authority) + umbracoFilePath); + umbracoFile = uri.Segments.Last(); + var values = new Dictionary> { {"icon", m.ContentType.Icon?.Yield() ?? Enumerable.Empty()}, @@ -44,7 +71,8 @@ namespace Umbraco.Examine {"urlName", urlValue?.Yield() ?? Enumerable.Empty()}, {"path", m.Path?.Yield() ?? Enumerable.Empty()}, {"nodeType", m.ContentType.Id.ToString().Yield() }, - {"creatorName", (m.GetCreatorProfile(_userService)?.Name ?? "??").Yield()} + {"creatorName", (m.GetCreatorProfile(_userService)?.Name ?? "??").Yield()}, + {"__umbracoFile", new object[] {umbracoFile}} }; foreach (var property in m.Properties) diff --git a/src/Umbraco.Tests/UmbracoExamine/IndexInitializer.cs b/src/Umbraco.Tests/UmbracoExamine/IndexInitializer.cs index f7b1799d63..8ac9bc59ea 100644 --- a/src/Umbraco.Tests/UmbracoExamine/IndexInitializer.cs +++ b/src/Umbraco.Tests/UmbracoExamine/IndexInitializer.cs @@ -7,6 +7,7 @@ using Lucene.Net.Analysis; using Lucene.Net.Analysis.Standard; using Lucene.Net.Store; using Moq; +using Umbraco.Core; using Umbraco.Core.Logging; using Umbraco.Core.Models; using Umbraco.Core.Models.Membership; @@ -44,11 +45,19 @@ namespace Umbraco.Tests.UmbracoExamine public static MediaIndexPopulator GetMediaIndexRebuilder(PropertyEditorCollection propertyEditors, IMediaService mediaService) { - var mediaValueSetBuilder = new MediaValueSetBuilder(propertyEditors, new UrlSegmentProviderCollection(new[] { new DefaultUrlSegmentProvider() }), GetMockUserService()); + var mediaValueSetBuilder = new MediaValueSetBuilder(propertyEditors, new UrlSegmentProviderCollection(new[] { new DefaultUrlSegmentProvider() }), GetMockUserService(), MockRuntimeState(RuntimeLevel.Run)); var mediaIndexDataSource = new MediaIndexPopulator(null, mediaService, mediaValueSetBuilder); return mediaIndexDataSource; } + public static IRuntimeState MockRuntimeState(RuntimeLevel level) + { + var runtimeState = Mock.Of(); + Mock.Get(runtimeState).Setup(x => x.Level).Returns(level); + return runtimeState; + } + + public static IContentService GetMockContentService() { long longTotalRecs; diff --git a/src/Umbraco.Web/Models/Mapping/EntityMapDefinition.cs b/src/Umbraco.Web/Models/Mapping/EntityMapDefinition.cs index eb474e4cbe..7e88590552 100644 --- a/src/Umbraco.Web/Models/Mapping/EntityMapDefinition.cs +++ b/src/Umbraco.Web/Models/Mapping/EntityMapDefinition.cs @@ -180,6 +180,15 @@ namespace Umbraco.Web.Models.Mapping target.Name = source.Values.ContainsKey("nodeName") ? source.Values["nodeName"] : "[no name]"; + if (source.Values.ContainsKey("__umbracoFile")) + { + var umbracoFile = source.Values["__umbracoFile"]; + if (umbracoFile != null) + { + target.Name = $"{target.Name} ({umbracoFile})"; + } + } + if (source.Values.ContainsKey(UmbracoExamineIndex.NodeKeyFieldName)) { if (Guid.TryParse(source.Values[UmbracoExamineIndex.NodeKeyFieldName], out var key)) diff --git a/src/Umbraco.Web/Search/UmbracoTreeSearcher.cs b/src/Umbraco.Web/Search/UmbracoTreeSearcher.cs index c3c3dc75ce..23f13c2f33 100644 --- a/src/Umbraco.Web/Search/UmbracoTreeSearcher.cs +++ b/src/Umbraco.Web/Search/UmbracoTreeSearcher.cs @@ -85,6 +85,7 @@ namespace Umbraco.Web.Search break; case UmbracoEntityTypes.Media: type = "media"; + fields = new[] { "__umbracoFile" }; var allMediaStartNodes = _umbracoContext.Security.CurrentUser.CalculateMediaStartNodeIds(_entityService); AppendPath(sb, UmbracoObjectTypes.Media, allMediaStartNodes, searchFrom, ignoreUserStartNodes, _entityService); break; From 72147ab8f24a0634e3f99dca43733106d30b0474 Mon Sep 17 00:00:00 2001 From: Jeavon Date: Fri, 4 Oct 2019 10:34:10 +0100 Subject: [PATCH 02/40] Fixing Examine unit tests --- src/Umbraco.Tests/UmbracoExamine/IndexInitializer.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Umbraco.Tests/UmbracoExamine/IndexInitializer.cs b/src/Umbraco.Tests/UmbracoExamine/IndexInitializer.cs index 8ac9bc59ea..87b4400d58 100644 --- a/src/Umbraco.Tests/UmbracoExamine/IndexInitializer.cs +++ b/src/Umbraco.Tests/UmbracoExamine/IndexInitializer.cs @@ -54,6 +54,8 @@ namespace Umbraco.Tests.UmbracoExamine { var runtimeState = Mock.Of(); Mock.Get(runtimeState).Setup(x => x.Level).Returns(level); + Mock.Get(runtimeState).SetupGet(m => m.ApplicationUrl).Returns(new Uri("https://LocalHost/umbraco")); + return runtimeState; } From 68866e9faf5ad7cad911fe67697bb04d0d99d5cb Mon Sep 17 00:00:00 2001 From: Jeavon Date: Fri, 4 Oct 2019 11:17:36 +0100 Subject: [PATCH 03/40] Adding a constant for the new field name --- src/Umbraco.Examine/MediaValueSetBuilder.cs | 2 +- src/Umbraco.Examine/UmbracoExamineIndex.cs | 1 + src/Umbraco.Web/Models/Mapping/EntityMapDefinition.cs | 4 ++-- src/Umbraco.Web/Search/UmbracoTreeSearcher.cs | 2 +- 4 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/Umbraco.Examine/MediaValueSetBuilder.cs b/src/Umbraco.Examine/MediaValueSetBuilder.cs index e6e7d620d9..db8299dd6d 100644 --- a/src/Umbraco.Examine/MediaValueSetBuilder.cs +++ b/src/Umbraco.Examine/MediaValueSetBuilder.cs @@ -72,7 +72,7 @@ namespace Umbraco.Examine {"path", m.Path?.Yield() ?? Enumerable.Empty()}, {"nodeType", m.ContentType.Id.ToString().Yield() }, {"creatorName", (m.GetCreatorProfile(_userService)?.Name ?? "??").Yield()}, - {"__umbracoFile", new object[] {umbracoFile}} + {UmbracoExamineIndex.UmbracoFileFieldName, new object[] {umbracoFile}} }; foreach (var property in m.Properties) diff --git a/src/Umbraco.Examine/UmbracoExamineIndex.cs b/src/Umbraco.Examine/UmbracoExamineIndex.cs index 24952050da..916ef95d1c 100644 --- a/src/Umbraco.Examine/UmbracoExamineIndex.cs +++ b/src/Umbraco.Examine/UmbracoExamineIndex.cs @@ -32,6 +32,7 @@ namespace Umbraco.Examine /// public const string IndexPathFieldName = SpecialFieldPrefix + "Path"; public const string NodeKeyFieldName = SpecialFieldPrefix + "Key"; + public const string UmbracoFileFieldName = SpecialFieldPrefix + "umbracoFile"; public const string IconFieldName = SpecialFieldPrefix + "Icon"; public const string PublishedFieldName = SpecialFieldPrefix + "Published"; diff --git a/src/Umbraco.Web/Models/Mapping/EntityMapDefinition.cs b/src/Umbraco.Web/Models/Mapping/EntityMapDefinition.cs index 7e88590552..5219ab8b54 100644 --- a/src/Umbraco.Web/Models/Mapping/EntityMapDefinition.cs +++ b/src/Umbraco.Web/Models/Mapping/EntityMapDefinition.cs @@ -180,9 +180,9 @@ namespace Umbraco.Web.Models.Mapping target.Name = source.Values.ContainsKey("nodeName") ? source.Values["nodeName"] : "[no name]"; - if (source.Values.ContainsKey("__umbracoFile")) + if (source.Values.ContainsKey(UmbracoExamineIndex.UmbracoFileFieldName)) { - var umbracoFile = source.Values["__umbracoFile"]; + var umbracoFile = source.Values[UmbracoExamineIndex.UmbracoFileFieldName]; if (umbracoFile != null) { target.Name = $"{target.Name} ({umbracoFile})"; diff --git a/src/Umbraco.Web/Search/UmbracoTreeSearcher.cs b/src/Umbraco.Web/Search/UmbracoTreeSearcher.cs index 23f13c2f33..84889e76c0 100644 --- a/src/Umbraco.Web/Search/UmbracoTreeSearcher.cs +++ b/src/Umbraco.Web/Search/UmbracoTreeSearcher.cs @@ -85,7 +85,7 @@ namespace Umbraco.Web.Search break; case UmbracoEntityTypes.Media: type = "media"; - fields = new[] { "__umbracoFile" }; + fields = new[] { UmbracoExamineIndex.UmbracoFileFieldName }; var allMediaStartNodes = _umbracoContext.Security.CurrentUser.CalculateMediaStartNodeIds(_entityService); AppendPath(sb, UmbracoObjectTypes.Media, allMediaStartNodes, searchFrom, ignoreUserStartNodes, _entityService); break; From 7130c99810afcb39230cb36213d850091020a24d Mon Sep 17 00:00:00 2001 From: Jeavon Date: Fri, 4 Oct 2019 17:44:26 +0100 Subject: [PATCH 04/40] Rename new field and ensure Id is also searchable --- src/Umbraco.Examine/UmbracoExamineIndex.cs | 2 +- src/Umbraco.Web/Search/UmbracoTreeSearcher.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Umbraco.Examine/UmbracoExamineIndex.cs b/src/Umbraco.Examine/UmbracoExamineIndex.cs index 916ef95d1c..e1dd77b994 100644 --- a/src/Umbraco.Examine/UmbracoExamineIndex.cs +++ b/src/Umbraco.Examine/UmbracoExamineIndex.cs @@ -32,7 +32,7 @@ namespace Umbraco.Examine /// public const string IndexPathFieldName = SpecialFieldPrefix + "Path"; public const string NodeKeyFieldName = SpecialFieldPrefix + "Key"; - public const string UmbracoFileFieldName = SpecialFieldPrefix + "umbracoFile"; + public const string UmbracoFileFieldName = "umbracoFileSrc"; public const string IconFieldName = SpecialFieldPrefix + "Icon"; public const string PublishedFieldName = SpecialFieldPrefix + "Published"; diff --git a/src/Umbraco.Web/Search/UmbracoTreeSearcher.cs b/src/Umbraco.Web/Search/UmbracoTreeSearcher.cs index 84889e76c0..a98cd8f212 100644 --- a/src/Umbraco.Web/Search/UmbracoTreeSearcher.cs +++ b/src/Umbraco.Web/Search/UmbracoTreeSearcher.cs @@ -85,7 +85,7 @@ namespace Umbraco.Web.Search break; case UmbracoEntityTypes.Media: type = "media"; - fields = new[] { UmbracoExamineIndex.UmbracoFileFieldName }; + fields = new[] { "id", "__NodeId", UmbracoExamineIndex.UmbracoFileFieldName}; var allMediaStartNodes = _umbracoContext.Security.CurrentUser.CalculateMediaStartNodeIds(_entityService); AppendPath(sb, UmbracoObjectTypes.Media, allMediaStartNodes, searchFrom, ignoreUserStartNodes, _entityService); break; From 61465ed997fcd639d8c41c7e5ebaf680bac79d76 Mon Sep 17 00:00:00 2001 From: Jeavon Date: Fri, 4 Oct 2019 18:30:35 +0100 Subject: [PATCH 05/40] Add null check to umbracoFilePath and used Yield extension method --- src/Umbraco.Examine/MediaValueSetBuilder.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/Umbraco.Examine/MediaValueSetBuilder.cs b/src/Umbraco.Examine/MediaValueSetBuilder.cs index db8299dd6d..20c92eb982 100644 --- a/src/Umbraco.Examine/MediaValueSetBuilder.cs +++ b/src/Umbraco.Examine/MediaValueSetBuilder.cs @@ -53,8 +53,11 @@ namespace Umbraco.Examine umbracoFilePath = umbracoFileSource; } + if (!string.IsNullOrEmpty(umbracoFilePath)) + { var uri = new Uri(_runtimeState.ApplicationUrl.GetLeftPart(UriPartial.Authority) + umbracoFilePath); umbracoFile = uri.Segments.Last(); + } var values = new Dictionary> { @@ -72,7 +75,7 @@ namespace Umbraco.Examine {"path", m.Path?.Yield() ?? Enumerable.Empty()}, {"nodeType", m.ContentType.Id.ToString().Yield() }, {"creatorName", (m.GetCreatorProfile(_userService)?.Name ?? "??").Yield()}, - {UmbracoExamineIndex.UmbracoFileFieldName, new object[] {umbracoFile}} + {UmbracoExamineIndex.UmbracoFileFieldName, umbracoFile.Yield()} }; foreach (var property in m.Properties) From 82af5f26e54275281f02292918950081e3d8ad51 Mon Sep 17 00:00:00 2001 From: Jeavon Date: Wed, 9 Oct 2019 16:16:19 +0100 Subject: [PATCH 06/40] Added a fix to handle hyphens in file names --- src/Umbraco.Web/Search/UmbracoTreeSearcher.cs | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/src/Umbraco.Web/Search/UmbracoTreeSearcher.cs b/src/Umbraco.Web/Search/UmbracoTreeSearcher.cs index a98cd8f212..5e2d0afc65 100644 --- a/src/Umbraco.Web/Search/UmbracoTreeSearcher.cs +++ b/src/Umbraco.Web/Search/UmbracoTreeSearcher.cs @@ -203,11 +203,26 @@ namespace Umbraco.Web.Search foreach (var f in fields) { + var queryWordsReplaced = new string[querywords.Length]; + + // when searching file names containing hyphens we need to replace the hyphens with spaces + if (f.Equals(UmbracoExamineIndex.UmbracoFileFieldName)) + { + for (var index = 0; index < querywords.Length; index++) + { + queryWordsReplaced[index] = querywords[index].Replace("\\-", " ").Trim(" "); + } + } + else + { + queryWordsReplaced = querywords; + } + //additional fields normally sb.Append(f); sb.Append(":"); sb.Append("("); - foreach (var w in querywords) + foreach (var w in queryWordsReplaced) { sb.Append(w.ToLower()); sb.Append("* "); From 0c957c2fd9e494785c6623256dc8ae0f456cfb7b Mon Sep 17 00:00:00 2001 From: Jeavon Date: Wed, 9 Oct 2019 16:46:57 +0100 Subject: [PATCH 07/40] Also replace underscores --- src/Umbraco.Web/Search/UmbracoTreeSearcher.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Umbraco.Web/Search/UmbracoTreeSearcher.cs b/src/Umbraco.Web/Search/UmbracoTreeSearcher.cs index 5e2d0afc65..fd87dd0660 100644 --- a/src/Umbraco.Web/Search/UmbracoTreeSearcher.cs +++ b/src/Umbraco.Web/Search/UmbracoTreeSearcher.cs @@ -210,7 +210,7 @@ namespace Umbraco.Web.Search { for (var index = 0; index < querywords.Length; index++) { - queryWordsReplaced[index] = querywords[index].Replace("\\-", " ").Trim(" "); + queryWordsReplaced[index] = querywords[index].Replace("\\-", " ").Replace("_", " ").Trim(" "); } } else From 702aa41ff2a8801c5f24976dc9ee103afb0f4754 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B8ren=20Kottal?= Date: Wed, 9 Oct 2019 22:19:28 +0200 Subject: [PATCH 08/40] Adds nametemplates for grid editors --- .../Configuration/Grid/IGridEditorConfig.cs | 1 + src/Umbraco.Core/PropertyEditors/GridEditor.cs | 3 +++ .../views/propertyeditors/grid/grid.controller.js | 13 ++++++++++++- .../src/views/propertyeditors/grid/grid.html | 4 ++-- src/Umbraco.Web.UI/config/grid.editors.config.js | 5 ++++- 5 files changed, 22 insertions(+), 4 deletions(-) diff --git a/src/Umbraco.Core/Configuration/Grid/IGridEditorConfig.cs b/src/Umbraco.Core/Configuration/Grid/IGridEditorConfig.cs index e447f7f493..9a11b0ef3e 100644 --- a/src/Umbraco.Core/Configuration/Grid/IGridEditorConfig.cs +++ b/src/Umbraco.Core/Configuration/Grid/IGridEditorConfig.cs @@ -6,6 +6,7 @@ namespace Umbraco.Core.Configuration.Grid public interface IGridEditorConfig { string Name { get; } + string NameTemplate { get; } string Alias { get; } string View { get; } string Render { get; } diff --git a/src/Umbraco.Core/PropertyEditors/GridEditor.cs b/src/Umbraco.Core/PropertyEditors/GridEditor.cs index 986eed9ccc..cc3561fbc2 100644 --- a/src/Umbraco.Core/PropertyEditors/GridEditor.cs +++ b/src/Umbraco.Core/PropertyEditors/GridEditor.cs @@ -18,6 +18,9 @@ namespace Umbraco.Core.PropertyEditors [JsonProperty("name", Required = Required.Always)] public string Name { get; set; } + [JsonProperty("nameTemplate")] + public string NameTemplate { get; set; } + [JsonProperty("alias", Required = Required.Always)] public string Alias { get; set; } diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/grid/grid.controller.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/grid/grid.controller.js index ccc390252b..0a4ab83dea 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/grid/grid.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/grid/grid.controller.js @@ -8,7 +8,8 @@ angular.module("umbraco") angularHelper, $element, eventsService, - editorService + editorService, + $interpolate ) { // Grid status variables @@ -680,6 +681,11 @@ angular.module("umbraco") $scope.showRowConfigurations = !$scope.showRowConfigurations; }; + $scope.getTemplateName = function (control) { + if (control.editor.nameExp) return control.editor.nameExp(control) + return control.editor.name; + } + // ********************************************* // Initialization @@ -923,6 +929,11 @@ angular.module("umbraco") localizationService.localize("grid_" + value.alias, undefined, value.name).then(function (v) { value.name = v; }); + // setup nametemplate + + value.nameExp = !!value.nameTemplate + ? $interpolate(value.nameTemplate) + : undefined; }); $scope.contentReady = true; diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/grid/grid.html b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/grid/grid.html index 6b739a9b86..3995ed703d 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/grid/grid.html +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/grid/grid.html @@ -182,7 +182,7 @@
- {{control.editor.name}} + {{ getTemplateName(control) }}
@@ -190,7 +190,7 @@
- {{control.editor.name}} + {{ getTemplateName(control) }}
diff --git a/src/Umbraco.Web.UI/config/grid.editors.config.js b/src/Umbraco.Web.UI/config/grid.editors.config.js index 12fa726f21..49b843689b 100644 --- a/src/Umbraco.Web.UI/config/grid.editors.config.js +++ b/src/Umbraco.Web.UI/config/grid.editors.config.js @@ -7,12 +7,14 @@ }, { "name": "Image", + "nameTemplate": "{{ 'Image: ' + (value.udi | ncNodeName) }}", "alias": "media", "view": "media", "icon": "icon-picture" }, { "name": "Macro", + "nameTemplate": "{{ 'Macro: ' + value.macroAlias }}", "alias": "macro", "view": "macro", "icon": "icon-settings-alt" @@ -25,6 +27,7 @@ }, { "name": "Headline", + "nameTemplate": "{{ 'Headline: ' + value }}", "alias": "headline", "view": "textstring", "icon": "icon-coin", @@ -43,4 +46,4 @@ "markup": "
#value#
" } } -] \ No newline at end of file +] From 0ee9c2d327a1e8629db99a0292732175eec205df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Tue, 22 Oct 2019 15:22:34 +0200 Subject: [PATCH 09/40] ability to disable confirm button in umb-confirm --- src/Umbraco.Web.UI.Client/src/views/components/umb-confirm.html | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Umbraco.Web.UI.Client/src/views/components/umb-confirm.html b/src/Umbraco.Web.UI.Client/src/views/components/umb-confirm.html index 384c5ccaf7..d8e4f09b8a 100644 --- a/src/Umbraco.Web.UI.Client/src/views/components/umb-confirm.html +++ b/src/Umbraco.Web.UI.Client/src/views/components/umb-confirm.html @@ -14,6 +14,7 @@ action="confirm()" button-style="{{confirmButtonStyle || 'primary'}}" state="confirmButtonState" + disabled="confirmDisabled === true" label-key="{{confirmLabelKey || 'general_ok'}}">
From 98df5eae6739fd1529910028e2fb687289af2718 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Tue, 22 Oct 2019 15:22:52 +0200 Subject: [PATCH 10/40] never underline icons in table --- src/Umbraco.Web.UI.Client/src/less/components/umb-table.less | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Umbraco.Web.UI.Client/src/less/components/umb-table.less b/src/Umbraco.Web.UI.Client/src/less/components/umb-table.less index 5e766b7578..94c0318fca 100644 --- a/src/Umbraco.Web.UI.Client/src/less/components/umb-table.less +++ b/src/Umbraco.Web.UI.Client/src/less/components/umb-table.less @@ -161,6 +161,7 @@ input.umb-table__input { line-height: 20px; color: @ui-option-type; vertical-align: bottom; + text-decoration: none; } .umb-table-body__checkicon, From 0f07ecba5463257d4b641e669f2c46ce2ffaf761 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Tue, 22 Oct 2019 15:23:46 +0200 Subject: [PATCH 11/40] umb-confirm ability to set wether the confirm button is disabled via confirmDisabled --- .../src/common/directives/components/umbconfirm.directive.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/umbconfirm.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/components/umbconfirm.directive.js index 1ddd09357a..9114cfb1c1 100644 --- a/src/Umbraco.Web.UI.Client/src/common/directives/components/umbconfirm.directive.js +++ b/src/Umbraco.Web.UI.Client/src/common/directives/components/umbconfirm.directive.js @@ -56,6 +56,7 @@ function confirmDirective() { onCancel: '=', caption: '@', confirmButtonStyle: '@', + confirmDisabled: ' Date: Tue, 22 Oct 2019 15:24:36 +0200 Subject: [PATCH 12/40] links to edit references --- .../src/views/datatypes/delete.html | 20 +++++++++---------- .../datatypes/views/datatype.references.html | 4 ++-- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/views/datatypes/delete.html b/src/Umbraco.Web.UI.Client/src/views/datatypes/delete.html index 6c415e9f38..32140cf6f2 100644 --- a/src/Umbraco.Web.UI.Client/src/views/datatypes/delete.html +++ b/src/Umbraco.Web.UI.Client/src/views/datatypes/delete.html @@ -49,9 +49,9 @@ - - {{::relation.name}} - {{::property.name}}{{$last ? '' : ', '}} + + {{::reference.name}} + {{::property.name}}{{$last ? '' : ', '}} @@ -73,9 +73,9 @@ - - {{::relation.name}} - {{::property.name}}{{$last ? '' : ', '}} + + {{::reference.name}} + {{::property.name}}{{$last ? '' : ', '}} @@ -97,9 +97,9 @@ - - {{::relation.name}} - {{::property.name}}{{$last ? '' : ', '}} + + {{::reference.name}} + {{::property.name}}{{$last ? '' : ', '}} @@ -112,7 +112,7 @@
- {{::reference.name}}
{{::reference.alias}}
{{::reference.properties | umbCmsJoinArray:', ':'name'}}
- + @@ -98,7 +98,7 @@
{{::reference.name}}
{{::reference.alias}}
{{::reference.properties | umbCmsJoinArray:', ':'name'}}
- + From 89e6cc3611c688177b7b405da40f35a5680b355d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Tue, 22 Oct 2019 15:26:59 +0200 Subject: [PATCH 13/40] do close dialog, even thought people might open in a tab. --- src/Umbraco.Web.UI.Client/src/views/datatypes/delete.html | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/views/datatypes/delete.html b/src/Umbraco.Web.UI.Client/src/views/datatypes/delete.html index 32140cf6f2..aedb7c7545 100644 --- a/src/Umbraco.Web.UI.Client/src/views/datatypes/delete.html +++ b/src/Umbraco.Web.UI.Client/src/views/datatypes/delete.html @@ -50,7 +50,7 @@ - {{::reference.name}} + {{::reference.name}} {{::property.name}}{{$last ? '' : ', '}} @@ -74,7 +74,7 @@ - {{::reference.name}} + {{::reference.name}} {{::property.name}}{{$last ? '' : ', '}} @@ -98,7 +98,7 @@ - {{::reference.name}} + {{::reference.name}} {{::property.name}}{{$last ? '' : ', '}} From 6776d6cde6d4e73a87c1eae23078aa715fc74999 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Tue, 22 Oct 2019 15:35:50 +0200 Subject: [PATCH 14/40] hide dialog if opening reference in this tab/window. --- .../src/views/datatypes/datatype.delete.controller.js | 6 ++++++ src/Umbraco.Web.UI.Client/src/views/datatypes/delete.html | 6 +++--- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/views/datatypes/datatype.delete.controller.js b/src/Umbraco.Web.UI.Client/src/views/datatypes/datatype.delete.controller.js index c6c58d9fa6..4542cde343 100644 --- a/src/Umbraco.Web.UI.Client/src/views/datatypes/datatype.delete.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/datatypes/datatype.delete.controller.js @@ -51,6 +51,12 @@ function DataTypeDeleteController($scope, dataTypeResource, treeService, navigat navigationService.hideDialog(); }; + vm.onReferenceClicked = function(event) { + if (event.metaKey !== true) { + navigationService.hideDialog(); + } + }; + vm.labels = {}; localizationService .localize("editdatatype_acceptDeleteConsequence", [$scope.currentNode.name]) diff --git a/src/Umbraco.Web.UI.Client/src/views/datatypes/delete.html b/src/Umbraco.Web.UI.Client/src/views/datatypes/delete.html index aedb7c7545..52adfcccec 100644 --- a/src/Umbraco.Web.UI.Client/src/views/datatypes/delete.html +++ b/src/Umbraco.Web.UI.Client/src/views/datatypes/delete.html @@ -50,7 +50,7 @@ - {{::reference.name}} + {{::reference.name}} {{::property.name}}{{$last ? '' : ', '}} @@ -74,7 +74,7 @@ - {{::reference.name}} + {{::reference.name}} {{::property.name}}{{$last ? '' : ', '}} @@ -98,7 +98,7 @@ - {{::reference.name}} + {{::reference.name}} {{::property.name}}{{$last ? '' : ', '}} From f20394556cb59bafe5fbba30c5c60db7c1c31d1f Mon Sep 17 00:00:00 2001 From: elitsa Date: Fri, 25 Oct 2019 11:58:04 +0200 Subject: [PATCH 15/40] Removed trailing newlines --- .../src/views/propertyeditors/grid/grid.controller.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/grid/grid.controller.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/grid/grid.controller.js index 0a4ab83dea..32f495e32b 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/grid/grid.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/grid/grid.controller.js @@ -662,7 +662,6 @@ angular.module("umbraco") return ((spans / $scope.model.config.items.columns) * 100).toFixed(8); }; - $scope.clearPrompt = function (scopedObject, e) { scopedObject.deletePrompt = false; e.preventDefault(); @@ -686,7 +685,6 @@ angular.module("umbraco") return control.editor.name; } - // ********************************************* // Initialization // these methods are called from ng-init on the template From 76bbf01cbe647708583f8284a010f014752cbab0 Mon Sep 17 00:00:00 2001 From: Jeavon Date: Tue, 29 Oct 2019 15:25:10 +0000 Subject: [PATCH 16/40] Changed field to a List as suggested in review --- src/Umbraco.Tests/UmbracoExamine/IndexInitializer.cs | 2 +- src/Umbraco.Web/Search/UmbracoTreeSearcher.cs | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/Umbraco.Tests/UmbracoExamine/IndexInitializer.cs b/src/Umbraco.Tests/UmbracoExamine/IndexInitializer.cs index 87b4400d58..5c9c965cd1 100644 --- a/src/Umbraco.Tests/UmbracoExamine/IndexInitializer.cs +++ b/src/Umbraco.Tests/UmbracoExamine/IndexInitializer.cs @@ -54,7 +54,7 @@ namespace Umbraco.Tests.UmbracoExamine { var runtimeState = Mock.Of(); Mock.Get(runtimeState).Setup(x => x.Level).Returns(level); - Mock.Get(runtimeState).SetupGet(m => m.ApplicationUrl).Returns(new Uri("https://LocalHost/umbraco")); + Mock.Get(runtimeState).SetupGet(m => m.ApplicationUrl).Returns(new Uri("https://localhost/umbraco")); return runtimeState; } diff --git a/src/Umbraco.Web/Search/UmbracoTreeSearcher.cs b/src/Umbraco.Web/Search/UmbracoTreeSearcher.cs index 7a62097490..463f4b09df 100644 --- a/src/Umbraco.Web/Search/UmbracoTreeSearcher.cs +++ b/src/Umbraco.Web/Search/UmbracoTreeSearcher.cs @@ -67,7 +67,7 @@ namespace Umbraco.Web.Search string type; var indexName = Constants.UmbracoIndexes.InternalIndexName; - var fields = new[] { "id", "__NodeId", "__Key" }; + var fields = new List { "id", "__NodeId", "__Key" }; // TODO: WE should try to allow passing in a lucene raw query, however we will still need to do some manual string // manipulation for things like start paths, member types, etc... @@ -87,7 +87,7 @@ namespace Umbraco.Web.Search case UmbracoEntityTypes.Member: indexName = Constants.UmbracoIndexes.MembersIndexName; type = "member"; - fields = new[] { "id", "__NodeId", "__Key", "email", "loginName" }; + fields.AddRange(new[]{ "email", "loginName"}); if (searchFrom != null && searchFrom != Constants.Conventions.MemberTypes.AllMembersListId && searchFrom.Trim() != "-1") { sb.Append("+__NodeTypeAlias:"); @@ -97,7 +97,7 @@ namespace Umbraco.Web.Search break; case UmbracoEntityTypes.Media: type = "media"; - fields = new[] { "id", "__NodeId", UmbracoExamineIndex.UmbracoFileFieldName}; + fields.AddRange(new[] { UmbracoExamineIndex.UmbracoFileFieldName }); var allMediaStartNodes = _umbracoContext.Security.CurrentUser.CalculateMediaStartNodeIds(_entityService); AppendPath(sb, UmbracoObjectTypes.Media, allMediaStartNodes, searchFrom, ignoreUserStartNodes, _entityService); break; @@ -162,7 +162,7 @@ namespace Umbraco.Web.Search return _mapper.MapEnumerable(results); } - private bool BuildQuery(StringBuilder sb, string query, string searchFrom, string[] fields, string type) + private bool BuildQuery(StringBuilder sb, string query, string searchFrom, List fields, string type) { //build a lucene query: // the nodeName will be boosted 10x without wildcards From 501f9495a9c794894f0ade1a591f5fe5752cd78b Mon Sep 17 00:00:00 2001 From: Bjarke Berg Date: Thu, 26 Sep 2019 10:05:41 +0200 Subject: [PATCH 17/40] Bumb version to 8.3 --- src/SolutionInfo.cs | 4 ++-- src/Umbraco.Web.UI/Umbraco.Web.UI.csproj | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/SolutionInfo.cs b/src/SolutionInfo.cs index 31a9953b23..bf3a271d32 100644 --- a/src/SolutionInfo.cs +++ b/src/SolutionInfo.cs @@ -18,5 +18,5 @@ using System.Resources; [assembly: AssemblyVersion("8.0.0")] // these are FYI and changed automatically -[assembly: AssemblyFileVersion("8.2.2")] -[assembly: AssemblyInformationalVersion("8.2.2")] +[assembly: AssemblyFileVersion("8.3.0")] +[assembly: AssemblyInformationalVersion("8.3.0")] diff --git a/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj b/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj index 10ca65357d..6c20e8c765 100644 --- a/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj +++ b/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj @@ -345,9 +345,9 @@ False True - 8220 + 8300 / - http://localhost:8220/ + http://localhost:8300/ False False From 6b318207c78e30c09f0ba93e824d3296b819aad0 Mon Sep 17 00:00:00 2001 From: Rasmus John Pedersen Date: Thu, 26 Sep 2019 16:32:58 +0200 Subject: [PATCH 18/40] Disable rename alias of system user groups --- .../editor/umbeditorheader.directive.js | 3 ++- .../src/less/components/umb-locked-field.less | 3 ++- .../components/editor/umb-editor-header.html | 2 +- .../views/components/umb-generate-alias.html | 2 +- .../src/views/users/group.html | 1 + .../Filters/UserGroupValidateAttribute.cs | 13 +++++++++++++ .../Models/ContentEditing/UserGroupBasic.cs | 6 ++++++ .../Models/Mapping/UserMapDefinition.cs | 18 +++++++++++------- 8 files changed, 37 insertions(+), 11 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/editor/umbeditorheader.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/components/editor/umbeditorheader.directive.js index 76c2e585f8..ebb780c36e 100644 --- a/src/Umbraco.Web.UI.Client/src/common/directives/components/editor/umbeditorheader.directive.js +++ b/src/Umbraco.Web.UI.Client/src/common/directives/components/editor/umbeditorheader.directive.js @@ -195,6 +195,7 @@ Use this directive to construct a header inside the main editor window. @param {string=} icon Show and edit the content icon. Opens an overlay to change the icon. @param {boolean=} hideIcon Set to true to hide icon. @param {string=} alias show and edit the content alias. +@param {boolean=} aliasLocked Set to true to lock the alias. @param {boolean=} hideAlias Set to true to hide alias. @param {string=} description Add a description to the content. @param {boolean=} hideDescription Set to true to hide description. @@ -207,7 +208,6 @@ Use this directive to construct a header inside the main editor window. function EditorHeaderDirective(editorService) { function link(scope) { - scope.vm = {}; scope.vm.dropdownOpen = false; scope.vm.currentVariant = ""; @@ -262,6 +262,7 @@ Use this directive to construct a header inside the main editor window. icon: "=", hideIcon: "@", alias: "=", + aliasLocked: "<", hideAlias: "=", description: "=", hideDescription: "@", diff --git a/src/Umbraco.Web.UI.Client/src/less/components/umb-locked-field.less b/src/Umbraco.Web.UI.Client/src/less/components/umb-locked-field.less index 8d9ae86ce7..3dd169e892 100644 --- a/src/Umbraco.Web.UI.Client/src/less/components/umb-locked-field.less +++ b/src/Umbraco.Web.UI.Client/src/less/components/umb-locked-field.less @@ -29,7 +29,8 @@ color: @gray-3; } -input.umb-locked-field__input { +input.umb-locked-field__input, +.umb-locked-field__text { background: rgba(255, 255, 255, 0); // if using transparent it will hide the text in safari border-color: transparent !important; font-size: 13px; diff --git a/src/Umbraco.Web.UI.Client/src/views/components/editor/umb-editor-header.html b/src/Umbraco.Web.UI.Client/src/views/components/editor/umb-editor-header.html index aca27da7be..824caa87a9 100644 --- a/src/Umbraco.Web.UI.Client/src/views/components/editor/umb-editor-header.html +++ b/src/Umbraco.Web.UI.Client/src/views/components/editor/umb-editor-header.html @@ -46,7 +46,7 @@ ng-if="!hideAlias" alias="$parent.alias" alias-from="$parent.name" - enable-lock="true" + enable-lock="aliasLocked !== true" validation-position="'right'" server-validation-field="Alias"> diff --git a/src/Umbraco.Web.UI.Client/src/views/components/umb-generate-alias.html b/src/Umbraco.Web.UI.Client/src/views/components/umb-generate-alias.html index 9d68ea1b63..836e8fc3f1 100644 --- a/src/Umbraco.Web.UI.Client/src/views/components/umb-generate-alias.html +++ b/src/Umbraco.Web.UI.Client/src/views/components/umb-generate-alias.html @@ -1,5 +1,5 @@
- {{ alias }} + {{ alias }}
[DataMember(Name = "userCount")] public int UserCount { get; set; } + + /// + /// Is the user group a system group e.g. "Administrators", "Sensitive data" or "Translators" + /// + [DataMember(Name = "isSystemUserGroup")] + public bool IsSystemUserGroup { get; set; } } } diff --git a/src/Umbraco.Web/Models/Mapping/UserMapDefinition.cs b/src/Umbraco.Web/Models/Mapping/UserMapDefinition.cs index 4acda1e552..abbb67c4aa 100644 --- a/src/Umbraco.Web/Models/Mapping/UserMapDefinition.cs +++ b/src/Umbraco.Web/Models/Mapping/UserMapDefinition.cs @@ -138,7 +138,7 @@ namespace Umbraco.Web.Models.Mapping } // Umbraco.Code.MapAll -ContentStartNode -UserCount -MediaStartNode -Key -Sections - // Umbraco.Code.MapAll -Notifications -Udi -Trashed -AdditionalData + // Umbraco.Code.MapAll -Notifications -Udi -Trashed -AdditionalData -IsSystemUserGroup private void Map(IReadOnlyUserGroup source, UserGroupBasic target, MapperContext context) { target.Alias = source.Alias; @@ -147,11 +147,11 @@ namespace Umbraco.Web.Models.Mapping target.Name = source.Name; target.ParentId = -1; target.Path = "-1," + source.Id; - MapUserGroupBasic(target, source.AllowedSections, source.StartContentId, source.StartMediaId, context); + MapUserGroupBasic(target, source.Alias, source.AllowedSections, source.StartContentId, source.StartMediaId, context); } // Umbraco.Code.MapAll -ContentStartNode -MediaStartNode -Sections -Notifications - // Umbraco.Code.MapAll -Udi -Trashed -AdditionalData + // Umbraco.Code.MapAll -Udi -Trashed -AdditionalData -IsSystemUserGroup private void Map(IUserGroup source, UserGroupBasic target, MapperContext context) { target.Alias = source.Alias; @@ -162,7 +162,7 @@ namespace Umbraco.Web.Models.Mapping target.ParentId = -1; target.Path = "-1," + source.Id; target.UserCount = source.UserCount; - MapUserGroupBasic(target, source.AllowedSections, source.StartContentId, source.StartMediaId, context); + MapUserGroupBasic(target, source.Alias, source.AllowedSections, source.StartContentId, source.StartMediaId, context); } // Umbraco.Code.MapAll -Udi -Trashed -AdditionalData -AssignedPermissions @@ -198,7 +198,7 @@ namespace Umbraco.Web.Models.Mapping } // Umbraco.Code.MapAll -ContentStartNode -MediaStartNode -Sections -Notifications -Udi - // Umbraco.Code.MapAll -Trashed -AdditionalData -Users -AssignedPermissions + // Umbraco.Code.MapAll -Trashed -AdditionalData -Users -AssignedPermissions -IsSystemUserGroup private void Map(IUserGroup source, UserGroupDisplay target, MapperContext context) { target.Alias = source.Alias; @@ -211,7 +211,7 @@ namespace Umbraco.Web.Models.Mapping target.Path = "-1," + source.Id; target.UserCount = source.UserCount; - MapUserGroupBasic(target, source.AllowedSections, source.StartContentId, source.StartMediaId, context); + MapUserGroupBasic(target, source.Alias, source.AllowedSections, source.StartContentId, source.StartMediaId, context); //Important! Currently we are never mapping to multiple UserGroupDisplay objects but if we start doing that // this will cause an N+1 and we'll need to change how this works. @@ -334,8 +334,12 @@ namespace Umbraco.Web.Models.Mapping // helpers - private void MapUserGroupBasic(UserGroupBasic target, IEnumerable sourceAllowedSections, int? sourceStartContentId, int? sourceStartMediaId, MapperContext context) + private void MapUserGroupBasic(UserGroupBasic target, string alias, IEnumerable sourceAllowedSections, int? sourceStartContentId, int? sourceStartMediaId, MapperContext context) { + target.IsSystemUserGroup = alias == Constants.Security.AdminGroupAlias + || alias == Constants.Security.TranslatorGroupAlias + || alias == Constants.Security.SensitiveDataGroupAlias; + var allSections = _sectionService.GetSections(); target.Sections = context.MapEnumerable(allSections.Where(x => sourceAllowedSections.Contains(x.Alias))); From 640f042acfe3c0dce198b88fa8e362ccb5ecc5e7 Mon Sep 17 00:00:00 2001 From: Rasmus John Pedersen Date: Thu, 26 Sep 2019 18:39:54 +0200 Subject: [PATCH 19/40] Disallow deleting "Sensitive data" user group --- .../Models/Membership/UserGroupExtensions.cs | 13 +++++++++++++ .../users/views/groups/groups.controller.js | 2 +- .../src/views/users/views/groups/groups.html | 2 +- .../Filters/UserGroupValidateAttribute.cs | 13 ++++--------- .../Editors/UserGroupsController.cs | 4 ++-- .../Models/Mapping/UserMapDefinition.cs | 19 ++++++++++--------- 6 files changed, 31 insertions(+), 22 deletions(-) diff --git a/src/Umbraco.Core/Models/Membership/UserGroupExtensions.cs b/src/Umbraco.Core/Models/Membership/UserGroupExtensions.cs index 3903fe405b..b1d0189c56 100644 --- a/src/Umbraco.Core/Models/Membership/UserGroupExtensions.cs +++ b/src/Umbraco.Core/Models/Membership/UserGroupExtensions.cs @@ -15,6 +15,12 @@ namespace Umbraco.Core.Models.Membership return new ReadOnlyUserGroup(group.Id, group.Name, group.Icon, group.StartContentId, group.StartMediaId, group.Alias, group.AllowedSections, group.Permissions); } + public static bool IsSystemUserGroup(this IUserGroup group) => + IsSystemUserGroup(group.Alias); + + public static bool IsSystemUserGroup(this IReadOnlyUserGroup group) => + IsSystemUserGroup(group.Alias); + public static IReadOnlyUserGroup ToReadOnlyGroup(this UserGroupDto group) { return new ReadOnlyUserGroup(group.Id, group.Name, group.Icon, @@ -22,5 +28,12 @@ namespace Umbraco.Core.Models.Membership group.UserGroup2AppDtos.Select(x => x.AppAlias).ToArray(), group.DefaultPermissions == null ? Enumerable.Empty() : group.DefaultPermissions.ToCharArray().Select(x => x.ToString())); } + + private static bool IsSystemUserGroup(this string groupAlias) + { + return groupAlias == Constants.Security.AdminGroupAlias + || groupAlias == Constants.Security.SensitiveDataGroupAlias + || groupAlias == Constants.Security.TranslatorGroupAlias; + } } } diff --git a/src/Umbraco.Web.UI.Client/src/views/users/views/groups/groups.controller.js b/src/Umbraco.Web.UI.Client/src/views/users/views/groups/groups.controller.js index 1e51d4585e..b21859f5c4 100644 --- a/src/Umbraco.Web.UI.Client/src/views/users/views/groups/groups.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/users/views/groups/groups.controller.js @@ -81,7 +81,7 @@ } // Disallow selection of the admin/translators group, the checkbox is not visible in the UI, but clicking(and thus selecting) is still possible. // Currently selection can only be used for deleting, and the Controller will also disallow deleting the admin group. - if (userGroup.alias === "admin" || userGroup.alias === "translator") + if (userGroup.isSystemUserGroup) return; listViewHelper.selectHandler(userGroup, $index, vm.userGroups, vm.selection, $event); diff --git a/src/Umbraco.Web.UI.Client/src/views/users/views/groups/groups.html b/src/Umbraco.Web.UI.Client/src/views/users/views/groups/groups.html index 5d1496d90f..4d252a3ae0 100644 --- a/src/Umbraco.Web.UI.Client/src/views/users/views/groups/groups.html +++ b/src/Umbraco.Web.UI.Client/src/views/users/views/groups/groups.html @@ -86,7 +86,7 @@
+ ng-class="{'-selected': group.selected, '-selectable': group.hasAccess && !group.isSystemUserGroup}">
diff --git a/src/Umbraco.Web/Editors/Filters/UserGroupValidateAttribute.cs b/src/Umbraco.Web/Editors/Filters/UserGroupValidateAttribute.cs index 7d465a9ddc..78cd8e6a4d 100644 --- a/src/Umbraco.Web/Editors/Filters/UserGroupValidateAttribute.cs +++ b/src/Umbraco.Web/Editors/Filters/UserGroupValidateAttribute.cs @@ -51,16 +51,11 @@ namespace Umbraco.Web.Editors.Filters return; } - if (persisted.Alias != userGroupSave.Alias) + if (persisted.Alias != userGroupSave.Alias && persisted.IsSystemUserGroup()) { - if (persisted.Alias == Constants.Security.AdminGroupAlias - || persisted.Alias == Constants.Security.SensitiveDataGroupAlias - || persisted.Alias == Constants.Security.TranslatorGroupAlias) - { - var message = $"User group with alias: {persisted.Alias} cannot be changed"; - actionContext.Response = actionContext.Request.CreateErrorResponse(HttpStatusCode.BadRequest, message); - return; - } + var message = $"User group with alias: {persisted.Alias} cannot be changed"; + actionContext.Response = actionContext.Request.CreateErrorResponse(HttpStatusCode.BadRequest, message); + return; } //map the model to the persisted instance diff --git a/src/Umbraco.Web/Editors/UserGroupsController.cs b/src/Umbraco.Web/Editors/UserGroupsController.cs index 1b64722735..b081ca6137 100644 --- a/src/Umbraco.Web/Editors/UserGroupsController.cs +++ b/src/Umbraco.Web/Editors/UserGroupsController.cs @@ -154,8 +154,8 @@ namespace Umbraco.Web.Editors public HttpResponseMessage PostDeleteUserGroups([FromUri] int[] userGroupIds) { var userGroups = Services.UserService.GetAllUserGroups(userGroupIds) - //never delete the admin group or translators group - .Where(x => x.Alias != Constants.Security.AdminGroupAlias && x.Alias != Constants.Security.TranslatorGroupAlias) + //never delete the admin group, sensitive data or translators group + .Where(x => !x.IsSystemUserGroup()) .ToArray(); foreach (var userGroup in userGroups) { diff --git a/src/Umbraco.Web/Models/Mapping/UserMapDefinition.cs b/src/Umbraco.Web/Models/Mapping/UserMapDefinition.cs index abbb67c4aa..88960fb189 100644 --- a/src/Umbraco.Web/Models/Mapping/UserMapDefinition.cs +++ b/src/Umbraco.Web/Models/Mapping/UserMapDefinition.cs @@ -147,7 +147,9 @@ namespace Umbraco.Web.Models.Mapping target.Name = source.Name; target.ParentId = -1; target.Path = "-1," + source.Id; - MapUserGroupBasic(target, source.Alias, source.AllowedSections, source.StartContentId, source.StartMediaId, context); + target.IsSystemUserGroup = source.IsSystemUserGroup(); + + MapUserGroupBasic(target, source.AllowedSections, source.StartContentId, source.StartMediaId, context); } // Umbraco.Code.MapAll -ContentStartNode -MediaStartNode -Sections -Notifications @@ -162,7 +164,9 @@ namespace Umbraco.Web.Models.Mapping target.ParentId = -1; target.Path = "-1," + source.Id; target.UserCount = source.UserCount; - MapUserGroupBasic(target, source.Alias, source.AllowedSections, source.StartContentId, source.StartMediaId, context); + target.IsSystemUserGroup = source.IsSystemUserGroup(); + + MapUserGroupBasic(target, source.AllowedSections, source.StartContentId, source.StartMediaId, context); } // Umbraco.Code.MapAll -Udi -Trashed -AdditionalData -AssignedPermissions @@ -198,7 +202,7 @@ namespace Umbraco.Web.Models.Mapping } // Umbraco.Code.MapAll -ContentStartNode -MediaStartNode -Sections -Notifications -Udi - // Umbraco.Code.MapAll -Trashed -AdditionalData -Users -AssignedPermissions -IsSystemUserGroup + // Umbraco.Code.MapAll -Trashed -AdditionalData -Users -AssignedPermissions private void Map(IUserGroup source, UserGroupDisplay target, MapperContext context) { target.Alias = source.Alias; @@ -210,8 +214,9 @@ namespace Umbraco.Web.Models.Mapping target.ParentId = -1; target.Path = "-1," + source.Id; target.UserCount = source.UserCount; + target.IsSystemUserGroup = source.IsSystemUserGroup(); - MapUserGroupBasic(target, source.Alias, source.AllowedSections, source.StartContentId, source.StartMediaId, context); + MapUserGroupBasic(target, source.AllowedSections, source.StartContentId, source.StartMediaId, context); //Important! Currently we are never mapping to multiple UserGroupDisplay objects but if we start doing that // this will cause an N+1 and we'll need to change how this works. @@ -334,12 +339,8 @@ namespace Umbraco.Web.Models.Mapping // helpers - private void MapUserGroupBasic(UserGroupBasic target, string alias, IEnumerable sourceAllowedSections, int? sourceStartContentId, int? sourceStartMediaId, MapperContext context) + private void MapUserGroupBasic(UserGroupBasic target, IEnumerable sourceAllowedSections, int? sourceStartContentId, int? sourceStartMediaId, MapperContext context) { - target.IsSystemUserGroup = alias == Constants.Security.AdminGroupAlias - || alias == Constants.Security.TranslatorGroupAlias - || alias == Constants.Security.SensitiveDataGroupAlias; - var allSections = _sectionService.GetSections(); target.Sections = context.MapEnumerable(allSections.Where(x => sourceAllowedSections.Contains(x.Alias))); From 73fc648718288191e66e4dd6da1984b9ea8c8212 Mon Sep 17 00:00:00 2001 From: Shannon Date: Thu, 10 Oct 2019 20:45:16 +1100 Subject: [PATCH 20/40] Adds logic to ensure you can't change to a culture that is already assigned + test --- .../Implement/LanguageRepository.cs | 13 ++++++++++++ .../Repositories/LanguageRepositoryTest.cs | 21 ++++++++++++++++++- 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/src/Umbraco.Core/Persistence/Repositories/Implement/LanguageRepository.cs b/src/Umbraco.Core/Persistence/Repositories/Implement/LanguageRepository.cs index 8597bbf19f..4c452ad554 100644 --- a/src/Umbraco.Core/Persistence/Repositories/Implement/LanguageRepository.cs +++ b/src/Umbraco.Core/Persistence/Repositories/Implement/LanguageRepository.cs @@ -182,6 +182,19 @@ namespace Umbraco.Core.Persistence.Repositories.Implement throw new InvalidOperationException($"Cannot save the default language ({entity.IsoCode}) as non-default. Make another language the default language instead."); } + if (entity.IsPropertyDirty(nameof(ILanguage.IsoCode))) + { + //if the iso code is changing, ensure there's not another lang with the same code already assigned + var sameCode = Sql() + .SelectCount() + .From() + .Where(x => x.IsoCode == entity.IsoCode && x.Id != entity.Id); + + var countOfSameCode = Database.ExecuteScalar(sameCode); + if (countOfSameCode > 0) + throw new InvalidOperationException($"Cannot update the language to a new culture: {entity.IsoCode} since that culture is already assigned to another language entity."); + } + // fallback cycles are detected at service level // update diff --git a/src/Umbraco.Tests/Persistence/Repositories/LanguageRepositoryTest.cs b/src/Umbraco.Tests/Persistence/Repositories/LanguageRepositoryTest.cs index 03c1713268..85a3374cea 100644 --- a/src/Umbraco.Tests/Persistence/Repositories/LanguageRepositoryTest.cs +++ b/src/Umbraco.Tests/Persistence/Repositories/LanguageRepositoryTest.cs @@ -1,4 +1,5 @@ -using System.Globalization; +using System; +using System.Globalization; using System.Linq; using Moq; using NUnit.Framework; @@ -297,6 +298,24 @@ namespace Umbraco.Tests.Persistence.Repositories } } + [Test] + public void Perform_Update_With_Existing_Culture() + { + // Arrange + var provider = TestObjects.GetScopeProvider(Logger); + using (var scope = provider.CreateScope()) + { + var repository = CreateRepository(provider); + + // Act + var language = repository.Get(5); + language.IsoCode = "da-DK"; + language.CultureName = "da-DK"; + + Assert.Throws(() => repository.Save(language)); + } + } + [Test] public void Can_Perform_Delete_On_LanguageRepository() { From a7eb693053d9793309630a0430c017f5420030fa Mon Sep 17 00:00:00 2001 From: Shannon Date: Mon, 14 Oct 2019 15:21:00 +1100 Subject: [PATCH 21/40] updates logic for cache refreshers for languages to deal with updating nucache and examine --- .../Cache/ContentCacheRefresher.cs | 45 ++++---- .../Cache/LanguageCacheRefresher.cs | 108 ++++++++++++++++-- src/Umbraco.Web/Search/ExamineComponent.cs | 26 ++++- 3 files changed, 142 insertions(+), 37 deletions(-) diff --git a/src/Umbraco.Web/Cache/ContentCacheRefresher.cs b/src/Umbraco.Web/Cache/ContentCacheRefresher.cs index 21b97d980d..5acd94d12c 100644 --- a/src/Umbraco.Web/Cache/ContentCacheRefresher.cs +++ b/src/Umbraco.Web/Cache/ContentCacheRefresher.cs @@ -97,13 +97,7 @@ namespace Umbraco.Web.Cache //if (Suspendable.PageCacheRefresher.CanUpdateDocumentCache) // ... - _publishedSnapshotService.Notify(payloads, out _, out var publishedChanged); - - if (payloads.Any(x => x.ChangeTypes.HasType(TreeChangeTypes.RefreshAll)) || publishedChanged) - { - // when a public version changes - AppCaches.ClearPartialViewCache(); - } + NotifyPublishedSnapshotService(_publishedSnapshotService, AppCaches, payloads); base.Refresh(payloads); } @@ -111,30 +105,35 @@ namespace Umbraco.Web.Cache // these events should never trigger // everything should be PAYLOAD/JSON - public override void RefreshAll() - { - throw new NotSupportedException(); - } + public override void RefreshAll() => throw new NotSupportedException(); - public override void Refresh(int id) - { - throw new NotSupportedException(); - } + public override void Refresh(int id) => throw new NotSupportedException(); - public override void Refresh(Guid id) - { - throw new NotSupportedException(); - } + public override void Refresh(Guid id) => throw new NotSupportedException(); - public override void Remove(int id) - { - throw new NotSupportedException(); - } + public override void Remove(int id) => throw new NotSupportedException(); #endregion #region Json + /// + /// Refreshes the publish snapshot service and if there are published changes ensures that partial view caches are refreshed too + /// + /// + /// + /// + internal static void NotifyPublishedSnapshotService(IPublishedSnapshotService service, AppCaches appCaches, JsonPayload[] payloads) + { + service.Notify(payloads, out _, out var publishedChanged); + + if (payloads.Any(x => x.ChangeTypes.HasType(TreeChangeTypes.RefreshAll)) || publishedChanged) + { + // when a public version changes + appCaches.ClearPartialViewCache(); + } + } + public class JsonPayload { public JsonPayload(int id, TreeChangeTypes changeTypes) diff --git a/src/Umbraco.Web/Cache/LanguageCacheRefresher.cs b/src/Umbraco.Web/Cache/LanguageCacheRefresher.cs index 9093124609..03102ec969 100644 --- a/src/Umbraco.Web/Cache/LanguageCacheRefresher.cs +++ b/src/Umbraco.Web/Cache/LanguageCacheRefresher.cs @@ -8,7 +8,9 @@ using Umbraco.Web.PublishedCache; namespace Umbraco.Web.Cache { - public sealed class LanguageCacheRefresher : CacheRefresherBase + public sealed class LanguageCacheRefresher : PayloadCacheRefresherBase + + //CacheRefresherBase { public LanguageCacheRefresher(AppCaches appCaches, IPublishedSnapshotService publishedSnapshotService, IDomainService domainService) : base(appCaches) @@ -33,21 +35,62 @@ namespace Umbraco.Web.Cache #region Refresher - public override void Refresh(int id) + public override void Refresh(JsonPayload[] payloads) { + if (payloads.Length == 0) return; + + var clearDictionary = false; + var clearContent = false; + + //clear all no matter what type of payload ClearAllIsolatedCacheByEntityType(); - RefreshDomains(id); - base.Refresh(id); + + foreach (var payload in payloads) + { + RefreshDomains(payload.Id); + + switch (payload.ChangeType) + { + case JsonPayload.LanguageChangeType.Update: + clearDictionary = true; + break; + case JsonPayload.LanguageChangeType.Remove: + clearDictionary = true; + clearContent = true; + break; + case JsonPayload.LanguageChangeType.ChangeCulture: + clearDictionary = true; + clearContent = true; + break; + } + } + + if (clearDictionary) + { + ClearAllIsolatedCacheByEntityType(); + } + + //if this flag is set, we will tell the published snapshot service to refresh ALL content + if (clearContent) + { + var clearContentPayload = new[] { new ContentCacheRefresher.JsonPayload(0, null, TreeChangeTypes.RefreshAll) }; + ContentCacheRefresher.NotifyPublishedSnapshotService(_publishedSnapshotService, AppCaches, clearContentPayload); + } + + // then trigger event + base.Refresh(payloads); } - public override void Remove(int id) - { - ClearAllIsolatedCacheByEntityType(); - //if a language is removed, then all dictionary cache needs to be removed - ClearAllIsolatedCacheByEntityType(); - RefreshDomains(id); - base.Remove(id); - } + // these events should never trigger + // everything should be PAYLOAD/JSON + + public override void RefreshAll() => throw new NotSupportedException(); + + public override void Refresh(int id) => throw new NotSupportedException(); + + public override void Refresh(Guid id) => throw new NotSupportedException(); + + public override void Remove(int id) => throw new NotSupportedException(); #endregion @@ -69,5 +112,46 @@ namespace Umbraco.Web.Cache _publishedSnapshotService.Notify(assignedDomains.Select(x => new DomainCacheRefresher.JsonPayload(x.Id, DomainChangeTypes.Remove)).ToArray()); } } + + #region Json + + public class JsonPayload + { + public JsonPayload(int id, string isoCode, LanguageChangeType changeType) + { + Id = id; + IsoCode = isoCode; + ChangeType = changeType; + } + + public int Id { get; } + public string IsoCode { get; } + public LanguageChangeType ChangeType { get; } + + public enum LanguageChangeType + { + /// + /// A new languages has been added + /// + Add = 0, + + /// + /// A language has been deleted + /// + Remove = 1, + + /// + /// A language has been updated - but it's culture remains the same + /// + Update = 2, + + /// + /// A language has been updated - it's culture has changed + /// + ChangeCulture = 3 + } + } + + #endregion } } diff --git a/src/Umbraco.Web/Search/ExamineComponent.cs b/src/Umbraco.Web/Search/ExamineComponent.cs index f34b1f862b..149b4d1436 100644 --- a/src/Umbraco.Web/Search/ExamineComponent.cs +++ b/src/Umbraco.Web/Search/ExamineComponent.cs @@ -27,6 +27,7 @@ namespace Umbraco.Web.Search private readonly IPublishedContentValueSetBuilder _publishedContentValueSetBuilder; private readonly IValueSetBuilder _mediaValueSetBuilder; private readonly IValueSetBuilder _memberValueSetBuilder; + private readonly BackgroundIndexRebuilder _backgroundIndexRebuilder; private static object _isConfiguredLocker = new object(); private readonly IScopeProvider _scopeProvider; private readonly ServiceContext _services; @@ -47,7 +48,8 @@ namespace Umbraco.Web.Search IContentValueSetBuilder contentValueSetBuilder, IPublishedContentValueSetBuilder publishedContentValueSetBuilder, IValueSetBuilder mediaValueSetBuilder, - IValueSetBuilder memberValueSetBuilder) + IValueSetBuilder memberValueSetBuilder, + BackgroundIndexRebuilder backgroundIndexRebuilder) { _services = services; _scopeProvider = scopeProvider; @@ -56,7 +58,7 @@ namespace Umbraco.Web.Search _publishedContentValueSetBuilder = publishedContentValueSetBuilder; _mediaValueSetBuilder = mediaValueSetBuilder; _memberValueSetBuilder = memberValueSetBuilder; - + _backgroundIndexRebuilder = backgroundIndexRebuilder; _mainDom = mainDom; _logger = profilingLogger; _indexCreator = indexCreator; @@ -111,6 +113,7 @@ namespace Umbraco.Web.Search ContentTypeCacheRefresher.CacheUpdated += ContentTypeCacheRefresherUpdated; MediaCacheRefresher.CacheUpdated += MediaCacheRefresherUpdated; MemberCacheRefresher.CacheUpdated += MemberCacheRefresherUpdated; + LanguageCacheRefresher.CacheUpdated += LanguageCacheRefresherUpdated; } public void Terminate() @@ -320,6 +323,25 @@ namespace Umbraco.Web.Search } } + private void LanguageCacheRefresherUpdated(LanguageCacheRefresher sender, CacheRefresherEventArgs e) + { + if (!(e.MessageObject is LanguageCacheRefresher.JsonPayload[] payloads)) + return; + + if (payloads.Length == 0) return; + + var removedOrCultureChanged = payloads.Any(x => + x.ChangeType == LanguageCacheRefresher.JsonPayload.LanguageChangeType.ChangeCulture + || x.ChangeType == LanguageCacheRefresher.JsonPayload.LanguageChangeType.Remove); + + if (removedOrCultureChanged) + { + //if a lang is removed or it's culture has changed, we need to rebuild the indexes since + //field names and values in the index have a string culture value. + _backgroundIndexRebuilder.RebuildIndexes(false); + } + } + /// /// Updates indexes based on content type changes /// From 37fce725ff649bbd0fb981b999f239006dfc2f84 Mon Sep 17 00:00:00 2001 From: Shannon Date: Mon, 14 Oct 2019 10:04:51 +0200 Subject: [PATCH 22/40] Updates UI to allow updating a culture for a language and warn the user if they are changing it, updates the controller to be able to udpate a culture on a lang --- .../src/views/languages/edit.controller.js | 119 +- .../src/views/languages/overlays/change.html | 7 + src/Umbraco.Web.UI/Umbraco/config/lang/en.xml | 1 + .../Umbraco/config/lang/en_us.xml | 4317 +++++++++-------- .../Cache/DistributedCacheExtensions.cs | 12 +- src/Umbraco.Web/Editors/LanguageController.cs | 35 +- 6 files changed, 2280 insertions(+), 2211 deletions(-) create mode 100644 src/Umbraco.Web.UI.Client/src/views/languages/overlays/change.html diff --git a/src/Umbraco.Web.UI.Client/src/views/languages/edit.controller.js b/src/Umbraco.Web.UI.Client/src/views/languages/edit.controller.js index a11aa8bff8..5f1c46de4c 100644 --- a/src/Umbraco.Web.UI.Client/src/views/languages/edit.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/languages/edit.controller.js @@ -1,7 +1,7 @@ (function () { "use strict"; - function LanguagesEditController($scope, $timeout, $location, $routeParams, navigationService, notificationsService, localizationService, languageResource, contentEditingHelper, formHelper, eventsService) { + function LanguagesEditController($scope, $q, $timeout, $location, $routeParams, overlayService, navigationService, notificationsService, localizationService, languageResource, contentEditingHelper, formHelper, eventsService) { var vm = this; @@ -20,6 +20,8 @@ vm.toggleMandatory = toggleMandatory; vm.toggleDefault = toggleDefault; + var currCulture = null; + function init() { // localize labels @@ -32,7 +34,8 @@ "languages_addLanguage", "languages_noFallbackLanguageOption", "languages_fallbackLanguageDescription", - "languages_fallbackLanguage" + "languages_fallbackLanguage", + "defaultdialogs_confirmSure" ]; localizationService.localizeMany(labelKeys).then(function (values) { @@ -43,6 +46,7 @@ vm.labels.defaultLanguageHelp = values[4]; vm.labels.addLanguage = values[5]; vm.labels.noFallbackLanguageOption = values[6]; + vm.labels.areYouSure = values[9]; $scope.properties = { fallbackLanguage: { @@ -53,46 +57,56 @@ }; if ($routeParams.create) { - vm.page.name = vm.labels.addLanguage; - languageResource.getCultures().then(function (culturesDictionary) { - var cultures = []; - angular.forEach(culturesDictionary, function (value, key) { - cultures.push({ - name: key, - displayName: value - }); - }); - vm.availableCultures = cultures; - }); + vm.page.name = vm.labels.addLanguage; } }); vm.loading = true; - languageResource.getAll().then(function (languages) { + + var promises = []; + + //load all culture/languages + promises.push(languageResource.getCultures().then(function (culturesDictionary) { + var cultures = []; + angular.forEach(culturesDictionary, function (value, key) { + cultures.push({ + name: key, + displayName: value + }); + }); + vm.availableCultures = cultures; + })); + + //load all possible fallback languages + promises.push(languageResource.getAll().then(function (languages) { vm.availableLanguages = languages.filter(function (l) { return $routeParams.id != l.id; }); vm.loading = false; - }); + })); if (!$routeParams.create) { - vm.loading = true; - - languageResource.getById($routeParams.id).then(function(lang) { + promises.push(languageResource.getById($routeParams.id).then(function(lang) { vm.language = lang; vm.page.name = vm.language.name; - /* we need to store the initial default state so we can disabel the toggle if it is the default. + /* we need to store the initial default state so we can disable the toggle if it is the default. we need to prevent from not having a default language. */ vm.initIsDefault = angular.copy(vm.language.isDefault); - vm.loading = false; makeBreadcrumbs(); - }); + + //store to check if we are changing the lang culture + currCulture = vm.language.culture; + })); } + $q.all(promises, function () { + vm.loading = false; + }); + $timeout(function () { navigationService.syncTree({ tree: "languages", path: "-1" }); }); @@ -103,31 +117,54 @@ if (formHelper.submitForm({ scope: $scope })) { vm.page.saveButtonState = "busy"; - languageResource.save(vm.language).then(function (lang) { + //check if the culture is being changed + if (currCulture && vm.language.culture !== currCulture) { - formHelper.resetForm({ scope: $scope }); + const changeCultureAlert = { + title: vm.labels.areYouSure, + view: "views/languages/overlays/change.html", + submitButtonLabelKey: "general_continue", + submit: function (model) { + saveLanguage(); + overlayService.close(); + }, + close: function () { + overlayService.close(); + vm.page.saveButtonState = "init"; + } + }; - vm.language = lang; - vm.page.saveButtonState = "success"; - localizationService.localize("speechBubbles_languageSaved").then(function(value){ - notificationsService.success(value); - }); - - // emit event when language is created or updated/saved - var args = { language: lang, isNew: $routeParams.create ? true : false }; - eventsService.emit("editors.languages.languageSaved", args); - - back(); - - }, function (err) { - vm.page.saveButtonState = "error"; - - formHelper.handleError(err); - - }); + overlayService.open(changeCultureAlert); + } + else { + saveLanguage(); + } } + } + function saveLanguage() { + languageResource.save(vm.language).then(function (lang) { + formHelper.resetForm({ scope: $scope }); + + vm.language = lang; + vm.page.saveButtonState = "success"; + localizationService.localize("speechBubbles_languageSaved").then(function (value) { + notificationsService.success(value); + }); + + // emit event when language is created or updated/saved + var args = { language: lang, isNew: $routeParams.create ? true : false }; + eventsService.emit("editors.languages.languageSaved", args); + + back(); + + }, function (err) { + vm.page.saveButtonState = "error"; + + formHelper.handleError(err); + + }); } function back() { diff --git a/src/Umbraco.Web.UI.Client/src/views/languages/overlays/change.html b/src/Umbraco.Web.UI.Client/src/views/languages/overlays/change.html new file mode 100644 index 0000000000..c5e813fa51 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/views/languages/overlays/change.html @@ -0,0 +1,7 @@ +
+ +
+ Changing the culture for a language may be an expensive operation and will result in the content cache and indexes being rebuilt. +
+ +
diff --git a/src/Umbraco.Web.UI/Umbraco/config/lang/en.xml b/src/Umbraco.Web.UI/Umbraco/config/lang/en.xml index 7f15cab2c2..fefab08c4b 100644 --- a/src/Umbraco.Web.UI/Umbraco/config/lang/en.xml +++ b/src/Umbraco.Web.UI/Umbraco/config/lang/en.xml @@ -414,6 +414,7 @@ Click to add a Macro Insert table This will delete the language + Changing the culture for a language may be an expensive operation and will result in the content cache and indexes being rebuilt Last Edited Link Internal link: 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 08c8829a73..60e711f8e3 100644 --- a/src/Umbraco.Web.UI/Umbraco/config/lang/en_us.xml +++ b/src/Umbraco.Web.UI/Umbraco/config/lang/en_us.xml @@ -1,2157 +1,2168 @@ - - - - The Umbraco community - https://our.umbraco.com/documentation/Extending-Umbraco/Language-Files - - - Culture and Hostnames - Audit Trail - Browse Node - Change Document Type - Copy - Create - Export - Create Package - Create group - Delete - Disable - Empty recycle bin - Enable - Export Document Type - Import Document Type - Import Package - Edit in Canvas - Exit - Move - Notifications - Public access - Publish - Unpublish - Reload - Republish entire site - Rename - Restore - Set permissions for the page %0% - Choose where to copy - Choose where to move - to in the tree structure below - was moved to - was copied to - was deleted - Permissions - Rollback - Send To Publish - Send To Translation - Set group - Sort - Translate - Update - Set permissions - Unlock - Create Content Template - Resend Invitation - - - Content - Administration - Structure - Other - - - Allow access to assign culture and hostnames - Allow access to view a node's history log - Allow access to view a node - Allow access to change document type for a node - Allow access to copy a node - Allow access to create nodes - Allow access to delete nodes - Allow access to move a node - Allow access to set and change public access for a node - Allow access to publish a node - Allow access to unpublish a node - Allow access to change permissions for a node - Allow access to roll back a node to a previous state - Allow access to send a node for approval before publishing - Allow access to send a node for translation - Allow access to change the sort order for nodes - Allow access to translate a node - Allow access to save a node - Allow access to create a Content Template - - - Content - Info - - - Permission denied. - Add new Domain - remove - Invalid node. - One or more domains have an invalid format. - Domain has already been assigned. - Language - Domain - New domain '%0%' has been created - Domain '%0%' is deleted - Domain '%0%' has already been assigned - Domain '%0%' has been updated - Edit Current Domains - - - Inherit - Culture - or inherit culture from parent nodes. Will also apply
- to the current node, unless a domain below applies too.]]>
- Domains - - - Clear selection - Select - Do something else - Bold - Cancel Paragraph Indent - Insert form field - Insert graphic headline - Edit Html - Indent Paragraph - Italic - Center - Justify Left - Justify Right - Insert Link - Insert local link (anchor) - Bullet List - Numeric List - Insert macro - Insert picture - Publish and close - Publish with descendants - Edit relations - Return to list - Save - Save and close - Save and publish - Save and schedule - Send for approval - Save list view - Schedule - Preview - Preview is disabled because there's no template assigned - Choose style - Show styles - Insert table - Generate models and close - Save and generate models - Undo - Redo - Rollback - Delete tag - Cancel - Confirm - More publishing options - - - Viewing for - Content deleted - Content unpublished - Content unpublished for languages: %0% - Content published - Content published for languages: %0% - Content saved - Content saved for languages: %0% - Content moved - Content copied - Content rolled back - Content sent for publishing - Content sent for publishing for languages: %0% - Sort child items performed by user - Copy - Publish - Publish - Move - Save - Save - Delete - Unpublish - Unpublish - Rollback - Send To Publish - Send To Publish - Sort - History (all variants) - - - To change the document type for the selected content, first select from the list of valid types for this location. - Then confirm and/or amend the mapping of properties from the current type to the new, and click Save. - The content has been re-published. - Current Property - Current type - The document type cannot be changed, as there are no alternatives valid for this location. An alternative will be valid if it is allowed under the parent of the selected content item and that all existing child content items are allowed to be created under it. - Document Type Changed - Map Properties - Map to Property - New Template - New Type - none - Content - Select New Document Type - The document type of the selected content has been successfully changed to [new type] and the following properties mapped: - to - Could not complete property mapping as one or more properties have more than one mapping defined. - Only alternate types valid for the current location are displayed. - - - Failed to create a folder under parent with ID %0% - Failed to create a folder under parent with name %0% - The folder name cannot contain illegal characters. - Failed to delete item: %0% - - - Is Published - About this page - Alias - (how would you describe the picture over the phone) - Alternative Links - Click to edit this item - Created by - Original author - Updated by - Created - Date/time this document was created - Document Type - Editing - Remove at - This item has been changed after publication - This item is not published - Last published - There are no items to show - There are no items to show in the list. - No child items have been added - No members have been added - Media Type - Link to media item(s) - Member Group - Role - Member Type - No changes have been made - No date chosen - Page title - This media item has no link - No content can be added for this item - Properties - This document is published but is not visible because the parent '%0%' is unpublished - This culture is published but is not visible because it is unpublished on parent '%0%' - This document is published but is not in the cache - Could not get the url - This document is published but its url would collide with content %0% - This document is published but its url cannot be routed - Publish - Published - Published (pending changes)> - Publication Status - Publish with descendants to publish %0% and all content items underneath and thereby making their content publicly available.]]> - Publish with descendants to publish the selected languages and the same languages of content items underneath and thereby making their content publicly available.]]> - Publish at - Unpublish at - Clear Date - Set date - Sortorder is updated - To sort the nodes, simply drag the nodes or click one of the column headers. You can select multiple nodes by holding the "shift" or "control" key while selecting - Statistics - Title (optional) - Alternative text (optional) - Type - Unpublish - Draft - Not created - Last edited - Date/time this document was edited - Remove file(s) - Link to document - Member of group(s) - Not a member of group(s) - Child items - Target - This translates to the following time on the server: - What does this mean?]]> - Are you sure you want to delete this item? - Property %0% uses editor %1% which is not supported by Nested Content. - No content types are configured for this property. - Add another text box - Remove this text box - Content root - Include drafts: also publish unpublished content items. - This value is hidden. If you need access to view this value please contact your website administrator. - This value is hidden. - What languages would you like to publish? All languages with content are saved! - What languages would you like to publish? - What languages would you like to save? - All languages with content are saved on creation! - What languages would you like to send for approval? - What languages would you like to schedule? - Select the languages to unpublish. Unpublishing a mandatory language will unpublish all languages. - Published Languages - Unpublished Languages - Unmodified Languages - These languages haven't been created - Ready to Publish? - Ready to Save? - Send for approval - Select the date and time to publish and/or unpublish the content item. - Create new - Paste from clipboard - - - Create a new Content Template from '%0%' - Blank - Select a Content Template - Content Template created - A Content Template was created from '%0%' - Another Content Template with the same name already exists - A Content Template is predefined content that an editor can select to use as the basis for creating new content - - - Click to upload - or click here to choose files - You can drag files here to upload. - Cannot upload this file, it does not have an approved file type - Max file size is - Media root - Failed to move media - Parent and destination folders cannot be the same - Failed to copy media - Failed to create a folder under parent id %0% - Failed to rename the folder with id %0% - Drag and drop your file(s) into the area - - - Create a new member - All Members - Member groups have no additional properties for editing. - - - Where do you want to create the new %0% - Create an item under - Select the document type you want to make a content template for - Enter a folder name - Choose a type and a title - Document Types within the Settings section, by editing the Allowed child node types under Permissions.]]> - The selected page in the content tree doesn't allow for any pages to be created below it. - Edit permissions for this document type - Media Types Types within the Settings section, by editing the Allowed child node types under Permissions.]]> - The selected media in the tree doesn't allow for any other media to be created below it. - Edit permissions for this media type Document Type without a template - New folder - New data type - New JavaScript file - New empty partial view - New partial view macro - New partial view from snippet - New partial view macro from snippet - New partial view macro (without macro) - New style sheet file - New Rich Text Editor style sheet file - - - Browse your website - - Hide - If Umbraco isn't opening, you might need to allow popups from this site - has opened in a new window - Restart - Visit - Welcome - - - Stay - Discard changes - You have unsaved changes - Are you sure you want to navigate away from this page? - you have unsaved changes - Publishing will make the selected items visible on the site. - Unpublishing will remove the selected items and all their descendants from the site. - Unpublishing will remove this page and all its descendants from the site. - You have unsaved changes. Making changes to the Document Type will discard the changes. - - - Done - Deleted %0% item - Deleted %0% items - Deleted %0% out of %1% item - Deleted %0% out of %1% items - Published %0% item - Published %0% items - Published %0% out of %1% item - Published %0% out of %1% items - Unpublished %0% item - Unpublished %0% items - Unpublished %0% out of %1% item - Unpublished %0% out of %1% items - Moved %0% item - Moved %0% items - Moved %0% out of %1% item - Moved %0% out of %1% items - Copied %0% item - Copied %0% items - Copied %0% out of %1% item - Copied %0% out of %1% items - - - Link title - Link - Anchor / querystring - Name - Close this window - Are you sure you want to delete - Are you sure you want to disable - Are you sure? - Are you sure? - Cut - Edit Dictionary Item - Edit Language - Insert local link - Insert character - Insert graphic headline - Insert picture - Insert link - Click to add a Macro - Insert table - This will delete the language - Last Edited - Link - Internal link: - When using local links, insert "#" in front of link - Open in new window? - Macro Settings - This macro does not contain any properties you can edit - Paste - Edit permissions for - Set permissions for - Set permissions for %0% for user group %1% - Select the users groups you want to set permissions for - The items in the recycle bin are now being deleted. Please do not close this window while this operation takes place - The recycle bin is now empty - When items are deleted from the recycle bin, they will be gone forever - regexlib.com's webservice is currently experiencing some problems, which we have no control over. We are very sorry for this inconvenience.]]> - Search for a regular expression to add validation to a form field. Example: 'email, 'zip-code' 'url' - Remove Macro - Required Field - Site is reindexed - The website cache has been refreshed. All publish content is now up to date. While all unpublished content is still unpublished - The website cache will be refreshed. All published content will be updated, while unpublished content will stay unpublished. - Number of columns - Number of rows - Click on the image to see full size - Pick item - View Cache Item - Relate to original - Include descendants - The friendliest community - Link to page - Opens the linked document in a new window or tab - Link to media - Select content start node - Select media - Select media type - Select icon - Select item - Select link - Select macro - Select content - Select content type - Select media start node - Select member - Select member group - Select member type - Select node - Select sections - Select users - No icons were found - There are no parameters for this macro - There are no macros available to insert - External login providers - Exception Details - Stacktrace - Inner Exception - Link your - Un-link your - account - Select editor - Select snippet - This will delete the node and all its languages. If you only want to delete one language go and unpublish it instead. - - - There are no dictionary items. - - - %0%' below - ]]> - Culture Name - - Dictionary overview - - - Configured Searchers - Shows properties and tools for any configured Searcher (i.e. such as a multi-index searcher) - Field values - Health status - The health status of the index and if it can be read - Indexers - Index info - Lists the properties of the index - Manage Examine's indexes - Allows you to view the details of each index and provides some tools for managing the indexes - Rebuild index - - Depending on how much content there is in your site this could take a while.
- It is not recommended to rebuild an index during times of high website traffic or when editors are editing content. - ]]> -
- Searchers - Search the index and view the results - Tools - Tools to manage the index - - - Enter your username - Enter your password - Confirm your password - Name the %0%... - Enter a name... - Enter an email... - Enter a username... - Label... - Enter a description... - Type to search... - Type to filter... - Type to add tags (press enter after each tag)... - Enter your email - Enter a message... - Your username is usually your email - #value or ?key=value - Enter alias... - Generating alias... - Create item - Edit - Name - - - Create custom list view - Remove custom list view - A content type, media type or member type with this alias already exists - - - Renamed - Enter a new folder name here - %0% was renamed to %1% - - - Add prevalue - Database datatype - Property editor GUID - Property editor - Buttons - Enable advanced settings for - Enable context menu - Maximum default size of inserted images - Related stylesheets - Show label - Width and height - All property types & property data - using this data type will be deleted permanently, please confirm you want to delete these as well - Yes, delete - and all property types & property data using this data type - Select the folder to move - to in the tree structure below - was moved underneath - - - Your data has been saved, but before you can publish this page there are some errors you need to fix first: - The current membership provider does not support changing password (EnablePasswordRetrieval need to be true) - %0% already exists - There were errors: - There were errors: - The password should be a minimum of %0% characters long and contain at least %1% non-alpha numeric character(s) - %0% must be an integer - The %0% field in the %1% tab is mandatory - %0% is a mandatory field - %0% at %1% is not in a correct format - %0% is not in a correct format - - - Received an error from the server - The specified file type has been disallowed by the administrator - 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? - Startnode deleted, please contact your administrator - Please mark content before changing style - No active styles available - Please place cursor at the left of the two cells you wish to merge - You cannot split a cell that hasn't been merged. - This property is invalid - - - Options - About - Action - Actions - Add - Alias - All - Are you sure? - Back - Back to overview - Border - by - Cancel - Cell margin - Choose - Close - Close Window - Comment - Confirm - Constrain - Constrain proportions - Content - Continue - Copy - Create - Database - Date - Default - Delete - Deleted - Deleting... - Design - Dictionary - Dimensions - Down - Download - Edit - Edited - Elements - Email - Error - Field - Find - First - General - Groups - Group - Height - Help - Hide - History - Icon - Id - Import - Include subfolders in search - Info - Inner margin - Insert - Install - Invalid - Justify - Label - Language - Last - Layout - Links - Loading - Locked - Login - Log off - Logout - Macro - Mandatory - Message - Move - Name - New - Next - No - of - Off - OK - Open - On - or - Order by - Password - Path - One moment please... - Previous - Properties - Rebuild - Email to receive form data - Recycle Bin - Your recycle bin is empty - Reload - Remaining - Remove - Rename - Renew - Required - Retrieve - Retry - Permissions - Scheduled Publishing - Search - Sorry, we can not find what you are looking for. - No items have been added - Server - Settings - Show - Show page on Send - Size - Sort - Status - Submit - Type - Type to search... - under - Up - Update - Upgrade - Upload - Url - User - Username - Value - View - Welcome... - Width - Yes - Folder - Search results - Reorder - I am done reordering - Preview - Change password - to - List view - Saving... - current - Embed - selected - - - Blue - - - Add group - Add property - Add editor - Add template - Add child node - Add child - Edit data type - Navigate sections - Shortcuts - show shortcuts - Toggle list view - Toggle allow as root - Comment/Uncomment lines - Remove line - Copy Lines Up - Copy Lines Down - Move Lines Up - Move Lines Down - General - Editor - Toggle allow culture variants - - - Background color - Bold - Text color - Font - Text - - - Page - - - The installer cannot connect to the database. - Could not save the web.config file. Please modify the connection string manually. - Your database has been found and is identified as - Database configuration - install button to install the Umbraco %0% database - ]]> - Next to proceed.]]> - Database not found! Please check that the information in the "connection string" of the "web.config" file is correct.

-

To proceed, please edit the "web.config" file (using Visual Studio or your favourite text editor), scroll to the bottom, add the connection string for your database in the key named "UmbracoDbDSN" and save the file.

-

- Click the retry button when - done.
- More information on editing web.config here.

]]>
- - Please contact your ISP if necessary. - If you're installing on a local machine or server you might need information from your system administrator.]]> - - Press the upgrade button to upgrade your database to Umbraco %0%

-

- Don't worry - no content will be deleted and everything will continue working afterwards! -

- ]]>
- Press Next to - proceed. ]]> - next to continue the configuration wizard]]> - The Default users' password needs to be changed!]]> - The Default user has been disabled or has no access to Umbraco!

No further actions needs to be taken. Click Next to proceed.]]> - The Default user's password has been successfully changed since the installation!

No further actions needs to be taken. Click Next to proceed.]]> - The password is changed! - Get a great start, watch our introduction videos - By clicking the next button (or modifying the umbracoConfigurationStatus in web.config), you accept the license for this software as specified in the box below. Notice that this Umbraco distribution consists of two different licenses, the open source MIT license for the framework and the Umbraco freeware license that covers the UI. - Not installed yet. - Affected files and folders - More information on setting up permissions for Umbraco here - You need to grant ASP.NET modify permissions to the following files/folders - Your permission settings are almost perfect!

- You can run Umbraco without problems, but you will not be able to install packages which are recommended to take full advantage of Umbraco.]]>
- How to Resolve - Click here to read the text version - video tutorial on setting up folder permissions for Umbraco or read the text version.]]> - Your permission settings might be an issue! -

- You can run Umbraco without problems, but you will not be able to create folders or install packages which are recommended to take full advantage of Umbraco.]]>
- Your permission settings are not ready for Umbraco! -

- In order to run Umbraco, you'll need to update your permission settings.]]>
- Your permission settings are perfect!

- You are ready to run Umbraco and install packages!]]>
- Resolving folder issue - Follow this link for more information on problems with ASP.NET and creating folders - Setting up folder permissions - - I want to start from scratch - learn how) - You can still choose to install Runway later on. Please go to the Developer section and choose Packages. - ]]> - You've just set up a clean Umbraco platform. What do you want to do next? - Runway is installed - - This is our list of recommended modules, check off the ones you would like to install, or view the full list of modules - ]]> - Only recommended for experienced users - I want to start with a simple website - - "Runway" is a simple website providing some basic document types and templates. The installer can set up Runway for you automatically, - but you can easily edit, extend or remove it. It's not necessary and you can perfectly use Umbraco without it. However, - Runway offers an easy foundation based on best practices to get you started faster than ever. - If you choose to install Runway, you can optionally select basic building blocks called Runway Modules to enhance your Runway pages. -

- - Included with Runway: Home page, Getting Started page, Installing Modules page.
- Optional Modules: Top Navigation, Sitemap, Contact, Gallery. -
- ]]>
- What is Runway - Step 1/5 Accept license - Step 2/5: Database configuration - Step 3/5: Validating File Permissions - Step 4/5: Check Umbraco security - Step 5/5: Umbraco is ready to get you started - Thank you for choosing Umbraco - Browse your new site -You installed Runway, so why not see how your new website looks.]]> - Further help and information -Get help from our award winning community, browse the documentation or watch some free videos on how to build a simple site, how to use packages and a quick guide to the Umbraco terminology]]> - Umbraco %0% is installed and ready for use - /web.config file and update the AppSetting key UmbracoConfigurationStatus in the bottom to the value of '%0%'.]]> - started instantly by clicking the "Launch Umbraco" button below.
If you are new to Umbraco, -you can find plenty of resources on our getting started pages.]]>
- Launch Umbraco -To manage your website, simply open the Umbraco back office and start adding content, updating the templates and stylesheets or add new functionality]]> - Connection to database failed. - Umbraco Version 3 - Umbraco Version 4 - Watch - Umbraco %0% for a fresh install or upgrading from version 3.0. -

- Press "next" to start the wizard.]]>
- - - Culture Code - Culture Name - - - You've been idle and logout will automatically occur in - Renew now to save your work - - - Happy super Sunday - Happy manic Monday - Happy tubular Tuesday - Happy wonderful Wednesday - Happy thunderous Thursday - Happy funky Friday - Happy Caturday - Log in below - Sign in with - Session timed out - © 2001 - %0%
Umbraco.com

]]>
- Forgotten password? - An email will be sent to the address specified with a link to reset your password - An email with password reset instructions will be sent to the specified address if it matched our records - Show password - Hide password - Return to login form - Please provide a new password - Your Password has been updated - The link you have clicked on is invalid or has expired - Umbraco: Reset Password - - - - - - - - - - - -
- - - - - -
- -
- -
-
- - - - - - -
-
-
- - - - -
- - - - -
-

- Password reset requested -

-

- Your username to login to the Umbraco back-office is: %0% -

-

- - - - - - -
- - Click this link to reset your password - -
-

-

If you cannot click on the link, copy and paste this URL into your browser window:

- - - - -
- - %1% - -
-

-
-
-


-
-
- - - ]]>
- - - Dashboard - Sections - Content - - - Choose page above... - %0% has been copied to %1% - Select where the document %0% should be copied to below - %0% has been moved to %1% - Select where the document %0% should be moved to below - has been selected as the root of your new content, click 'ok' below. - No node selected yet, please select a node in the list above before clicking 'ok' - The current node is not allowed under the chosen node because of its type - The current node cannot be moved to one of its subpages - The current node cannot exist at the root - The action isn't allowed since you have insufficient permissions on 1 or more child documents. - Relate copied items to original - - - %0%]]> - Notification settings saved for - - The following languages have been modified %0% - - - - - - - - - - - -
- - - - - -
- -
- -
-
- - - - - - -
-
-
- - - - -
- - - - -
-

- Hi %0%, -

-

- This is an automated mail to inform you that the task '%1%' has been performed on the page '%2%' by the user '%3%' -

- - - - - - -
- -
- EDIT
-
-

-

Update summary:

- %6% -

-

- Have a nice day!

- Cheers from the Umbraco robot -

-
-
-


-
-
- - - ]]>
- The following languages have been modified:

- %0% - ]]>
- [%0%] Notification about %1% performed on %2% - Notifications - - - Actions - Created - Create package - - button and locating the package. Umbraco packages usually have a ".umb" or ".zip" extension. - ]]> - This will delete the package - Drop to upload - Include all child nodes - or click here to choose package file - Upload package - Install a local package by selecting it from your machine. Only install packages from sources you know and trust - Upload another package - Cancel and upload another package - I accept - terms of use - Path to file - Absolute path to file (ie: /bin/umbraco.bin) - Installed - Installed packages - Install local - Finish - This package has no configuration view - No packages have been created yet - You don’t have any packages installed - 'Packages' icon in the top right of your screen]]> - Package Actions - Author URL - Package Content - Package Files - Icon URL - Install package - License - License URL - Package Properties - Search for packages - Results for - We couldn’t find anything for - Please try searching for another package or browse through the categories - Popular - New releases - has - karma points - Information - Owner - Contributors - Created - Current version - .NET version - Downloads - Likes - Compatibility - This package is compatible with the following versions of Umbraco, as reported by community members. Full compatability cannot be guaranteed for versions reported below 100% - External sources - Author - Documentation - Package meta data - Package name - Package doesn't contain any items -
- You can safely remove this from the system by clicking "uninstall package" below.]]>
- Package options - Package readme - Package repository - Confirm package uninstall - Package was uninstalled - The package was successfully uninstalled - Uninstall package - - Notice: any documents, media etc depending on the items you remove, will stop working, and could lead to system instability, - so uninstall with caution. If in doubt, contact the package author.]]> - Package version - Upgrading from version - Package already installed - This package cannot be installed, it requires a minimum Umbraco version of - Uninstalling... - Downloading... - Importing... - Installing... - Restarting, please wait... - All done, your browser will now refresh, please wait... - Please click 'Finish' to complete installation and reload the page. - Uploading package... - - - Paste with full formatting (Not recommended) - The text you're trying to paste contains special characters or formatting. This could be caused by copying text from Microsoft Word. Umbraco can remove special characters or formatting automatically, so the pasted content will be more suitable for the web. - Paste as raw text without any formatting at all - Paste, but remove formatting (Recommended) - - - Group based protection - If you want to grant access to all members of specific member groups - You need to create a member group before you can use group based authentication - Error Page - Used when people are logged on, but do not have access - %0%]]> - %0% is now protected]]> - %0%]]> - Login Page - Choose the page that contains the login form - Remove protection... - %0%?]]> - Select the pages that contain login form and error messages - %0%]]> - %0%]]> - Specific members protection - If you wish to grant access to specific members - - - Insufficient user permissions to publish all descendant documents - - - - - - - - Validation failed for required language '%0%'. This language was saved but not published. - Publishing in progress - please wait... - %0% out of %1% pages have been published... - %0% has been published - %0% and subpages have been published - Publish %0% and all its subpages - Publish to publish %0% and thereby making its content publicly available.

- You can publish this page and all its subpages by checking Include unpublished subpages below. - ]]>
- - - You have not configured any approved colors - - - You can only select items of type(s): %0% - You have picked a content item currently deleted or in the recycle bin - You have picked content items currently deleted or in the recycle bin - - - You have picked a media item currently deleted or in the recycle bin - You have picked media items currently deleted or in the recycle bin - Trashed - - - enter external link - choose internal page - Caption - Link - Open in new window - enter the display caption - Enter the link - - - Reset crop - Save crop - Add new crop - Done - Undo edits - - - Select a version to compare with the current version - Current version - Red text will not be shown in the selected version. , green means added]]> - Document has been rolled back - This displays the selected version as HTML, if you wish to see the difference between 2 versions at the same time, use the diff view - Rollback to - Select version - View - - - Edit script file - - - Content - Forms - Media - Members - Packages - Settings - Translation - Users - - - The best Umbraco video tutorials - - - Default template - To import a document type, find the ".udt" file on your computer by clicking the "Browse" button and click "Import" (you'll be asked for confirmation on the next screen) - New Tab Title - Node type - Type - Stylesheet - Script - Tab - Tab Title - Tabs - Master Content Type enabled - This Content Type uses - as a Master Content Type. Tabs from Master Content Types are not shown and can only be edited on the Master Content Type itself - No properties defined on this tab. Click on the "add a new property" link at the top to create a new property. - Create matching template - Add icon - - - Sort order - Creation date - Sorting complete. - Drag the different items up or down below to set how they should be arranged. Or click the column headers to sort the entire collection of items - - This node has no child nodes to sort - - - Validation - Validation errors must be fixed before the item can be saved - Failed - Saved - Insufficient user permissions, could not complete the operation - Cancelled - Operation was cancelled by a 3rd party add-in - Property type already exists - Property type created - DataType: %1%]]> - Propertytype deleted - Document Type saved - Tab created - Tab deleted - Tab with id: %0% deleted - Stylesheet not saved - Stylesheet saved - Stylesheet saved without any errors - Datatype saved - Dictionary item saved - Content published - and is visible on the website - %0% documents published and visible on the website - %0% published and visible on the website - %0% documents published for languages %1% and visible on the website - Content saved - Remember to publish to make changes visible - A schedule for publishing has been updated - %0% saved - Sent For Approval - Changes have been sent for approval - %0% changes have been sent for approval - Media saved - Media saved without any errors - Member saved - Member group saved - Stylesheet Property Saved - Stylesheet saved - Template saved - Error saving user (check log) - User Saved - User type saved - User group saved - File not saved - file could not be saved. Please check file permissions - File saved - File saved without any errors - Language saved - Media Type saved - Member Type saved - Member Group saved - Template not saved - Please make sure that you do not have 2 templates with the same alias - Template saved - Template saved without any errors! - Content unpublished - Content variation %0% unpublished - The mandatory language '%0%' was unpublished. All languages for this content item are now unpublished. - Partial view saved - Partial view saved without any errors! - Partial view not saved - An error occurred saving the file. - Permissions saved for - Deleted %0% user groups - %0% was deleted - Enabled %0% users - Disabled %0% users - %0% is now enabled - %0% is now disabled - User groups have been set - Unlocked %0% users - %0% is now unlocked - Member was exported to file - An error occurred while exporting the member - User %0% was deleted - Invite user - Invitation has been re-sent to %0% - Cannot publish the document since the required '%0%' is not published - Validation failed for language '%0%' - Document type was exported to file - An error occurred while exporting the document type - The release date cannot be in the past - Cannot schedule the document for publishing since the required '%0%' is not published - Cannot schedule the document for publishing since the required '%0%' has a publish date later than a non mandatory language - The expire date cannot be in the past - The expire date cannot be before the release date - - - Add style - Edit style - Rich text editor styles - Define the styles that should be available in the rich text editor for this stylesheet - Edit stylesheet - Edit stylesheet property - The name displayed in the editor style selector - Preview - How the text will look like in the rich text editor. - Selector - Uses CSS syntax, e.g. "h1" or ".redHeader" - Styles - The CSS that should be applied in the rich text editor, e.g. "color:red;" - Code - Rich Text Editor - - - Failed to delete template with ID %0% - Edit template - Sections - Insert content area - Insert content area placeholder - Insert - Choose what to insert into your template - Dictionary item - A dictionary item is a placeholder for a translatable piece of text, which makes it easy to create designs for multilingual websites. - Macro - - A Macro is a configurable component which is great for - reusable parts of your design, where you need the option to provide parameters, - such as galleries, forms and lists. - - Value - Displays the value of a named field from the current page, with options to modify the value or fallback to alternative values. - Partial view - - A partial view is a separate template file which can be rendered inside another - template, it's great for reusing markup or for separating complex templates into separate files. - - Master template - No master - Render child template - @RenderBody() placeholder. - ]]> - Define a named section - @section { ... }. This can be rendered in a - specific area of the parent of this template, by using @RenderSection. - ]]> - Render a named section - @RenderSection(name) placeholder. - This renders an area of a child template which is wrapped in a corresponding @section [name]{ ... } definition. - ]]> - Section Name - Section is mandatory - - If mandatory, the child template must contain a @section definition, otherwise an error is shown. - - Query builder - items returned, in - I want - all content - content of type "%0%" - from - my website - where - and - is - is not - before - before (including selected date) - after - after (including selected date) - equals - does not equal - contains - does not contain - greater than - greater than or equal to - less than - less than or equal to - Id - Name - Created Date - Last Updated Date - order by - ascending - descending - Template - - - Image - Macro - Choose type of content - Choose a layout - Add a row - Add content - Drop content - Settings applied - This content is not allowed here - This content is allowed here - Click to embed - Click to insert image - Image caption... - Write here... - Grid Layouts - Layouts are the overall work area for the grid editor, usually you only need one or two different layouts - Add Grid Layout - Adjust the layout by setting column widths and adding additional sections - Row configurations - Rows are predefined cells arranged horizontally - Add row configuration - Adjust the row by setting cell widths and adding additional cells - Columns - Total combined number of columns in the grid layout - Settings - Configure what settings editors can change - Styles - Configure what styling editors can change - Allow all editors - Allow all row configurations - Maximum items - Leave blank or set to 0 for unlimited - Set as default - Choose extra - Choose default - are added - - - Compositions - Group - You have not added any groups - Add group - Inherited from - Add property - Required label - Enable list view - Configures the content item to show a sortable and searchable list of its children, the children will not be shown in the tree - Allowed Templates - Choose which templates editors are allowed to use on content of this type - Allow as root - Allow editors to create content of this type in the root of the content tree - Allowed child node types - Allow content of the specified types to be created underneath content of this type - Choose child node - Inherit tabs and properties from an existing document type. New tabs will be added to the current document type or merged if a tab with an identical name exists. - This content type is used in a composition, and therefore cannot be composed itself. - There are no content types available to use as a composition. - Create new - Use existing - Editor settings - Configuration - Yes, delete - was moved underneath - was copied underneath - Select the folder to move - Select the folder to copy - to in the tree structure below - All Document types - All Documents - All media items - using this document type will be deleted permanently, please confirm you want to delete these as well. - using this media type will be deleted permanently, please confirm you want to delete these as well. - using this member type will be deleted permanently, please confirm you want to delete these as well - and all documents using this type - and all media items using this type - and all members using this type - Member can edit - Allow this property value to be edited by the member on their profile page - Is sensitive data - Hide this property value from content editors that don't have access to view sensitive information - Show on member profile - Allow this property value to be displayed on the member profile page - tab has no sort order - Where is this composition used? - This composition is currently used in the composition of the following content types: - Allow varying by culture - Allow editors to create content of this type in different languages - Allow varying by culture - Element type - Is an Element type - An Element type is meant to be used for instance in Nested Content, and not in the tree - This is not applicable for an Element type - You have made changes to this property. Are you sure you want to discard them? - - - Add language - Mandatory language - Properties on this language have to be filled out before the node can be published. - Default language - An Umbraco site can only have one default language set. - Switching default language may result in default content missing. - Falls back to - No fall back language - To allow multi-lingual content to fall back to another language if not present in the requested language, select it here. - Fall back language - - - Add parameter - Edit parameter - Enter macro name - Parameters - Define the parameters that should be available when using this macro. - Select partial view macro file - - - Building models - this can take a bit of time, don't worry - Models generated - Models could not be generated - Models generation has failed, see exception in U log - - - Add fallback field - Fallback field - Add default value - Default value - Fallback field - Default value - Casing - Encoding - Choose field - Convert line breaks - Yes, convert line breaks - Replaces line breaks with 'br' html tag - Custom Fields - Date only - Format and encoding - Format as date - Format the value as a date, or a date with time, according to the active culture - HTML encode - Will replace special characters by their HTML equivalent. - Will be inserted after the field value - Will be inserted before the field value - Lowercase - Modify output - None - Output sample - Insert after field - Insert before field - Recursive - Yes, make it recursive - Separator - Standard Fields - Uppercase - URL encode - Will format special characters in URLs - Will only be used when the field values above are empty - This field will only be used if the primary field is empty - Date and time - - - Translation details - Download XML DTD - Fields - Include subpages - - No translator users found. Please create a translator user before you start sending content to translation - The page '%0%' has been send to translation - Send the page '%0%' to translation - Total words - Translate to - Translation completed. - You can preview the pages, you've just translated, by clicking below. If the original page is found, you will get a comparison of the 2 pages. - Translation failed, the XML file might be corrupt - Translation options - Translator - Upload translation XML - - - Content - Content Templates - Media - Cache Browser - Recycle Bin - Created packages - Data Types - Dictionary - Installed packages - Install skin - Install starter kit - Languages - Install local package - Macros - Media Types - Members - Member Groups - Member Roles - Member Types - Document Types - Relation Types - Packages - Packages - Partial Views - Partial View Macro Files - Install from repository - Install Runway - Runway modules - Scripting Files - Scripts - Stylesheets - Templates - Log Viewer - Users - Settings - Templating - Third Party - - - New update ready - %0% is ready, click here for download - No connection to server - Error checking for update. Please review trace-stack for further information - - - Access - Based on the assigned groups and start nodes, the user has access to the following nodes - Assign access - Administrator - Category field - User created - Change Your Password - Change photo - New password - hasn't been locked out - The password hasn't been changed - Confirm new password - You can change your password for accessing the Umbraco Back Office by filling out the form below and click the 'Change Password' button - Content Channel - Create another user - Create new users to give them access to Umbraco. When a new user is created a password will be generated that you can share with the user. - Description field - Disable User - Document Type - Editor - Excerpt field - Failed login attempts - Go to user profile - Add groups to assign access and permissions - Invite another user - Invite new users to give them access to Umbraco. An invite email will be sent to the user with information on how to log in to Umbraco. Invites last for 72 hours. - Language - Set the language you will see in menus and dialogs - Last lockout date - Last login - Password last changed - Username - Media start node - Limit the media library to a specific start node - Media start nodes - Limit the media library to specific start nodes - Sections - Disable Umbraco Access - has not logged in yet - Old password - Password - Reset password - Your password has been changed! - Please confirm the new password - Enter your new password - Your new password cannot be blank! - Current password - Invalid current password - There was a difference between the new password and the confirmed password. Please try again! - The confirmed password doesn't match the new password! - Replace child node permissions - You are currently modifying permissions for the pages: - Select pages to modify their permissions - Remove photo - Default permissions - Granular permissions - Set permissions for specific nodes - Profile - Search all children - Add sections to give users access - Select user groups - No start node selected - No start nodes selected - Content start node - Limit the content tree to a specific start node - Content start nodes - Limit the content tree to specific start nodes - User last updated - has been created - The new user has successfully been created. To log in to Umbraco use the password below. - User management - Name - User permissions - User group - has been invited - An invitation has been sent to the new user with details about how to log in to Umbraco. - Hello there and welcome to Umbraco! In just 1 minute you’ll be good to go, we just need you to setup a password and add a picture for your avatar. - Welcome to Umbraco! Unfortunately your invite has expired. Please contact your administrator and ask them to resend it. - Uploading a photo of yourself will make it easy for other users to recognize you. Click the circle above to upload your photo. - Writer - Change - Your profile - Your recent history - Session expires in - Invite user - Create user - Send invite - Back to users - Umbraco: Invitation - - - - - - - - - - - -
- - - - - -
- -
- -
-
- - - - - - -
-
-
- - - - -
- - - - -
-

- Hi %0%, -

-

- You have been invited by %1% to the Umbraco Back Office. -

-

- Message from %1%: -
- %2% -

- - - - - - -
- - - - - - -
- - Click this link to accept the invite - -
-
-

If you cannot click on the link, copy and paste this URL into your browser window:

- - - - -
- - %3% - -
-

-
-
-


-
-
- - ]]>
- Invite - Resending invitation... - Delete User - Are you sure you wish to delete this user account? - All - Active - Disabled - Locked out - Invited - Inactive - Name (A-Z) - Name (Z-A) - Newest - Oldest - Last login - - - Validation - Validate as an email address - Validate as a number - Validate as a URL - ...or enter a custom validation - Field is mandatory - Enter a regular expression - You need to add at least - You can only have - items - items selected - Invalid date - Not a number - Invalid email - Value cannot be null - Value cannot be empty - Value is invalid, it does not match the correct pattern - Custom validation - - - - Value is set to the recommended value: '%0%'. - Value was set to '%1%' for XPath '%2%' in configuration file '%3%'. - Expected value '%1%' for '%2%' in configuration file '%3%', but found '%0%'. - Found unexpected value '%0%' for '%2%' in configuration file '%3%'. - - Custom errors are set to '%0%'. - Custom errors are currently set to '%0%'. It is recommended to set this to '%1%' before go live. - Custom errors successfully set to '%0%'. - MacroErrors are set to '%0%'. - MacroErrors are set to '%0%' which will prevent some or all pages in your site from loading completely if there are any errors in macros. Rectifying this will set the value to '%1%'. - MacroErrors are now set to '%0%'. - - Try Skip IIS Custom Errors is set to '%0%' and you're using IIS version '%1%'. - Try Skip IIS Custom Errors is currently '%0%'. It is recommended to set this to '%1%' for your IIS version (%2%). - Try Skip IIS Custom Errors successfully set to '%0%'. - - File does not exist: '%0%'. - '%0%' in config file '%1%'.]]> - There was an error, check log for full error: %0%. - Database - The database schema is correct for this version of Umbraco - %0% problems were detected with your database schema (Check the log for details) - Some errors were detected while validating the database schema against the current version of Umbraco. - Your website's certificate is valid. - Certificate validation error: '%0%' - Your website's SSL certificate has expired. - Your website's SSL certificate is expiring in %0% days. - Error pinging the URL %0% - '%1%' - You are currently %0% viewing the site using the HTTPS scheme. - The appSetting 'Umbraco.Core.UseHttps' is set to 'false' in your web.config file. Once you access this site using the HTTPS scheme, that should be set to 'true'. - The appSetting 'Umbraco.Core.UseHttps' is set to '%0%' in your web.config file, your cookies are %1% marked as secure. - Could not update the 'Umbraco.Core.UseHttps' setting in your web.config file. Error: %0% - - Enable HTTPS - Sets umbracoSSL setting to true in the appSettings of the web.config file. - The appSetting 'Umbraco.Core.UseHttps' is now set to 'true' in your web.config file, your cookies will be marked as secure. - Fix - Cannot fix a check with a value comparison type of 'ShouldNotEqual'. - Cannot fix a check with a value comparison type of 'ShouldEqual' with a provided value. - Value to fix check not provided. - Debug compilation mode is disabled. - Debug compilation mode is currently enabled. It is recommended to disable this setting before go live. - Debug compilation mode successfully disabled. - Trace mode is disabled. - Trace mode is currently enabled. It is recommended to disable this setting before go live. - Trace mode successfully disabled. - All folders have the correct permissions set. - - %0%.]]> - %0%. If they aren't being written to no action need be taken.]]> - All files have the correct permissions set. - - %0%.]]> - %0%. If they aren't being written to no action need be taken.]]> - X-Frame-Options used to control whether a site can be IFRAMEd by another was found.]]> - X-Frame-Options used to control whether a site can be IFRAMEd by another was not found.]]> - Set Header in Config - Adds a value to the httpProtocol/customHeaders section of web.config to prevent the site being IFRAMEd by other websites. - A setting to create a header preventing IFRAMEing of the site by other websites has been added to your web.config file. - Could not update web.config file. Error: %0% - X-Content-Type-Options used to protect against MIME sniffing vulnerabilities was found.]]> - X-Content-Type-Options used to protect against MIME sniffing vulnerabilities was not found.]]> - Adds a value to the httpProtocol/customHeaders section of web.config to protect against MIME sniffing vulnerabilities. - A setting to create a header protecting against MIME sniffing vulnerabilities has been added to your web.config file. - Strict-Transport-Security, also known as the HSTS-header, was found.]]> - Strict-Transport-Security was not found.]]> - Adds the header 'Strict-Transport-Security' with the value 'max-age=10886400' to the httpProtocol/customHeaders section of web.config. Use this fix only if you will have your domains running with https for the next 18 weeks (minimum). - The HSTS header has been added to your web.config file. - X-XSS-Protection was found.]]> - X-XSS-Protection was not found.]]> - Adds the header 'X-XSS-Protection' with the value '1; mode=block' to the httpProtocol/customHeaders section of web.config. - The X-XSS-Protection header has been added to your web.config file. - - %0%.]]> - No headers revealing information about the website technology were found. - In the Web.config file, system.net/mailsettings could not be found. - In the Web.config file system.net/mailsettings section, the host is not configured. - SMTP settings are configured correctly and the service is operating as expected. - The SMTP server configured with host '%0%' and port '%1%' could not be reached. Please check to ensure the SMTP settings in the Web.config file system.net/mailsettings are correct. - %0%.]]> - %0%.]]> -

Results of the scheduled Umbraco Health Checks run on %0% at %1% are as follows:

%2%]]>
- Umbraco Health Check Status: %0% - - - Disable URL tracker - Enable URL tracker - Culture - Original URL - Redirected To - Redirect Url Management - The following URLs redirect to this content item: - No redirects have been made - When a published page gets renamed or moved a redirect will automatically be made to the new page. - Are you sure you want to remove the redirect from '%0%' to '%1%'? - Redirect URL removed. - Error removing redirect URL. - This will remove the redirect - Are you sure you want to disable the URL tracker? - URL tracker has now been disabled. - Error disabling the URL tracker, more information can be found in your log file. - URL tracker has now been enabled. - Error enabling the URL tracker, more information can be found in your log file. - - - No Dictionary items to choose from - - - %0% characters left.]]> - %1% too many.]]> - - - Trashed content with Id: {0} related to original parent content with Id: {1} - Trashed media with Id: {0} related to original parent media item with Id: {1} - Cannot automatically restore this item - There is no location where this item can be automatically restored. You can move the item manually using the tree below. - was restored under - - - Direction - Parent to child - Bidirectional - Parent - Child - Count - Relations - Created - Comment - Name - No relations for this relation type. - Relation Type - Relations - - - Getting Started - Redirect URL Management - Content - Welcome - Examine Management - Published Status - Models Builder - Health Check + + + + The Umbraco community + https://our.umbraco.com/documentation/Extending-Umbraco/Language-Files + + + Culture and Hostnames + Audit Trail + Browse Node + Change Document Type + Copy + Create + Export + Create Package + Create group + Delete + Disable + Empty recycle bin + Enable + Export Document Type + Import Document Type + Import Package + Edit in Canvas + Exit + Move + Notifications + Public access + Publish + Unpublish + Reload + Republish entire site + Rename + Restore + Set permissions for the page %0% + Choose where to copy + Choose where to move + to in the tree structure below + was moved to + was copied to + was deleted + Permissions + Rollback + Send To Publish + Send To Translation + Set group + Sort + Translate + Update + Set permissions + Unlock + Create Content Template + Resend Invitation + + + Content + Administration + Structure + Other + + + Allow access to assign culture and hostnames + Allow access to view a node's history log + Allow access to view a node + Allow access to change document type for a node + Allow access to copy a node + Allow access to create nodes + Allow access to delete nodes + Allow access to move a node + Allow access to set and change public access for a node + Allow access to publish a node + Allow access to unpublish a node + Allow access to change permissions for a node + Allow access to roll back a node to a previous state + Allow access to send a node for approval before publishing + Allow access to send a node for translation + Allow access to change the sort order for nodes + Allow access to translate a node + Allow access to save a node + Allow access to create a Content Template + + + Content + Info + + + Permission denied. + Add new Domain + remove + Invalid node. + One or more domains have an invalid format. + Domain has already been assigned. + Language + Domain + New domain '%0%' has been created + Domain '%0%' is deleted + Domain '%0%' has already been assigned + Domain '%0%' has been updated + Edit Current Domains + + + Inherit + Culture + or inherit culture from parent nodes. Will also apply
+ to the current node, unless a domain below applies too.]]>
+ Domains + + + Clear selection + Select + Do something else + Bold + Cancel Paragraph Indent + Insert form field + Insert graphic headline + Edit Html + Indent Paragraph + Italic + Center + Justify Left + Justify Right + Insert Link + Insert local link (anchor) + Bullet List + Numeric List + Insert macro + Insert picture + Publish and close + Publish with descendants + Edit relations + Return to list + Save + Save and close + Save and publish + Save and schedule + Send for approval + Save list view + Schedule + Preview + Preview is disabled because there's no template assigned + Choose style + Show styles + Insert table + Generate models and close + Save and generate models + Undo + Redo + Rollback + Delete tag + Cancel + Confirm + More publishing options + + + Viewing for + Content deleted + Content unpublished + Content unpublished for languages: %0% + Content published + Content published for languages: %0% + Content saved + Content saved for languages: %0% + Content moved + Content copied + Content rolled back + Content sent for publishing + Content sent for publishing for languages: %0% + Sort child items performed by user + Copy + Publish + Publish + Move + Save + Save + Delete + Unpublish + Unpublish + Rollback + Send To Publish + Send To Publish + Sort + History (all variants) + + + To change the document type for the selected content, first select from the list of valid types for this location. + Then confirm and/or amend the mapping of properties from the current type to the new, and click Save. + The content has been re-published. + Current Property + Current type + The document type cannot be changed, as there are no alternatives valid for this location. An alternative will be valid if it is allowed under the parent of the selected content item and that all existing child content items are allowed to be created under it. + Document Type Changed + Map Properties + Map to Property + New Template + New Type + none + Content + Select New Document Type + The document type of the selected content has been successfully changed to [new type] and the following properties mapped: + to + Could not complete property mapping as one or more properties have more than one mapping defined. + Only alternate types valid for the current location are displayed. + + + Failed to create a folder under parent with ID %0% + Failed to create a folder under parent with name %0% + The folder name cannot contain illegal characters. + Failed to delete item: %0% + + + Is Published + About this page + Alias + (how would you describe the picture over the phone) + Alternative Links + Click to edit this item + Created by + Original author + Updated by + Created + Date/time this document was created + Document Type + Editing + Remove at + This item has been changed after publication + This item is not published + Last published + There are no items to show + There are no items to show in the list. + No child items have been added + No members have been added + Media Type + Link to media item(s) + Member Group + Role + Member Type + No changes have been made + No date chosen + Page title + This media item has no link + No content can be added for this item + Properties + This document is published but is not visible because the parent '%0%' is unpublished + This culture is published but is not visible because it is unpublished on parent '%0%' + This document is published but is not in the cache + Could not get the url + This document is published but its url would collide with content %0% + This document is published but its url cannot be routed + Publish + Published + Published (pending changes)> + Publication Status + Publish with descendants to publish %0% and all content items underneath and thereby making their content publicly available.]]> + Publish with descendants to publish the selected languages and the same languages of content items underneath and thereby making their content publicly available.]]> + Publish at + Unpublish at + Clear Date + Set date + Sortorder is updated + To sort the nodes, simply drag the nodes or click one of the column headers. You can select multiple nodes by holding the "shift" or "control" key while selecting + Statistics + Title (optional) + Alternative text (optional) + Type + Unpublish + Draft + Not created + Last edited + Date/time this document was edited + Remove file(s) + Link to document + Member of group(s) + Not a member of group(s) + Child items + Target + This translates to the following time on the server: + What does this mean?]]> + Are you sure you want to delete this item? + Property %0% uses editor %1% which is not supported by Nested Content. + No content types are configured for this property. + Add another text box + Remove this text box + Content root + Include drafts: also publish unpublished content items. + This value is hidden. If you need access to view this value please contact your website administrator. + This value is hidden. + What languages would you like to publish? All languages with content are saved! + What languages would you like to publish? + What languages would you like to save? + All languages with content are saved on creation! + What languages would you like to send for approval? + What languages would you like to schedule? + Select the languages to unpublish. Unpublishing a mandatory language will unpublish all languages. + Published Languages + Unpublished Languages + Unmodified Languages + These languages haven't been created + Ready to Publish? + Ready to Save? + Send for approval + Select the date and time to publish and/or unpublish the content item. + Create new + Paste from clipboard + + + Create a new Content Template from '%0%' + Blank + Select a Content Template + Content Template created + A Content Template was created from '%0%' + Another Content Template with the same name already exists + A Content Template is predefined content that an editor can select to use as the basis for creating new content + + + Click to upload + or click here to choose files + You can drag files here to upload. + Cannot upload this file, it does not have an approved file type + Max file size is + Media root + Failed to move media + Parent and destination folders cannot be the same + Failed to copy media + Failed to create a folder under parent id %0% + Failed to rename the folder with id %0% + Drag and drop your file(s) into the area + + + Create a new member + All Members + Member groups have no additional properties for editing. + + + Where do you want to create the new %0% + Create an item under + Select the document type you want to make a content template for + Enter a folder name + Choose a type and a title + Document Types within the Settings section, by editing the Allowed child node types under Permissions.]]> + The selected page in the content tree doesn't allow for any pages to be created below it. + Edit permissions for this document type + Media Types Types within the Settings section, by editing the Allowed child node types under Permissions.]]> + The selected media in the tree doesn't allow for any other media to be created below it. + Edit permissions for this media type Document Type without a template + New folder + New data type + New JavaScript file + New empty partial view + New partial view macro + New partial view from snippet + New partial view macro from snippet + New partial view macro (without macro) + New style sheet file + New Rich Text Editor style sheet file + + + Browse your website + - Hide + If Umbraco isn't opening, you might need to allow popups from this site + has opened in a new window + Restart + Visit + Welcome + + + Stay + Discard changes + You have unsaved changes + Are you sure you want to navigate away from this page? - you have unsaved changes + Publishing will make the selected items visible on the site. + Unpublishing will remove the selected items and all their descendants from the site. + Unpublishing will remove this page and all its descendants from the site. + You have unsaved changes. Making changes to the Document Type will discard the changes. + + + Done + Deleted %0% item + Deleted %0% items + Deleted %0% out of %1% item + Deleted %0% out of %1% items + Published %0% item + Published %0% items + Published %0% out of %1% item + Published %0% out of %1% items + Unpublished %0% item + Unpublished %0% items + Unpublished %0% out of %1% item + Unpublished %0% out of %1% items + Moved %0% item + Moved %0% items + Moved %0% out of %1% item + Moved %0% out of %1% items + Copied %0% item + Copied %0% items + Copied %0% out of %1% item + Copied %0% out of %1% items + + + Link title + Link + Anchor / querystring + Name + Close this window + Are you sure you want to delete + Are you sure you want to disable + Are you sure? + Are you sure? + Cut + Edit Dictionary Item + Edit Language + Insert local link + Insert character + Insert graphic headline + Insert picture + Insert link + Click to add a Macro + Insert table + This will delete the language + Changing the culture for a language may be an expensive operation and will result in the content cache and indexes being rebuilt + Last Edited + Link + Internal link: + When using local links, insert "#" in front of link + Open in new window? + Macro Settings + This macro does not contain any properties you can edit + Paste + Edit permissions for + Set permissions for + Set permissions for %0% for user group %1% + Select the users groups you want to set permissions for + The items in the recycle bin are now being deleted. Please do not close this window while this operation takes place + The recycle bin is now empty + When items are deleted from the recycle bin, they will be gone forever + regexlib.com's webservice is currently experiencing some problems, which we have no control over. We are very sorry for this inconvenience.]]> + Search for a regular expression to add validation to a form field. Example: 'email, 'zip-code' 'url' + Remove Macro + Required Field + Site is reindexed + The website cache has been refreshed. All publish content is now up to date. While all unpublished content is still unpublished + The website cache will be refreshed. All published content will be updated, while unpublished content will stay unpublished. + Number of columns + Number of rows + Click on the image to see full size + Pick item + View Cache Item + Relate to original + Include descendants + The friendliest community + Link to page + Opens the linked document in a new window or tab + Link to media + Select content start node + Select media + Select media type + Select icon + Select item + Select link + Select macro + Select content + Select content type + Select media start node + Select member + Select member group + Select member type + Select node + Select sections + Select users + No icons were found + There are no parameters for this macro + There are no macros available to insert + External login providers + Exception Details + Stacktrace + Inner Exception + Link your + Un-link your + account + Select editor + Select snippet + This will delete the node and all its languages. If you only want to delete one language go and unpublish it instead. + + + There are no dictionary items. + + + %0%' below + ]]> + Culture Name + + Dictionary overview + + + Configured Searchers + Shows properties and tools for any configured Searcher (i.e. such as a multi-index searcher) + Field values + Health status + The health status of the index and if it can be read + Indexers + Index info + Lists the properties of the index + Manage Examine's indexes + Allows you to view the details of each index and provides some tools for managing the indexes + Rebuild index + + Depending on how much content there is in your site this could take a while.
+ It is not recommended to rebuild an index during times of high website traffic or when editors are editing content. + ]]> +
+ Searchers + Search the index and view the results + Tools + Tools to manage the index + + + Enter your username + Enter your password + Confirm your password + Name the %0%... + Enter a name... + Enter an email... + Enter a username... + Label... + Enter a description... + Type to search... + Type to filter... + Type to add tags (press enter after each tag)... + Enter your email + Enter a message... + Your username is usually your email + #value or ?key=value + Enter alias... + Generating alias... + Create item + Edit + Name + + + Create custom list view + Remove custom list view + A content type, media type or member type with this alias already exists + + + Renamed + Enter a new folder name here + %0% was renamed to %1% + + + Add prevalue + Database datatype + Property editor GUID + Property editor + Buttons + Enable advanced settings for + Enable context menu + Maximum default size of inserted images + Related stylesheets + Show label + Width and height + All property types & property data + using this data type will be deleted permanently, please confirm you want to delete these as well + Yes, delete + and all property types & property data using this data type + Select the folder to move + to in the tree structure below + was moved underneath + + + Your data has been saved, but before you can publish this page there are some errors you need to fix first: + The current membership provider does not support changing password (EnablePasswordRetrieval need to be true) + %0% already exists + There were errors: + There were errors: + The password should be a minimum of %0% characters long and contain at least %1% non-alpha numeric character(s) + %0% must be an integer + The %0% field in the %1% tab is mandatory + %0% is a mandatory field + %0% at %1% is not in a correct format + %0% is not in a correct format + + + Received an error from the server + The specified file type has been disallowed by the administrator + 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? + Startnode deleted, please contact your administrator + Please mark content before changing style + No active styles available + Please place cursor at the left of the two cells you wish to merge + You cannot split a cell that hasn't been merged. + This property is invalid + + + Options + About + Action + Actions + Add + Alias + All + Are you sure? + Back + Back to overview + Border + by + Cancel + Cell margin + Choose + Close + Close Window + Comment + Confirm + Constrain + Constrain proportions + Content + Continue + Copy + Create + Database + Date + Default + Delete + Deleted + Deleting... + Design + Dictionary + Dimensions + Down + Download + Edit + Edited + Elements + Email + Error + Field + Find + First + General + Groups + Group + Height + Help + Hide + History + Icon + Id + Import + Include subfolders in search + Info + Inner margin + Insert + Install + Invalid + Justify + Label + Language + Last + Layout + Links + Loading + Locked + Login + Log off + Logout + Macro + Mandatory + Message + Move + Name + New + Next + No + of + Off + OK + Open + On + or + Order by + Password + Path + One moment please... + Previous + Properties + Rebuild + Email to receive form data + Recycle Bin + Your recycle bin is empty + Reload + Remaining + Remove + Rename + Renew + Required + Retrieve + Retry + Permissions + Scheduled Publishing + Search + Sorry, we can not find what you are looking for. + No items have been added + Server + Settings + Show + Show page on Send + Size + Sort + Status + Submit + Type + Type to search... + under + Up + Update + Upgrade + Upload + Url + User + Username + Value + View + Welcome... + Width + Yes + Folder + Search results + Reorder + I am done reordering + Preview + Change password + to + List view + Saving... + current + Embed + selected + + + Blue + + + Add group + Add property + Add editor + Add template + Add child node + Add child + Edit data type + Navigate sections + Shortcuts + show shortcuts + Toggle list view + Toggle allow as root + Comment/Uncomment lines + Remove line + Copy Lines Up + Copy Lines Down + Move Lines Up + Move Lines Down + General + Editor + Toggle allow culture variants + + + Background color + Bold + Text color + Font + Text + + + Page + + + The installer cannot connect to the database. + Could not save the web.config file. Please modify the connection string manually. + Your database has been found and is identified as + Database configuration + install button to install the Umbraco %0% database + ]]> + Next to proceed.]]> + Database not found! Please check that the information in the "connection string" of the "web.config" file is correct.

+

To proceed, please edit the "web.config" file (using Visual Studio or your favourite text editor), scroll to the bottom, add the connection string for your database in the key named "UmbracoDbDSN" and save the file.

+

+ Click the retry button when + done.
+ More information on editing web.config here.

]]>
+ + Please contact your ISP if necessary. + If you're installing on a local machine or server you might need information from your system administrator.]]> + + Press the upgrade button to upgrade your database to Umbraco %0%

+

+ Don't worry - no content will be deleted and everything will continue working afterwards! +

+ ]]>
+ Press Next to + proceed. ]]> + next to continue the configuration wizard]]> + The Default users' password needs to be changed!]]> + The Default user has been disabled or has no access to Umbraco!

No further actions needs to be taken. Click Next to proceed.]]> + The Default user's password has been successfully changed since the installation!

No further actions needs to be taken. Click Next to proceed.]]> + The password is changed! + Get a great start, watch our introduction videos + By clicking the next button (or modifying the umbracoConfigurationStatus in web.config), you accept the license for this software as specified in the box below. Notice that this Umbraco distribution consists of two different licenses, the open source MIT license for the framework and the Umbraco freeware license that covers the UI. + Not installed yet. + Affected files and folders + More information on setting up permissions for Umbraco here + You need to grant ASP.NET modify permissions to the following files/folders + Your permission settings are almost perfect!

+ You can run Umbraco without problems, but you will not be able to install packages which are recommended to take full advantage of Umbraco.]]>
+ How to Resolve + Click here to read the text version + video tutorial on setting up folder permissions for Umbraco or read the text version.]]> + Your permission settings might be an issue! +

+ You can run Umbraco without problems, but you will not be able to create folders or install packages which are recommended to take full advantage of Umbraco.]]>
+ Your permission settings are not ready for Umbraco! +

+ In order to run Umbraco, you'll need to update your permission settings.]]>
+ Your permission settings are perfect!

+ You are ready to run Umbraco and install packages!]]>
+ Resolving folder issue + Follow this link for more information on problems with ASP.NET and creating folders + Setting up folder permissions + + I want to start from scratch + learn how) + You can still choose to install Runway later on. Please go to the Developer section and choose Packages. + ]]> + You've just set up a clean Umbraco platform. What do you want to do next? + Runway is installed + + This is our list of recommended modules, check off the ones you would like to install, or view the full list of modules + ]]> + Only recommended for experienced users + I want to start with a simple website + + "Runway" is a simple website providing some basic document types and templates. The installer can set up Runway for you automatically, + but you can easily edit, extend or remove it. It's not necessary and you can perfectly use Umbraco without it. However, + Runway offers an easy foundation based on best practices to get you started faster than ever. + If you choose to install Runway, you can optionally select basic building blocks called Runway Modules to enhance your Runway pages. +

+ + Included with Runway: Home page, Getting Started page, Installing Modules page.
+ Optional Modules: Top Navigation, Sitemap, Contact, Gallery. +
+ ]]>
+ What is Runway + Step 1/5 Accept license + Step 2/5: Database configuration + Step 3/5: Validating File Permissions + Step 4/5: Check Umbraco security + Step 5/5: Umbraco is ready to get you started + Thank you for choosing Umbraco + Browse your new site +You installed Runway, so why not see how your new website looks.]]> + Further help and information +Get help from our award winning community, browse the documentation or watch some free videos on how to build a simple site, how to use packages and a quick guide to the Umbraco terminology]]> + Umbraco %0% is installed and ready for use + /web.config file and update the AppSetting key UmbracoConfigurationStatus in the bottom to the value of '%0%'.]]> + started instantly by clicking the "Launch Umbraco" button below.
If you are new to Umbraco, +you can find plenty of resources on our getting started pages.]]>
+ Launch Umbraco +To manage your website, simply open the Umbraco back office and start adding content, updating the templates and stylesheets or add new functionality]]> + Connection to database failed. + Umbraco Version 3 + Umbraco Version 4 + Watch + Umbraco %0% for a fresh install or upgrading from version 3.0. +

+ Press "next" to start the wizard.]]>
+ + + Culture Code + Culture Name + + + You've been idle and logout will automatically occur in + Renew now to save your work + + + Happy super Sunday + Happy manic Monday + Happy tubular Tuesday + Happy wonderful Wednesday + Happy thunderous Thursday + Happy funky Friday + Happy Caturday + Log in below + Sign in with + Session timed out + © 2001 - %0%
Umbraco.com

]]>
+ Forgotten password? + An email will be sent to the address specified with a link to reset your password + An email with password reset instructions will be sent to the specified address if it matched our records + Show password + Hide password + Return to login form + Please provide a new password + Your Password has been updated + The link you have clicked on is invalid or has expired + Umbraco: Reset Password + + + + + + + + + + + +
+ + + + + +
+ +
+ +
+
+ + + + + + +
+
+
+ + + + +
+ + + + +
+

+ Password reset requested +

+

+ Your username to login to the Umbraco back-office is: %0% +

+

+ + + + + + +
+ + Click this link to reset your password + +
+

+

If you cannot click on the link, copy and paste this URL into your browser window:

+ + + + +
+ + %1% + +
+

+
+
+


+
+
+ + + ]]>
+ + + Dashboard + Sections + Content + + + Choose page above... + %0% has been copied to %1% + Select where the document %0% should be copied to below + %0% has been moved to %1% + Select where the document %0% should be moved to below + has been selected as the root of your new content, click 'ok' below. + No node selected yet, please select a node in the list above before clicking 'ok' + The current node is not allowed under the chosen node because of its type + The current node cannot be moved to one of its subpages + The current node cannot exist at the root + The action isn't allowed since you have insufficient permissions on 1 or more child documents. + Relate copied items to original + + + %0%]]> + Notification settings saved for + + The following languages have been modified %0% + + + + + + + + + + + +
+ + + + + +
+ +
+ +
+
+ + + + + + +
+
+
+ + + + +
+ + + + +
+

+ Hi %0%, +

+

+ This is an automated mail to inform you that the task '%1%' has been performed on the page '%2%' by the user '%3%' +

+ + + + + + +
+ +
+ EDIT
+
+

+

Update summary:

+ %6% +

+

+ Have a nice day!

+ Cheers from the Umbraco robot +

+
+
+


+
+
+ + + ]]>
+ The following languages have been modified:

+ %0% + ]]>
+ [%0%] Notification about %1% performed on %2% + Notifications + + + Actions + Created + Create package + + button and locating the package. Umbraco packages usually have a ".umb" or ".zip" extension. + ]]> + This will delete the package + Drop to upload + Include all child nodes + or click here to choose package file + Upload package + Install a local package by selecting it from your machine. Only install packages from sources you know and trust + Upload another package + Cancel and upload another package + I accept + terms of use + Path to file + Absolute path to file (ie: /bin/umbraco.bin) + Installed + Installed packages + Install local + Finish + This package has no configuration view + No packages have been created yet + You don’t have any packages installed + 'Packages' icon in the top right of your screen]]> + Package Actions + Author URL + Package Content + Package Files + Icon URL + Install package + License + License URL + Package Properties + Search for packages + Results for + We couldn’t find anything for + Please try searching for another package or browse through the categories + Popular + New releases + has + karma points + Information + Owner + Contributors + Created + Current version + .NET version + Downloads + Likes + Compatibility + This package is compatible with the following versions of Umbraco, as reported by community members. Full compatability cannot be guaranteed for versions reported below 100% + External sources + Author + Documentation + Package meta data + Package name + Package doesn't contain any items +
+ You can safely remove this from the system by clicking "uninstall package" below.]]>
+ Package options + Package readme + Package repository + Confirm package uninstall + Package was uninstalled + The package was successfully uninstalled + Uninstall package + + Notice: any documents, media etc depending on the items you remove, will stop working, and could lead to system instability, + so uninstall with caution. If in doubt, contact the package author.]]> + Package version + Upgrading from version + Package already installed + This package cannot be installed, it requires a minimum Umbraco version of + Uninstalling... + Downloading... + Importing... + Installing... + Restarting, please wait... + All done, your browser will now refresh, please wait... + Please click 'Finish' to complete installation and reload the page. + Uploading package... + + + Paste with full formatting (Not recommended) + The text you're trying to paste contains special characters or formatting. This could be caused by copying text from Microsoft Word. Umbraco can remove special characters or formatting automatically, so the pasted content will be more suitable for the web. + Paste as raw text without any formatting at all + Paste, but remove formatting (Recommended) + + + Group based protection + If you want to grant access to all members of specific member groups + You need to create a member group before you can use group based authentication + Error Page + Used when people are logged on, but do not have access + %0%]]> + %0% is now protected]]> + %0%]]> + Login Page + Choose the page that contains the login form + Remove protection... + %0%?]]> + Select the pages that contain login form and error messages + %0%]]> + %0%]]> + Specific members protection + If you wish to grant access to specific members + + + Insufficient user permissions to publish all descendant documents + + + + + + + + Validation failed for required language '%0%'. This language was saved but not published. + Publishing in progress - please wait... + %0% out of %1% pages have been published... + %0% has been published + %0% and subpages have been published + Publish %0% and all its subpages + Publish to publish %0% and thereby making its content publicly available.

+ You can publish this page and all its subpages by checking Include unpublished subpages below. + ]]>
+ + + You have not configured any approved colors + + + You can only select items of type(s): %0% + You have picked a content item currently deleted or in the recycle bin + You have picked content items currently deleted or in the recycle bin + + + Deleted item + You have picked a media item currently deleted or in the recycle bin + You have picked media items currently deleted or in the recycle bin + Trashed + + + enter external link + choose internal page + Caption + Link + Open in new window + enter the display caption + Enter the link + + + Reset crop + Save crop + Add new crop + Done + Undo edits + + + Select a version to compare with the current version + Current version + Red text will not be shown in the selected version. , green means added]]> + Document has been rolled back + This displays the selected version as HTML, if you wish to see the difference between 2 versions at the same time, use the diff view + Rollback to + Select version + View + + + Edit script file + + + Content + Forms + Media + Members + Packages + Settings + Translation + Users + + + The best Umbraco video tutorials + + + Default template + To import a document type, find the ".udt" file on your computer by clicking the "Browse" button and click "Import" (you'll be asked for confirmation on the next screen) + New Tab Title + Node type + Type + Stylesheet + Script + Tab + Tab Title + Tabs + Master Content Type enabled + This Content Type uses + as a Master Content Type. Tabs from Master Content Types are not shown and can only be edited on the Master Content Type itself + No properties defined on this tab. Click on the "add a new property" link at the top to create a new property. + Create matching template + Add icon + + + Sort order + Creation date + Sorting complete. + Drag the different items up or down below to set how they should be arranged. Or click the column headers to sort the entire collection of items + + This node has no child nodes to sort + + + Validation + Validation errors must be fixed before the item can be saved + Failed + Saved + Insufficient user permissions, could not complete the operation + Cancelled + Operation was cancelled by a 3rd party add-in + Property type already exists + Property type created + DataType: %1%]]> + Propertytype deleted + Document Type saved + Tab created + Tab deleted + Tab with id: %0% deleted + Stylesheet not saved + Stylesheet saved + Stylesheet saved without any errors + Datatype saved + Dictionary item saved + Content published + and is visible on the website + %0% documents published and visible on the website + %0% published and visible on the website + %0% documents published for languages %1% and visible on the website + Content saved + Remember to publish to make changes visible + A schedule for publishing has been updated + %0% saved + Sent For Approval + Changes have been sent for approval + %0% changes have been sent for approval + Media saved + Media saved without any errors + Member saved + Member group saved + Stylesheet Property Saved + Stylesheet saved + Template saved + Error saving user (check log) + User Saved + User type saved + User group saved + File not saved + file could not be saved. Please check file permissions + File saved + File saved without any errors + Language saved + Media Type saved + Member Type saved + Member Group saved + Template not saved + Please make sure that you do not have 2 templates with the same alias + Template saved + Template saved without any errors! + Content unpublished + Content variation %0% unpublished + The mandatory language '%0%' was unpublished. All languages for this content item are now unpublished. + Partial view saved + Partial view saved without any errors! + Partial view not saved + An error occurred saving the file. + Permissions saved for + Deleted %0% user groups + %0% was deleted + Enabled %0% users + Disabled %0% users + %0% is now enabled + %0% is now disabled + User groups have been set + Unlocked %0% users + %0% is now unlocked + Member was exported to file + An error occurred while exporting the member + User %0% was deleted + Invite user + Invitation has been re-sent to %0% + Cannot publish the document since the required '%0%' is not published + Validation failed for language '%0%' + Document type was exported to file + An error occurred while exporting the document type + The release date cannot be in the past + Cannot schedule the document for publishing since the required '%0%' is not published + Cannot schedule the document for publishing since the required '%0%' has a publish date later than a non mandatory language + The expire date cannot be in the past + The expire date cannot be before the release date + + + Add style + Edit style + Rich text editor styles + Define the styles that should be available in the rich text editor for this stylesheet + Edit stylesheet + Edit stylesheet property + The name displayed in the editor style selector + Preview + How the text will look like in the rich text editor. + Selector + Uses CSS syntax, e.g. "h1" or ".redHeader" + Styles + The CSS that should be applied in the rich text editor, e.g. "color:red;" + Code + Rich Text Editor + + + Failed to delete template with ID %0% + Edit template + Sections + Insert content area + Insert content area placeholder + Insert + Choose what to insert into your template + Dictionary item + A dictionary item is a placeholder for a translatable piece of text, which makes it easy to create designs for multilingual websites. + Macro + + A Macro is a configurable component which is great for + reusable parts of your design, where you need the option to provide parameters, + such as galleries, forms and lists. + + Value + Displays the value of a named field from the current page, with options to modify the value or fallback to alternative values. + Partial view + + A partial view is a separate template file which can be rendered inside another + template, it's great for reusing markup or for separating complex templates into separate files. + + Master template + No master + Render child template + @RenderBody() placeholder. + ]]> + Define a named section + @section { ... }. This can be rendered in a + specific area of the parent of this template, by using @RenderSection. + ]]> + Render a named section + @RenderSection(name) placeholder. + This renders an area of a child template which is wrapped in a corresponding @section [name]{ ... } definition. + ]]> + Section Name + Section is mandatory + + If mandatory, the child template must contain a @section definition, otherwise an error is shown. + + Query builder + items returned, in + I want + all content + content of type "%0%" + from + my website + where + and + is + is not + before + before (including selected date) + after + after (including selected date) + equals + does not equal + contains + does not contain + greater than + greater than or equal to + less than + less than or equal to + Id + Name + Created Date + Last Updated Date + order by + ascending + descending + Template + + + Image + Macro + Choose type of content + Choose a layout + Add a row + Add content + Drop content + Settings applied + This content is not allowed here + This content is allowed here + Click to embed + Click to insert image + Image caption... + Write here... + Grid Layouts + Layouts are the overall work area for the grid editor, usually you only need one or two different layouts + Add Grid Layout + Adjust the layout by setting column widths and adding additional sections + Row configurations + Rows are predefined cells arranged horizontally + Add row configuration + Adjust the row by setting cell widths and adding additional cells + Columns + Total combined number of columns in the grid layout + Settings + Configure what settings editors can change + Styles + Configure what styling editors can change + Allow all editors + Allow all row configurations + Maximum items + Leave blank or set to 0 for unlimited + Set as default + Choose extra + Choose default + are added + + + Compositions + Group + You have not added any groups + Add group + Inherited from + Add property + Required label + Enable list view + Configures the content item to show a sortable and searchable list of its children, the children will not be shown in the tree + Allowed Templates + Choose which templates editors are allowed to use on content of this type + Allow as root + Allow editors to create content of this type in the root of the content tree + Allowed child node types + Allow content of the specified types to be created underneath content of this type + Choose child node + Inherit tabs and properties from an existing document type. New tabs will be added to the current document type or merged if a tab with an identical name exists. + This content type is used in a composition, and therefore cannot be composed itself. + There are no content types available to use as a composition. + Create new + Use existing + Editor settings + Configuration + Yes, delete + was moved underneath + was copied underneath + Select the folder to move + Select the folder to copy + to in the tree structure below + All Document types + All Documents + All media items + using this document type will be deleted permanently, please confirm you want to delete these as well. + using this media type will be deleted permanently, please confirm you want to delete these as well. + using this member type will be deleted permanently, please confirm you want to delete these as well + and all documents using this type + and all media items using this type + and all members using this type + Member can edit + Allow this property value to be edited by the member on their profile page + Is sensitive data + Hide this property value from content editors that don't have access to view sensitive information + Show on member profile + Allow this property value to be displayed on the member profile page + tab has no sort order + Where is this composition used? + This composition is currently used in the composition of the following content types: + Allow varying by culture + Allow editors to create content of this type in different languages + Allow varying by culture + Element type + Is an Element type + An Element type is meant to be used for instance in Nested Content, and not in the tree + This is not applicable for an Element type + You have made changes to this property. Are you sure you want to discard them? + + + Add language + Mandatory language + Properties on this language have to be filled out before the node can be published. + Default language + An Umbraco site can only have one default language set. + Switching default language may result in default content missing. + Falls back to + No fall back language + To allow multi-lingual content to fall back to another language if not present in the requested language, select it here. + Fall back language + + + Add parameter + Edit parameter + Enter macro name + Parameters + Define the parameters that should be available when using this macro. + Select partial view macro file + + + Building models + this can take a bit of time, don't worry + Models generated + Models could not be generated + Models generation has failed, see exception in U log + + + Add fallback field + Fallback field + Add default value + Default value + Fallback field + Default value + Casing + Encoding + Choose field + Convert line breaks + Yes, convert line breaks + Replaces line breaks with 'br' html tag + Custom Fields + Date only + Format and encoding + Format as date + Format the value as a date, or a date with time, according to the active culture + HTML encode + Will replace special characters by their HTML equivalent. + Will be inserted after the field value + Will be inserted before the field value + Lowercase + Modify output + None + Output sample + Insert after field + Insert before field + Recursive + Yes, make it recursive + Separator + Standard Fields + Uppercase + URL encode + Will format special characters in URLs + Will only be used when the field values above are empty + This field will only be used if the primary field is empty + Date and time + + + Translation details + Download XML DTD + Fields + Include subpages + + No translator users found. Please create a translator user before you start sending content to translation + The page '%0%' has been send to translation + Send the page '%0%' to translation + Total words + Translate to + Translation completed. + You can preview the pages, you've just translated, by clicking below. If the original page is found, you will get a comparison of the 2 pages. + Translation failed, the XML file might be corrupt + Translation options + Translator + Upload translation XML + + + Content + Content Templates + Media + Cache Browser + Recycle Bin + Created packages + Data Types + Dictionary + Installed packages + Install skin + Install starter kit + Languages + Install local package + Macros + Media Types + Members + Member Groups + Member Roles + Member Types + Document Types + Relation Types + Packages + Packages + Partial Views + Partial View Macro Files + Install from repository + Install Runway + Runway modules + Scripting Files + Scripts + Stylesheets + Templates + Log Viewer + Users + Settings + Templating + Third Party + + + New update ready + %0% is ready, click here for download + No connection to server + Error checking for update. Please review trace-stack for further information + + + Access + Based on the assigned groups and start nodes, the user has access to the following nodes + Assign access + Administrator + Category field + User created + Change Your Password + Change photo + New password + hasn't been locked out + The password hasn't been changed + Confirm new password + You can change your password for accessing the Umbraco Back Office by filling out the form below and click the 'Change Password' button + Content Channel + Create another user + Create new users to give them access to Umbraco. When a new user is created a password will be generated that you can share with the user. + Description field + Disable User + Document Type + Editor + Excerpt field + Failed login attempts + Go to user profile + Add groups to assign access and permissions + Invite another user + Invite new users to give them access to Umbraco. An invite email will be sent to the user with information on how to log in to Umbraco. Invites last for 72 hours. + Language + Set the language you will see in menus and dialogs + Last lockout date + Last login + Password last changed + Username + Media start node + Limit the media library to a specific start node + Media start nodes + Limit the media library to specific start nodes + Sections + Disable Umbraco Access + has not logged in yet + Old password + Password + Reset password + Your password has been changed! + Please confirm the new password + Enter your new password + Your new password cannot be blank! + Current password + Invalid current password + There was a difference between the new password and the confirmed password. Please try again! + The confirmed password doesn't match the new password! + Replace child node permissions + You are currently modifying permissions for the pages: + Select pages to modify their permissions + Remove photo + Default permissions + Granular permissions + Set permissions for specific nodes + Profile + Search all children + Add sections to give users access + Select user groups + No start node selected + No start nodes selected + Content start node + Limit the content tree to a specific start node + Content start nodes + Limit the content tree to specific start nodes + User last updated + has been created + The new user has successfully been created. To log in to Umbraco use the password below. + User management + Name + User permissions + User group + has been invited + An invitation has been sent to the new user with details about how to log in to Umbraco. + Hello there and welcome to Umbraco! In just 1 minute you’ll be good to go, we just need you to setup a password and add a picture for your avatar. + Welcome to Umbraco! Unfortunately your invite has expired. Please contact your administrator and ask them to resend it. + Uploading a photo of yourself will make it easy for other users to recognize you. Click the circle above to upload your photo. + Writer + Change + Your profile + Your recent history + Session expires in + Invite user + Create user + Send invite + Back to users + Umbraco: Invitation + + + + + + + + + + + +
+ + + + + +
+ +
+ +
+
+ + + + + + +
+
+
+ + + + +
+ + + + +
+

+ Hi %0%, +

+

+ You have been invited by %1% to the Umbraco Back Office. +

+

+ Message from %1%: +
+ %2% +

+ + + + + + +
+ + + + + + +
+ + Click this link to accept the invite + +
+
+

If you cannot click on the link, copy and paste this URL into your browser window:

+ + + + +
+ + %3% + +
+

+
+
+


+
+
+ + ]]>
+ Invite + Resending invitation... + Delete User + Are you sure you wish to delete this user account? + All + Active + Disabled + Locked out + Invited + Inactive + Name (A-Z) + Name (Z-A) + Newest + Oldest + Last login + + + Validation + Validate as an email address + Validate as a number + Validate as a URL + ...or enter a custom validation + Field is mandatory + Enter a regular expression + You need to add at least + You can only have + items + items selected + Invalid date + Not a number + Invalid email + Value cannot be null + Value cannot be empty + Value is invalid, it does not match the correct pattern + Custom validation + + + + Value is set to the recommended value: '%0%'. + Value was set to '%1%' for XPath '%2%' in configuration file '%3%'. + Expected value '%1%' for '%2%' in configuration file '%3%', but found '%0%'. + Found unexpected value '%0%' for '%2%' in configuration file '%3%'. + + Custom errors are set to '%0%'. + Custom errors are currently set to '%0%'. It is recommended to set this to '%1%' before go live. + Custom errors successfully set to '%0%'. + MacroErrors are set to '%0%'. + MacroErrors are set to '%0%' which will prevent some or all pages in your site from loading completely if there are any errors in macros. Rectifying this will set the value to '%1%'. + MacroErrors are now set to '%0%'. + + Try Skip IIS Custom Errors is set to '%0%' and you're using IIS version '%1%'. + Try Skip IIS Custom Errors is currently '%0%'. It is recommended to set this to '%1%' for your IIS version (%2%). + Try Skip IIS Custom Errors successfully set to '%0%'. + + File does not exist: '%0%'. + '%0%' in config file '%1%'.]]> + There was an error, check log for full error: %0%. + Database - The database schema is correct for this version of Umbraco + %0% problems were detected with your database schema (Check the log for details) + Some errors were detected while validating the database schema against the current version of Umbraco. + Your website's certificate is valid. + Certificate validation error: '%0%' + Your website's SSL certificate has expired. + Your website's SSL certificate is expiring in %0% days. + Error pinging the URL %0% - '%1%' + You are currently %0% viewing the site using the HTTPS scheme. + The appSetting 'Umbraco.Core.UseHttps' is set to 'false' in your web.config file. Once you access this site using the HTTPS scheme, that should be set to 'true'. + The appSetting 'Umbraco.Core.UseHttps' is set to '%0%' in your web.config file, your cookies are %1% marked as secure. + Could not update the 'Umbraco.Core.UseHttps' setting in your web.config file. Error: %0% + + Enable HTTPS + Sets umbracoSSL setting to true in the appSettings of the web.config file. + The appSetting 'Umbraco.Core.UseHttps' is now set to 'true' in your web.config file, your cookies will be marked as secure. + Fix + Cannot fix a check with a value comparison type of 'ShouldNotEqual'. + Cannot fix a check with a value comparison type of 'ShouldEqual' with a provided value. + Value to fix check not provided. + Debug compilation mode is disabled. + Debug compilation mode is currently enabled. It is recommended to disable this setting before go live. + Debug compilation mode successfully disabled. + Trace mode is disabled. + Trace mode is currently enabled. It is recommended to disable this setting before go live. + Trace mode successfully disabled. + All folders have the correct permissions set. + + %0%.]]> + %0%. If they aren't being written to no action need be taken.]]> + All files have the correct permissions set. + + %0%.]]> + %0%. If they aren't being written to no action need be taken.]]> + X-Frame-Options used to control whether a site can be IFRAMEd by another was found.]]> + X-Frame-Options used to control whether a site can be IFRAMEd by another was not found.]]> + Set Header in Config + Adds a value to the httpProtocol/customHeaders section of web.config to prevent the site being IFRAMEd by other websites. + A setting to create a header preventing IFRAMEing of the site by other websites has been added to your web.config file. + Could not update web.config file. Error: %0% + X-Content-Type-Options used to protect against MIME sniffing vulnerabilities was found.]]> + X-Content-Type-Options used to protect against MIME sniffing vulnerabilities was not found.]]> + Adds a value to the httpProtocol/customHeaders section of web.config to protect against MIME sniffing vulnerabilities. + A setting to create a header protecting against MIME sniffing vulnerabilities has been added to your web.config file. + Strict-Transport-Security, also known as the HSTS-header, was found.]]> + Strict-Transport-Security was not found.]]> + Adds the header 'Strict-Transport-Security' with the value 'max-age=10886400' to the httpProtocol/customHeaders section of web.config. Use this fix only if you will have your domains running with https for the next 18 weeks (minimum). + The HSTS header has been added to your web.config file. + X-XSS-Protection was found.]]> + X-XSS-Protection was not found.]]> + Adds the header 'X-XSS-Protection' with the value '1; mode=block' to the httpProtocol/customHeaders section of web.config. + The X-XSS-Protection header has been added to your web.config file. + + %0%.]]> + No headers revealing information about the website technology were found. + In the Web.config file, system.net/mailsettings could not be found. + In the Web.config file system.net/mailsettings section, the host is not configured. + SMTP settings are configured correctly and the service is operating as expected. + The SMTP server configured with host '%0%' and port '%1%' could not be reached. Please check to ensure the SMTP settings in the Web.config file system.net/mailsettings are correct. + %0%.]]> + %0%.]]> +

Results of the scheduled Umbraco Health Checks run on %0% at %1% are as follows:

%2%]]>
+ Umbraco Health Check Status: %0% + + + Disable URL tracker + Enable URL tracker + Culture + Original URL + Redirected To + Redirect Url Management + The following URLs redirect to this content item: + No redirects have been made + When a published page gets renamed or moved a redirect will automatically be made to the new page. + Are you sure you want to remove the redirect from '%0%' to '%1%'? + Redirect URL removed. + Error removing redirect URL. + This will remove the redirect + Are you sure you want to disable the URL tracker? + URL tracker has now been disabled. + Error disabling the URL tracker, more information can be found in your log file. + URL tracker has now been enabled. + Error enabling the URL tracker, more information can be found in your log file. + + + No Dictionary items to choose from + + + %0% characters left.]]> + %1% too many.]]> + + + Trashed content with Id: {0} related to original parent content with Id: {1} + Trashed media with Id: {0} related to original parent media item with Id: {1} + Cannot automatically restore this item + There is no location where this item can be automatically restored. You can move the item manually using the tree below. + was restored under + + + Direction + Parent to child + Bidirectional + Parent + Child + Count + Relations + Created + Comment + Name + No relations for this relation type. + Relation Type + Relations + + + Getting Started + Redirect URL Management + Content + Welcome + Examine Management + Published Status + Models Builder + Health Check Profiling - Getting Started - Install Umbraco Forms - - + Getting Started + Install Umbraco Forms + + Go back Active layout: Jump to - group - -
+ group + passed + warning + failed + suggestion + Check passed + Check failed + Open backoffice search + Open/Close backoffice help + Open/Close your profile options + +
diff --git a/src/Umbraco.Web/Cache/DistributedCacheExtensions.cs b/src/Umbraco.Web/Cache/DistributedCacheExtensions.cs index 80c49e279c..579448e264 100644 --- a/src/Umbraco.Web/Cache/DistributedCacheExtensions.cs +++ b/src/Umbraco.Web/Cache/DistributedCacheExtensions.cs @@ -266,13 +266,21 @@ namespace Umbraco.Web.Cache public static void RefreshLanguageCache(this DistributedCache dc, ILanguage language) { if (language == null) return; - dc.Refresh(LanguageCacheRefresher.UniqueId, language.Id); + + var payload = new LanguageCacheRefresher.JsonPayload(language.Id, language.IsoCode, + language.WasPropertyDirty(nameof(ILanguage.IsoCode)) + ? LanguageCacheRefresher.JsonPayload.LanguageChangeType.ChangeCulture + : LanguageCacheRefresher.JsonPayload.LanguageChangeType.Update); + + dc.RefreshByPayload(LanguageCacheRefresher.UniqueId, new[] { payload }); } public static void RemoveLanguageCache(this DistributedCache dc, ILanguage language) { if (language == null) return; - dc.Remove(LanguageCacheRefresher.UniqueId, language.Id); + + var payload = new LanguageCacheRefresher.JsonPayload(language.Id, language.IsoCode, LanguageCacheRefresher.JsonPayload.LanguageChangeType.Remove); + dc.RefreshByPayload(LanguageCacheRefresher.UniqueId, new[] { payload }); } #endregion diff --git a/src/Umbraco.Web/Editors/LanguageController.cs b/src/Umbraco.Web/Editors/LanguageController.cs index 650dcea6e9..cb7fde23db 100644 --- a/src/Umbraco.Web/Editors/LanguageController.cs +++ b/src/Umbraco.Web/Editors/LanguageController.cs @@ -99,24 +99,28 @@ namespace Umbraco.Web.Editors throw new HttpResponseException(Request.CreateValidationErrorResponse(ModelState)); // this is prone to race conditions but the service will not let us proceed anyways - var existing = Services.LocalizationService.GetLanguageByIsoCode(language.IsoCode); + var existingByCulture = Services.LocalizationService.GetLanguageByIsoCode(language.IsoCode); // the localization service might return the generic language even when queried for specific ones (e.g. "da" when queried for "da-DK") // - we need to handle that explicitly - if (existing?.IsoCode != language.IsoCode) + if (existingByCulture?.IsoCode != language.IsoCode) { - existing = null; + existingByCulture = null; } - if (existing != null && language.Id != existing.Id) + if (existingByCulture != null && language.Id != existingByCulture.Id) { //someone is trying to create a language that already exist ModelState.AddModelError("IsoCode", "The language " + language.IsoCode + " already exists"); throw new HttpResponseException(Request.CreateValidationErrorResponse(ModelState)); } - if (existing == null) + var existingById = language.Id != default ? Services.LocalizationService.GetLanguageById(language.Id) : null; + + if (existingById == null) { + //Creating a new lang... + CultureInfo culture; try { @@ -141,38 +145,39 @@ namespace Umbraco.Web.Editors return Mapper.Map(newLang); } - existing.IsMandatory = language.IsMandatory; + existingById.IsMandatory = language.IsMandatory; // note that the service will prevent the default language from being "un-defaulted" // but does not hurt to test here - though the UI should prevent it too - if (existing.IsDefault && !language.IsDefault) + if (existingById.IsDefault && !language.IsDefault) { ModelState.AddModelError("IsDefault", "Cannot un-default the default language."); throw new HttpResponseException(Request.CreateValidationErrorResponse(ModelState)); } - existing.IsDefault = language.IsDefault; - existing.FallbackLanguageId = language.FallbackLanguageId; + existingById.IsDefault = language.IsDefault; + existingById.FallbackLanguageId = language.FallbackLanguageId; + existingById.IsoCode = language.IsoCode; // modifying an existing language can create a fallback, verify // note that the service will check again, dealing with race conditions - if (existing.FallbackLanguageId.HasValue) + if (existingById.FallbackLanguageId.HasValue) { var languages = Services.LocalizationService.GetAllLanguages().ToDictionary(x => x.Id, x => x); - if (!languages.ContainsKey(existing.FallbackLanguageId.Value)) + if (!languages.ContainsKey(existingById.FallbackLanguageId.Value)) { ModelState.AddModelError("FallbackLanguage", "The selected fall back language does not exist."); throw new HttpResponseException(Request.CreateValidationErrorResponse(ModelState)); } - if (CreatesCycle(existing, languages)) + if (CreatesCycle(existingById, languages)) { - ModelState.AddModelError("FallbackLanguage", $"The selected fall back language {languages[existing.FallbackLanguageId.Value].IsoCode} would create a circular path."); + ModelState.AddModelError("FallbackLanguage", $"The selected fall back language {languages[existingById.FallbackLanguageId.Value].IsoCode} would create a circular path."); throw new HttpResponseException(Request.CreateValidationErrorResponse(ModelState)); } } - Services.LocalizationService.Save(existing); - return Mapper.Map(existing); + Services.LocalizationService.Save(existingById); + return Mapper.Map(existingById); } // see LocalizationService From 22de853dee25c811092925cc88a85837e4c69020 Mon Sep 17 00:00:00 2001 From: Shannon Date: Mon, 14 Oct 2019 22:02:42 +1100 Subject: [PATCH 23/40] ensures the domain cache is totally refreshed when changing langs --- src/Umbraco.Web/Cache/DomainCacheRefresher.cs | 20 ++------- .../Cache/LanguageCacheRefresher.cs | 45 +++++++++---------- .../NuCache/PublishedSnapshotService.cs | 18 ++++++++ 3 files changed, 44 insertions(+), 39 deletions(-) diff --git a/src/Umbraco.Web/Cache/DomainCacheRefresher.cs b/src/Umbraco.Web/Cache/DomainCacheRefresher.cs index 37b0a483a6..4ffe4e2717 100644 --- a/src/Umbraco.Web/Cache/DomainCacheRefresher.cs +++ b/src/Umbraco.Web/Cache/DomainCacheRefresher.cs @@ -47,25 +47,13 @@ namespace Umbraco.Web.Cache // these events should never trigger // everything should be PAYLOAD/JSON - public override void RefreshAll() - { - throw new NotSupportedException(); - } + public override void RefreshAll() => throw new NotSupportedException(); - public override void Refresh(int id) - { - throw new NotSupportedException(); - } + public override void Refresh(int id) => throw new NotSupportedException(); - public override void Refresh(Guid id) - { - throw new NotSupportedException(); - } + public override void Refresh(Guid id) => throw new NotSupportedException(); - public override void Remove(int id) - { - throw new NotSupportedException(); - } + public override void Remove(int id) => throw new NotSupportedException(); #endregion diff --git a/src/Umbraco.Web/Cache/LanguageCacheRefresher.cs b/src/Umbraco.Web/Cache/LanguageCacheRefresher.cs index 03102ec969..2877874e5a 100644 --- a/src/Umbraco.Web/Cache/LanguageCacheRefresher.cs +++ b/src/Umbraco.Web/Cache/LanguageCacheRefresher.cs @@ -5,6 +5,7 @@ using Umbraco.Core.Models; using Umbraco.Core.Services; using Umbraco.Core.Services.Changes; using Umbraco.Web.PublishedCache; +using static Umbraco.Web.Cache.LanguageCacheRefresher.JsonPayload; namespace Umbraco.Web.Cache { @@ -12,11 +13,10 @@ namespace Umbraco.Web.Cache //CacheRefresherBase { - public LanguageCacheRefresher(AppCaches appCaches, IPublishedSnapshotService publishedSnapshotService, IDomainService domainService) + public LanguageCacheRefresher(AppCaches appCaches, IPublishedSnapshotService publishedSnapshotService) : base(appCaches) { _publishedSnapshotService = publishedSnapshotService; - _domainService = domainService; } #region Define @@ -45,20 +45,21 @@ namespace Umbraco.Web.Cache //clear all no matter what type of payload ClearAllIsolatedCacheByEntityType(); + //clear all no matter what type of payload + RefreshDomains(); + foreach (var payload in payloads) { - RefreshDomains(payload.Id); - switch (payload.ChangeType) { - case JsonPayload.LanguageChangeType.Update: + case LanguageChangeType.Update: clearDictionary = true; break; - case JsonPayload.LanguageChangeType.Remove: + case LanguageChangeType.Remove: clearDictionary = true; clearContent = true; break; - case JsonPayload.LanguageChangeType.ChangeCulture: + case LanguageChangeType.ChangeCulture: clearDictionary = true; clearContent = true; break; @@ -70,11 +71,13 @@ namespace Umbraco.Web.Cache ClearAllIsolatedCacheByEntityType(); } - //if this flag is set, we will tell the published snapshot service to refresh ALL content + //if this flag is set, we will tell the published snapshot service to refresh ALL content and evict ALL IContent items if (clearContent) { + ContentCacheRefresher.RefreshContentTypes(AppCaches); // we need to evict all IContent items + //now refresh all nucache var clearContentPayload = new[] { new ContentCacheRefresher.JsonPayload(0, null, TreeChangeTypes.RefreshAll) }; - ContentCacheRefresher.NotifyPublishedSnapshotService(_publishedSnapshotService, AppCaches, clearContentPayload); + ContentCacheRefresher.NotifyPublishedSnapshotService(_publishedSnapshotService, AppCaches, clearContentPayload); } // then trigger event @@ -94,23 +97,19 @@ namespace Umbraco.Web.Cache #endregion - private void RefreshDomains(int langId) + /// + /// Clears all domain caches + /// + private void RefreshDomains() { - var assignedDomains = _domainService.GetAll(true).Where(x => x.LanguageId.HasValue && x.LanguageId.Value == langId).ToList(); + ClearAllIsolatedCacheByEntityType(); - if (assignedDomains.Count > 0) - { - // TODO: this is duplicating the logic in DomainCacheRefresher BUT we cannot inject that into this because it it not registered explicitly in the container, - // and we cannot inject the CacheRefresherCollection since that would be a circular reference, so what is the best way to call directly in to the - // DomainCacheRefresher? + // note: must do what's above FIRST else the repositories still have the old cached + // content and when the PublishedCachesService is notified of changes it does not see + // the new content... - ClearAllIsolatedCacheByEntityType(); - // note: must do what's above FIRST else the repositories still have the old cached - // content and when the PublishedCachesService is notified of changes it does not see - // the new content... - // notify - _publishedSnapshotService.Notify(assignedDomains.Select(x => new DomainCacheRefresher.JsonPayload(x.Id, DomainChangeTypes.Remove)).ToArray()); - } + var payloads = new[] { new DomainCacheRefresher.JsonPayload(0, DomainChangeTypes.RefreshAll) }; + _publishedSnapshotService.Notify(payloads); } #region Json diff --git a/src/Umbraco.Web/PublishedCache/NuCache/PublishedSnapshotService.cs b/src/Umbraco.Web/PublishedCache/NuCache/PublishedSnapshotService.cs index bf6012816a..23c2131a82 100755 --- a/src/Umbraco.Web/PublishedCache/NuCache/PublishedSnapshotService.cs +++ b/src/Umbraco.Web/PublishedCache/NuCache/PublishedSnapshotService.cs @@ -260,6 +260,8 @@ namespace Umbraco.Web.PublishedCache.NuCache ContentTypeService.ScopedRefreshedEntity += OnContentTypeRefreshedEntity; MediaTypeService.ScopedRefreshedEntity += OnMediaTypeRefreshedEntity; MemberTypeService.ScopedRefreshedEntity += OnMemberTypeRefreshedEntity; + + LocalizationService.SavedLanguage += OnLanguageSaved; } private void TearDownRepositoryEvents() @@ -277,6 +279,8 @@ namespace Umbraco.Web.PublishedCache.NuCache ContentTypeService.ScopedRefreshedEntity -= OnContentTypeRefreshedEntity; MediaTypeService.ScopedRefreshedEntity -= OnMediaTypeRefreshedEntity; MemberTypeService.ScopedRefreshedEntity -= OnMemberTypeRefreshedEntity; + + LocalizationService.SavedLanguage -= OnLanguageSaved; } public override void Dispose() @@ -1309,6 +1313,20 @@ namespace Umbraco.Web.PublishedCache.NuCache RebuildMemberDbCache(contentTypeIds: memberTypeIds); } + /// + /// If a is ever saved with a different culture, we need to rebuild all of the content nucache table + /// + /// + /// + private void OnLanguageSaved(ILocalizationService sender, Core.Events.SaveEventArgs e) + { + var cultureChanged = e.SavedEntities.Any(x => x.WasPropertyDirty(nameof(ILanguage.IsoCode))); + if(cultureChanged) + { + RebuildContentDbCache(); + } + } + private ContentNuDto GetDto(IContentBase content, bool published) { // should inject these in ctor From 58f50be33738b48fdc22afdcbbf0af0928d34cfb Mon Sep 17 00:00:00 2001 From: Shannon Date: Mon, 14 Oct 2019 22:09:47 +1100 Subject: [PATCH 24/40] simplifies lang refresher a bit --- src/Umbraco.Web/Cache/LanguageCacheRefresher.cs | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/Umbraco.Web/Cache/LanguageCacheRefresher.cs b/src/Umbraco.Web/Cache/LanguageCacheRefresher.cs index 2877874e5a..8463acd6e0 100644 --- a/src/Umbraco.Web/Cache/LanguageCacheRefresher.cs +++ b/src/Umbraco.Web/Cache/LanguageCacheRefresher.cs @@ -45,9 +45,6 @@ namespace Umbraco.Web.Cache //clear all no matter what type of payload ClearAllIsolatedCacheByEntityType(); - //clear all no matter what type of payload - RefreshDomains(); - foreach (var payload in payloads) { switch (payload.ChangeType) @@ -56,9 +53,6 @@ namespace Umbraco.Web.Cache clearDictionary = true; break; case LanguageChangeType.Remove: - clearDictionary = true; - clearContent = true; - break; case LanguageChangeType.ChangeCulture: clearDictionary = true; clearContent = true; @@ -74,6 +68,8 @@ namespace Umbraco.Web.Cache //if this flag is set, we will tell the published snapshot service to refresh ALL content and evict ALL IContent items if (clearContent) { + //clear all domain caches + RefreshDomains(); ContentCacheRefresher.RefreshContentTypes(AppCaches); // we need to evict all IContent items //now refresh all nucache var clearContentPayload = new[] { new ContentCacheRefresher.JsonPayload(0, null, TreeChangeTypes.RefreshAll) }; From 5125772de543413c9d81458997dc41151bc6c1bb Mon Sep 17 00:00:00 2001 From: Shannon Date: Wed, 16 Oct 2019 15:00:13 +1100 Subject: [PATCH 25/40] ensures nucache table isn't rebuilt when adding a new lang --- .../PublishedCache/NuCache/PublishedSnapshotService.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Umbraco.Web/PublishedCache/NuCache/PublishedSnapshotService.cs b/src/Umbraco.Web/PublishedCache/NuCache/PublishedSnapshotService.cs index 23c2131a82..948019e8cc 100755 --- a/src/Umbraco.Web/PublishedCache/NuCache/PublishedSnapshotService.cs +++ b/src/Umbraco.Web/PublishedCache/NuCache/PublishedSnapshotService.cs @@ -1320,7 +1320,8 @@ namespace Umbraco.Web.PublishedCache.NuCache /// private void OnLanguageSaved(ILocalizationService sender, Core.Events.SaveEventArgs e) { - var cultureChanged = e.SavedEntities.Any(x => x.WasPropertyDirty(nameof(ILanguage.IsoCode))); + //culture changed on an existing language + var cultureChanged = e.SavedEntities.Any(x => !x.WasPropertyDirty(nameof(ILanguage.Id)) && x.WasPropertyDirty(nameof(ILanguage.IsoCode))); if(cultureChanged) { RebuildContentDbCache(); From 57288236250352f7e05bc14917db5999a7bcb651 Mon Sep 17 00:00:00 2001 From: Shannon Date: Wed, 16 Oct 2019 15:49:19 +1100 Subject: [PATCH 26/40] Fixes tests - Nucache tests were not disposing the snapshot service so was binding to all events!! renames the test snapshot service to avoid confusion --- ...dSnapshotService.cs => XmlPublishedSnapshotService.cs} | 6 +++--- src/Umbraco.Tests/LegacyXmlPublishedCache/XmlStore.cs | 2 +- .../PublishedContent/NuCacheChildrenTests.cs | 6 ++++++ src/Umbraco.Tests/PublishedContent/NuCacheTests.cs | 7 +++++++ src/Umbraco.Tests/Scoping/ScopedXmlTests.cs | 2 +- src/Umbraco.Tests/TestHelpers/TestWithDatabaseBase.cs | 8 ++++---- src/Umbraco.Tests/Umbraco.Tests.csproj | 2 +- src/Umbraco.Tests/Web/Mvc/UmbracoViewPageTests.cs | 4 ++-- 8 files changed, 25 insertions(+), 12 deletions(-) rename src/Umbraco.Tests/LegacyXmlPublishedCache/{PublishedSnapshotService.cs => XmlPublishedSnapshotService.cs} (97%) diff --git a/src/Umbraco.Tests/LegacyXmlPublishedCache/PublishedSnapshotService.cs b/src/Umbraco.Tests/LegacyXmlPublishedCache/XmlPublishedSnapshotService.cs similarity index 97% rename from src/Umbraco.Tests/LegacyXmlPublishedCache/PublishedSnapshotService.cs rename to src/Umbraco.Tests/LegacyXmlPublishedCache/XmlPublishedSnapshotService.cs index 394a33d777..ec6b854a46 100644 --- a/src/Umbraco.Tests/LegacyXmlPublishedCache/PublishedSnapshotService.cs +++ b/src/Umbraco.Tests/LegacyXmlPublishedCache/XmlPublishedSnapshotService.cs @@ -21,7 +21,7 @@ namespace Umbraco.Tests.LegacyXmlPublishedCache /// /// Implements a published snapshot service. /// - internal class PublishedSnapshotService : PublishedSnapshotServiceBase + internal class XmlPublishedSnapshotService : PublishedSnapshotServiceBase { private readonly XmlStore _xmlStore; private readonly RoutesCache _routesCache; @@ -41,7 +41,7 @@ namespace Umbraco.Tests.LegacyXmlPublishedCache #region Constructors // used in WebBootManager + tests - public PublishedSnapshotService(ServiceContext serviceContext, + public XmlPublishedSnapshotService(ServiceContext serviceContext, IPublishedContentTypeFactory publishedContentTypeFactory, IScopeProvider scopeProvider, IAppCache requestCache, @@ -65,7 +65,7 @@ namespace Umbraco.Tests.LegacyXmlPublishedCache } // used in some tests - internal PublishedSnapshotService(ServiceContext serviceContext, + internal XmlPublishedSnapshotService(ServiceContext serviceContext, IPublishedContentTypeFactory publishedContentTypeFactory, IScopeProvider scopeProvider, IAppCache requestCache, diff --git a/src/Umbraco.Tests/LegacyXmlPublishedCache/XmlStore.cs b/src/Umbraco.Tests/LegacyXmlPublishedCache/XmlStore.cs index 3b675c2f07..447104b7cd 100644 --- a/src/Umbraco.Tests/LegacyXmlPublishedCache/XmlStore.cs +++ b/src/Umbraco.Tests/LegacyXmlPublishedCache/XmlStore.cs @@ -32,7 +32,7 @@ namespace Umbraco.Tests.LegacyXmlPublishedCache /// Represents the Xml storage for the Xml published cache. /// /// - /// One instance of is instantiated by the and + /// One instance of is instantiated by the and /// then passed to all instances that are created (one per request). /// This class should *not* be public. /// diff --git a/src/Umbraco.Tests/PublishedContent/NuCacheChildrenTests.cs b/src/Umbraco.Tests/PublishedContent/NuCacheChildrenTests.cs index c116c12f59..5acba4b609 100644 --- a/src/Umbraco.Tests/PublishedContent/NuCacheChildrenTests.cs +++ b/src/Umbraco.Tests/PublishedContent/NuCacheChildrenTests.cs @@ -41,6 +41,12 @@ namespace Umbraco.Tests.PublishedContent private ContentType _contentTypeVariant; private TestDataSource _source; + [TearDown] + public void Teardown() + { + _snapshotService?.Dispose(); + } + private void Init(IEnumerable kits) { Current.Reset(); diff --git a/src/Umbraco.Tests/PublishedContent/NuCacheTests.cs b/src/Umbraco.Tests/PublishedContent/NuCacheTests.cs index 44df5c20cb..0e05e6baad 100644 --- a/src/Umbraco.Tests/PublishedContent/NuCacheTests.cs +++ b/src/Umbraco.Tests/PublishedContent/NuCacheTests.cs @@ -36,6 +36,12 @@ namespace Umbraco.Tests.PublishedContent private ContentType _contentType; private PropertyType _propertyType; + [TearDown] + public void Teardown() + { + _snapshotService?.Dispose(); + } + private void Init() { Current.Reset(); @@ -303,5 +309,6 @@ namespace Umbraco.Tests.PublishedContent Assert.IsFalse(c2.IsPublished("dk-DA")); Assert.IsTrue(c2.IsPublished("de-DE")); } + } } diff --git a/src/Umbraco.Tests/Scoping/ScopedXmlTests.cs b/src/Umbraco.Tests/Scoping/ScopedXmlTests.cs index 34482a79fa..91a6934e18 100644 --- a/src/Umbraco.Tests/Scoping/ScopedXmlTests.cs +++ b/src/Umbraco.Tests/Scoping/ScopedXmlTests.cs @@ -73,7 +73,7 @@ namespace Umbraco.Tests.Scoping // xmlStore.Xml - the actual main xml document // publishedContentCache.GetXml() - the captured xml - private static XmlStore XmlStore => (Current.Factory.GetInstance() as PublishedSnapshotService).XmlStore; + private static XmlStore XmlStore => (Current.Factory.GetInstance() as XmlPublishedSnapshotService).XmlStore; private static XmlDocument XmlMaster => XmlStore.Xml; private static XmlDocument XmlInContext => ((PublishedContentCache) Umbraco.Web.Composing.Current.UmbracoContext.Content).GetXml(false); diff --git a/src/Umbraco.Tests/TestHelpers/TestWithDatabaseBase.cs b/src/Umbraco.Tests/TestHelpers/TestWithDatabaseBase.cs index 9cc2b97445..050de4fcb9 100644 --- a/src/Umbraco.Tests/TestHelpers/TestWithDatabaseBase.cs +++ b/src/Umbraco.Tests/TestHelpers/TestWithDatabaseBase.cs @@ -259,7 +259,7 @@ namespace Umbraco.Tests.TestHelpers var publishedSnapshotAccessor = new UmbracoContextPublishedSnapshotAccessor(Umbraco.Web.Composing.Current.UmbracoContextAccessor); var variationContextAccessor = new TestVariationContextAccessor(); - var service = new PublishedSnapshotService( + var service = new XmlPublishedSnapshotService( ServiceContext, Factory.GetInstance(), ScopeProvider, @@ -357,14 +357,14 @@ namespace Umbraco.Tests.TestHelpers protected UmbracoContext GetUmbracoContext(string url, int templateId = 1234, RouteData routeData = null, bool setSingleton = false, IUmbracoSettingsSection umbracoSettings = null, IEnumerable urlProviders = null, IEnumerable mediaUrlProviders = null, IGlobalSettings globalSettings = null, IPublishedSnapshotService snapshotService = null) { // ensure we have a PublishedCachesService - var service = snapshotService ?? PublishedSnapshotService as PublishedSnapshotService; + var service = snapshotService ?? PublishedSnapshotService as XmlPublishedSnapshotService; if (service == null) throw new Exception("Not a proper XmlPublishedCache.PublishedCachesService."); - if (service is PublishedSnapshotService) + if (service is XmlPublishedSnapshotService) { // re-initialize PublishedCacheService content with an Xml source with proper template id - ((PublishedSnapshotService)service).XmlStore.GetXmlDocument = () => + ((XmlPublishedSnapshotService)service).XmlStore.GetXmlDocument = () => { var doc = new XmlDocument(); doc.LoadXml(GetXmlContent(templateId)); diff --git a/src/Umbraco.Tests/Umbraco.Tests.csproj b/src/Umbraco.Tests/Umbraco.Tests.csproj index fcf73fbffa..39826fcc38 100644 --- a/src/Umbraco.Tests/Umbraco.Tests.csproj +++ b/src/Umbraco.Tests/Umbraco.Tests.csproj @@ -511,7 +511,7 @@ - + diff --git a/src/Umbraco.Tests/Web/Mvc/UmbracoViewPageTests.cs b/src/Umbraco.Tests/Web/Mvc/UmbracoViewPageTests.cs index 5c291c9601..9ca17675af 100644 --- a/src/Umbraco.Tests/Web/Mvc/UmbracoViewPageTests.cs +++ b/src/Umbraco.Tests/Web/Mvc/UmbracoViewPageTests.cs @@ -29,7 +29,7 @@ namespace Umbraco.Tests.Web.Mvc [UmbracoTest(WithApplication = true)] public class UmbracoViewPageTests : UmbracoTestBase { - private PublishedSnapshotService _service; + private XmlPublishedSnapshotService _service; [TearDown] public override void TearDown() @@ -421,7 +421,7 @@ namespace Umbraco.Tests.Web.Mvc var scopeProvider = TestObjects.GetScopeProvider(Mock.Of()); var factory = Mock.Of(); var umbracoContextAccessor = Mock.Of(); - _service = new PublishedSnapshotService(svcCtx, factory, scopeProvider, cache, + _service = new XmlPublishedSnapshotService(svcCtx, factory, scopeProvider, cache, null, null, umbracoContextAccessor, null, null, null, new TestDefaultCultureAccessor(), From e77eb746558165bc56a52b8a1b55f8370044e65c Mon Sep 17 00:00:00 2001 From: Bjarke Berg Date: Mon, 4 Nov 2019 11:54:19 +0100 Subject: [PATCH 27/40] post cherry pick fix --- src/Umbraco.Web/Cache/LanguageCacheRefresher.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Umbraco.Web/Cache/LanguageCacheRefresher.cs b/src/Umbraco.Web/Cache/LanguageCacheRefresher.cs index 8463acd6e0..e7d77207e3 100644 --- a/src/Umbraco.Web/Cache/LanguageCacheRefresher.cs +++ b/src/Umbraco.Web/Cache/LanguageCacheRefresher.cs @@ -46,7 +46,7 @@ namespace Umbraco.Web.Cache ClearAllIsolatedCacheByEntityType(); foreach (var payload in payloads) - { + { switch (payload.ChangeType) { case LanguageChangeType.Update: @@ -72,8 +72,8 @@ namespace Umbraco.Web.Cache RefreshDomains(); ContentCacheRefresher.RefreshContentTypes(AppCaches); // we need to evict all IContent items //now refresh all nucache - var clearContentPayload = new[] { new ContentCacheRefresher.JsonPayload(0, null, TreeChangeTypes.RefreshAll) }; - ContentCacheRefresher.NotifyPublishedSnapshotService(_publishedSnapshotService, AppCaches, clearContentPayload); + var clearContentPayload = new[] { new ContentCacheRefresher.JsonPayload(0, TreeChangeTypes.RefreshAll) }; + ContentCacheRefresher.NotifyPublishedSnapshotService(_publishedSnapshotService, AppCaches, clearContentPayload); } // then trigger event From 1c70d04ce29fd750055227cabac2bccd44cc1d0b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B8ren=20Kottal?= Date: Tue, 5 Nov 2019 15:33:07 +0100 Subject: [PATCH 28/40] Moves editor name part out of template. Adds null checking in templates --- .../src/views/propertyeditors/grid/grid.controller.js | 11 +++++++++-- src/Umbraco.Web.UI/config/grid.editors.config.js | 7 ++++--- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/grid/grid.controller.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/grid/grid.controller.js index 32f495e32b..5dce84d5dc 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/grid/grid.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/grid/grid.controller.js @@ -681,8 +681,15 @@ angular.module("umbraco") }; $scope.getTemplateName = function (control) { - if (control.editor.nameExp) return control.editor.nameExp(control) - return control.editor.name; + var templateName = control.editor.name; + if (control.editor.nameExp) { + var valueOfTemplate = control.editor.nameExp(control); + if (valueOfTemplate != "") { + templateName += ": "; + templateName += valueOfTemplate; + } + } + return templateName; } // ********************************************* diff --git a/src/Umbraco.Web.UI/config/grid.editors.config.js b/src/Umbraco.Web.UI/config/grid.editors.config.js index 49b843689b..210d167f9e 100644 --- a/src/Umbraco.Web.UI/config/grid.editors.config.js +++ b/src/Umbraco.Web.UI/config/grid.editors.config.js @@ -7,14 +7,14 @@ }, { "name": "Image", - "nameTemplate": "{{ 'Image: ' + (value.udi | ncNodeName) }}", + "nameTemplate": "{{ value && value.udi ? (value.udi | ncNodeName) : '' }}", "alias": "media", "view": "media", "icon": "icon-picture" }, { "name": "Macro", - "nameTemplate": "{{ 'Macro: ' + value.macroAlias }}", + "nameTemplate": "{{ value && value.macroAlias ? value.macroAlias : '' }}", "alias": "macro", "view": "macro", "icon": "icon-settings-alt" @@ -27,7 +27,7 @@ }, { "name": "Headline", - "nameTemplate": "{{ 'Headline: ' + value }}", + "nameTemplate": "{{ value }}", "alias": "headline", "view": "textstring", "icon": "icon-coin", @@ -38,6 +38,7 @@ }, { "name": "Quote", + "nameTemplate": "{{ value ? value.substring(0,32) + (value.length > 32 ? '...' : '') : '' }}", "alias": "quote", "view": "textstring", "icon": "icon-quote", From 466610bd328603e3d30ceb2ef463769f871cc0f4 Mon Sep 17 00:00:00 2001 From: Paul Seal Date: Thu, 7 Nov 2019 12:18:57 +0000 Subject: [PATCH 29/40] - added delete title to trash icons in the grid --- .../src/views/propertyeditors/grid/grid.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/grid/grid.html b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/grid/grid.html index 3995ed703d..e889067321 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/grid/grid.html +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/grid/grid.html @@ -95,7 +95,7 @@
- +
- + Date: Sun, 27 Oct 2019 10:40:03 +0000 Subject: [PATCH 30/40] Changed the styling of Resend Invitation button and fixed the margin --- .../src/less/components/users/umb-user-details.less | 5 +++++ .../src/views/users/views/user/details.html | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/Umbraco.Web.UI.Client/src/less/components/users/umb-user-details.less b/src/Umbraco.Web.UI.Client/src/less/components/users/umb-user-details.less index 9ddad03b48..7caec3c78e 100644 --- a/src/Umbraco.Web.UI.Client/src/less/components/users/umb-user-details.less +++ b/src/Umbraco.Web.UI.Client/src/less/components/users/umb-user-details.less @@ -63,6 +63,10 @@ a.umb-user-details-details__back-link { .umb-user-details-details__sidebar { flex: 0 0 @sidebarwidth; + + .umb-button{ + margin-left:0px; + } } @media (max-width: 768px) { @@ -101,6 +105,7 @@ a.umb-user-details-details__back-link { .umb-user-details-details__information-item { margin-bottom: 10px; font-size: 13px; + margin-top:10px; } .umb-user-details-details__information-item-label { diff --git a/src/Umbraco.Web.UI.Client/src/views/users/views/user/details.html b/src/Umbraco.Web.UI.Client/src/views/users/views/user/details.html index e759be5e7a..ee77e4c14e 100644 --- a/src/Umbraco.Web.UI.Client/src/views/users/views/user/details.html +++ b/src/Umbraco.Web.UI.Client/src/views/users/views/user/details.html @@ -322,7 +322,7 @@ rows="4"> Date: Thu, 7 Nov 2019 12:44:58 +0000 Subject: [PATCH 31/40] Accessibility Improvement - Open Template in info content app changed from anchor tag to button --- .../src/views/components/content/umb-content-node-info.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/views/components/content/umb-content-node-info.html b/src/Umbraco.Web.UI.Client/src/views/components/content/umb-content-node-info.html index da093f72fe..d72e977010 100644 --- a/src/Umbraco.Web.UI.Client/src/views/components/content/umb-content-node-info.html +++ b/src/Umbraco.Web.UI.Client/src/views/components/content/umb-content-node-info.html @@ -169,9 +169,9 @@ ng-change="updateTemplate(node.template)"> - +
From 41915080b2745207cdf596921d955831394d2f2e Mon Sep 17 00:00:00 2001 From: andyneil Date: Thu, 7 Nov 2019 15:01:22 +0000 Subject: [PATCH 32/40] Fix incorrect data types for default member properties. (#7086) Issue https://github.com/umbraco/Umbraco-CMS/issues/7051 --- src/Umbraco.Core/Constants-Conventions.cs | 18 ++++++++++++------ .../Implement/MemberTypeRepository.cs | 13 +++++++++++-- 2 files changed, 23 insertions(+), 8 deletions(-) diff --git a/src/Umbraco.Core/Constants-Conventions.cs b/src/Umbraco.Core/Constants-Conventions.cs index 6c9407667a..e78c498e66 100644 --- a/src/Umbraco.Core/Constants-Conventions.cs +++ b/src/Umbraco.Core/Constants-Conventions.cs @@ -221,7 +221,8 @@ namespace Umbraco.Core FailedPasswordAttempts, new PropertyType(PropertyEditors.Aliases.Label, ValueStorageType.Integer, true, FailedPasswordAttempts) { - Name = FailedPasswordAttemptsLabel + Name = FailedPasswordAttemptsLabel, + DataTypeId = Constants.DataTypes.LabelInt } }, { @@ -242,35 +243,40 @@ namespace Umbraco.Core LastLockoutDate, new PropertyType(PropertyEditors.Aliases.Label, ValueStorageType.Date, true, LastLockoutDate) { - Name = LastLockoutDateLabel + Name = LastLockoutDateLabel, + DataTypeId = Constants.DataTypes.LabelDateTime } }, { LastLoginDate, new PropertyType(PropertyEditors.Aliases.Label, ValueStorageType.Date, true, LastLoginDate) { - Name = LastLoginDateLabel + Name = LastLoginDateLabel, + DataTypeId = Constants.DataTypes.LabelDateTime } }, { LastPasswordChangeDate, new PropertyType(PropertyEditors.Aliases.Label, ValueStorageType.Date, true, LastPasswordChangeDate) { - Name = LastPasswordChangeDateLabel + Name = LastPasswordChangeDateLabel, + DataTypeId = Constants.DataTypes.LabelDateTime } }, { PasswordAnswer, new PropertyType(PropertyEditors.Aliases.Label, ValueStorageType.Nvarchar, true, PasswordAnswer) { - Name = PasswordAnswerLabel + Name = PasswordAnswerLabel, + DataTypeId = Constants.DataTypes.LabelString } }, { PasswordQuestion, new PropertyType(PropertyEditors.Aliases.Label, ValueStorageType.Nvarchar, true, PasswordQuestion) { - Name = PasswordQuestionLabel + Name = PasswordQuestionLabel, + DataTypeId = Constants.DataTypes.LabelString } } }; diff --git a/src/Umbraco.Core/Persistence/Repositories/Implement/MemberTypeRepository.cs b/src/Umbraco.Core/Persistence/Repositories/Implement/MemberTypeRepository.cs index ee651819bf..c3b95dbd8f 100644 --- a/src/Umbraco.Core/Persistence/Repositories/Implement/MemberTypeRepository.cs +++ b/src/Umbraco.Core/Persistence/Repositories/Implement/MemberTypeRepository.cs @@ -225,8 +225,17 @@ namespace Umbraco.Core.Persistence.Repositories.Implement if (builtinProperties.ContainsKey(propertyType.Alias)) { //this reset's its current data type reference which will be re-assigned based on the property editor assigned on the next line - propertyType.DataTypeId = 0; - propertyType.DataTypeKey = default; + var propDefinition = builtinProperties[propertyType.Alias]; + if (propDefinition != null) + { + propertyType.DataTypeId = propDefinition.DataTypeId; + propertyType.DataTypeKey = propDefinition.DataTypeKey; + } + else + { + propertyType.DataTypeId = 0; + propertyType.DataTypeKey = default; + } } } } From 0d2c2846d4e9c3d44c956650db33fc2955a394a3 Mon Sep 17 00:00:00 2001 From: Richard Thompson Date: Thu, 7 Nov 2019 14:55:21 +0000 Subject: [PATCH 33/40] Corrected the model variable name The model variable name is registerModel rather than profileModel. --- .../Umbraco/PartialViewMacros/Templates/RegisterMember.cshtml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Umbraco.Web.UI/Umbraco/PartialViewMacros/Templates/RegisterMember.cshtml b/src/Umbraco.Web.UI/Umbraco/PartialViewMacros/Templates/RegisterMember.cshtml index ca6f09bd97..17ed95ea31 100644 --- a/src/Umbraco.Web.UI/Umbraco/PartialViewMacros/Templates/RegisterMember.cshtml +++ b/src/Umbraco.Web.UI/Umbraco/PartialViewMacros/Templates/RegisterMember.cshtml @@ -85,7 +85,7 @@ else easily change it. For example, if you wanted to render a custom editor for this field called "MyEditor" you would create a file at ~/Views/Shared/EditorTemplates/MyEditor.cshtml", then you will change the next line of code to render your specific editor template like: - @Html.EditorFor(m => profileModel.MemberProperties[i].Value, "MyEditor") + @Html.EditorFor(m => registerModel.MemberProperties[i].Value, "MyEditor") *@ @Html.EditorFor(m => registerModel.MemberProperties[i].Value) @Html.HiddenFor(m => registerModel.MemberProperties[i].Alias) From a2551521e45e47da4318012704d4c129e659aaa8 Mon Sep 17 00:00:00 2001 From: Jan Skovgaard Date: Mon, 11 Nov 2019 20:48:52 +0100 Subject: [PATCH 34/40] Settings dashboard: Add translations (#6880) --- .../settings/settingsdashboardintro.html | 32 ++++++++++++++----- src/Umbraco.Web.UI/Umbraco/config/lang/en.xml | 30 +++++++++++++++++ .../Umbraco/config/lang/en_us.xml | 30 +++++++++++++++++ 3 files changed, 84 insertions(+), 8 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/views/dashboard/settings/settingsdashboardintro.html b/src/Umbraco.Web.UI.Client/src/views/dashboard/settings/settingsdashboardintro.html index cc3e57bdc4..0ad88b9894 100644 --- a/src/Umbraco.Web.UI.Client/src/views/dashboard/settings/settingsdashboardintro.html +++ b/src/Umbraco.Web.UI.Client/src/views/dashboard/settings/settingsdashboardintro.html @@ -1,14 +1,30 @@ -

Start here

-

This section contains the building blocks for your Umbraco site. Follow the below links to find out more about working with the items in the Settings section:

-
Find out more:
+

+ Start here +

+ +

This section contains the building blocks for your Umbraco site. Follow the below links to find out more about working with the items in the Settings section:

+
: +
+ Find out more: +
diff --git a/src/Umbraco.Web.UI/Umbraco/config/lang/en.xml b/src/Umbraco.Web.UI/Umbraco/config/lang/en.xml index a8c1be1829..653974a6fe 100644 --- a/src/Umbraco.Web.UI/Umbraco/config/lang/en.xml +++ b/src/Umbraco.Web.UI/Umbraco/config/lang/en.xml @@ -2303,4 +2303,34 @@ To manage your website, simply open the Umbraco back office and start adding con To get you started + + Start here + This section contains the building blocks for your Umbraco site. Follow the below links to find out more about working with the items in the Settings section + Find out more + + in the Documentation section of Our Umbraco + ]]> + + + Community Forum + ]]> + + + tutorial videos (some are free, some require a subscription) + ]]> + + + productivity boosting tools and commercial support + ]]> + + + training and certification opportunities + ]]> + + 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 cca99b1244..ee3c7199f1 100644 --- a/src/Umbraco.Web.UI/Umbraco/config/lang/en_us.xml +++ b/src/Umbraco.Web.UI/Umbraco/config/lang/en_us.xml @@ -2319,4 +2319,34 @@ To manage your website, simply open the Umbraco back office and start adding con To get you started + + Start here + This section contains the building blocks for your Umbraco site. Follow the below links to find out more about working with the items in the Settings section + Find out more + + in the Documentation section of Our Umbraco + ]]> + + + Community Forum + ]]> + + + tutorial videos (some are free, some require a subscription) + ]]> + + + productivity boosting tools and commercial support + ]]> + + + training and certification opportunities + ]]> + + From 7eef6b40370fa4cd29a112252a49efb8bd6c25b3 Mon Sep 17 00:00:00 2001 From: Bjarke Berg Date: Tue, 12 Nov 2019 08:50:31 +0100 Subject: [PATCH 35/40] https://github.com/umbraco/Umbraco-CMS/issues/7125 - Updates the projects to use the same versions as required by our nuspec --- src/Umbraco.Examine/Umbraco.Examine.csproj | 2 +- src/Umbraco.Tests/Umbraco.Tests.csproj | 2 +- src/Umbraco.Web.UI/Umbraco.Web.UI.csproj | 8 ++++---- src/Umbraco.Web/Umbraco.Web.csproj | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/Umbraco.Examine/Umbraco.Examine.csproj b/src/Umbraco.Examine/Umbraco.Examine.csproj index e28a8e674e..da22d9e809 100644 --- a/src/Umbraco.Examine/Umbraco.Examine.csproj +++ b/src/Umbraco.Examine/Umbraco.Examine.csproj @@ -48,7 +48,7 @@ - + 1.0.0-beta2-19324-01 runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/src/Umbraco.Tests/Umbraco.Tests.csproj b/src/Umbraco.Tests/Umbraco.Tests.csproj index 39826fcc38..2f81623309 100644 --- a/src/Umbraco.Tests/Umbraco.Tests.csproj +++ b/src/Umbraco.Tests/Umbraco.Tests.csproj @@ -79,7 +79,7 @@ - + 1.8.14 diff --git a/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj b/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj index 6c20e8c765..51258de413 100644 --- a/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj +++ b/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj @@ -84,9 +84,9 @@ - - - + + + @@ -429,4 +429,4 @@ - + \ No newline at end of file diff --git a/src/Umbraco.Web/Umbraco.Web.csproj b/src/Umbraco.Web/Umbraco.Web.csproj index 166eeba352..781e023f78 100755 --- a/src/Umbraco.Web/Umbraco.Web.csproj +++ b/src/Umbraco.Web/Umbraco.Web.csproj @@ -60,9 +60,9 @@ - + - + 2.7.0.100 From 10622cc430dc535beb745d9d7b9d7c24c342ae82 Mon Sep 17 00:00:00 2001 From: Jeavon Date: Tue, 12 Nov 2019 10:26:25 +0000 Subject: [PATCH 36/40] Switched to using a dummy Uri so that runtimeState isn't needed as per review --- src/Umbraco.Examine/MediaValueSetBuilder.cs | 9 ++++----- .../UmbracoExamine/IndexInitializer.cs | 13 +------------ 2 files changed, 5 insertions(+), 17 deletions(-) diff --git a/src/Umbraco.Examine/MediaValueSetBuilder.cs b/src/Umbraco.Examine/MediaValueSetBuilder.cs index 20c92eb982..3e5b9865cc 100644 --- a/src/Umbraco.Examine/MediaValueSetBuilder.cs +++ b/src/Umbraco.Examine/MediaValueSetBuilder.cs @@ -16,16 +16,14 @@ namespace Umbraco.Examine { private readonly UrlSegmentProviderCollection _urlSegmentProviders; private readonly IUserService _userService; - private readonly IRuntimeState _runtimeState; public MediaValueSetBuilder(PropertyEditorCollection propertyEditors, UrlSegmentProviderCollection urlSegmentProviders, - IUserService userService, IRuntimeState runtimeState) + IUserService userService) : base(propertyEditors, false) { _urlSegmentProviders = urlSegmentProviders; _userService = userService; - _runtimeState = runtimeState; } /// @@ -55,8 +53,9 @@ namespace Umbraco.Examine if (!string.IsNullOrEmpty(umbracoFilePath)) { - var uri = new Uri(_runtimeState.ApplicationUrl.GetLeftPart(UriPartial.Authority) + umbracoFilePath); - umbracoFile = uri.Segments.Last(); + // intentional dummy Uri + var uri = new Uri("https://localhost/" + umbracoFilePath); + umbracoFile = uri.Segments.Last(); } var values = new Dictionary> diff --git a/src/Umbraco.Tests/UmbracoExamine/IndexInitializer.cs b/src/Umbraco.Tests/UmbracoExamine/IndexInitializer.cs index 5c9c965cd1..6c65ae8345 100644 --- a/src/Umbraco.Tests/UmbracoExamine/IndexInitializer.cs +++ b/src/Umbraco.Tests/UmbracoExamine/IndexInitializer.cs @@ -45,21 +45,10 @@ namespace Umbraco.Tests.UmbracoExamine public static MediaIndexPopulator GetMediaIndexRebuilder(PropertyEditorCollection propertyEditors, IMediaService mediaService) { - var mediaValueSetBuilder = new MediaValueSetBuilder(propertyEditors, new UrlSegmentProviderCollection(new[] { new DefaultUrlSegmentProvider() }), GetMockUserService(), MockRuntimeState(RuntimeLevel.Run)); + var mediaValueSetBuilder = new MediaValueSetBuilder(propertyEditors, new UrlSegmentProviderCollection(new[] { new DefaultUrlSegmentProvider() }), GetMockUserService()); var mediaIndexDataSource = new MediaIndexPopulator(null, mediaService, mediaValueSetBuilder); return mediaIndexDataSource; } - - public static IRuntimeState MockRuntimeState(RuntimeLevel level) - { - var runtimeState = Mock.Of(); - Mock.Get(runtimeState).Setup(x => x.Level).Returns(level); - Mock.Get(runtimeState).SetupGet(m => m.ApplicationUrl).Returns(new Uri("https://localhost/umbraco")); - - return runtimeState; - } - - public static IContentService GetMockContentService() { long longTotalRecs; From e2adb4964c5f38742025e714d921432ddfc0628c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Wed, 13 Nov 2019 09:36:40 +0100 Subject: [PATCH 37/40] remove isProd from Gulp script --- .../gulp/tasks/dependencies.js | 25 +++++++++---------- .../gulp/tasks/removeProductionMode.js | 22 ---------------- .../gulp/util/processJs.js | 9 +++---- src/Umbraco.Web.UI.Client/gulpfile.js | 4 --- 4 files changed, 16 insertions(+), 44 deletions(-) delete mode 100644 src/Umbraco.Web.UI.Client/gulp/tasks/removeProductionMode.js diff --git a/src/Umbraco.Web.UI.Client/gulp/tasks/dependencies.js b/src/Umbraco.Web.UI.Client/gulp/tasks/dependencies.js index a9d77b03c6..def956ac9f 100644 --- a/src/Umbraco.Web.UI.Client/gulp/tasks/dependencies.js +++ b/src/Umbraco.Web.UI.Client/gulp/tasks/dependencies.js @@ -259,19 +259,18 @@ function dependencies() { //css, fonts and image files var assetsTask = gulp.src(config.sources.globs.assets, { allowEmpty: true }); - if (global.isProd === true) { - assetsTask = assetsTask.pipe(imagemin([ - imagemin.gifsicle({interlaced: true}), - imagemin.jpegtran({progressive: true}), - imagemin.optipng({optimizationLevel: 5}), - imagemin.svgo({ - plugins: [ - {removeViewBox: true}, - {cleanupIDs: false} - ] - }) - ])); - } + assetsTask = assetsTask.pipe(imagemin([ + imagemin.gifsicle({interlaced: true}), + imagemin.jpegtran({progressive: true}), + imagemin.optipng({optimizationLevel: 5}), + imagemin.svgo({ + plugins: [ + {removeViewBox: true}, + {cleanupIDs: false} + ] + }) + ])); + assetsTask = assetsTask.pipe(gulp.dest(config.root + config.targets.assets)); stream.add(assetsTask); diff --git a/src/Umbraco.Web.UI.Client/gulp/tasks/removeProductionMode.js b/src/Umbraco.Web.UI.Client/gulp/tasks/removeProductionMode.js deleted file mode 100644 index 3481d84e39..0000000000 --- a/src/Umbraco.Web.UI.Client/gulp/tasks/removeProductionMode.js +++ /dev/null @@ -1,22 +0,0 @@ -'use strict'; - -var gulp = require('gulp'); -var through2 = require('through2'); - -function createEmptyStream() { - var pass = through2.obj(); - process.nextTick(pass.end.bind(pass)); - return pass; -} - -/************************** - * Copies all angular JS files into their separate umbraco.*.js file - **************************/ -function removeProductionMode() { - - global.isProd = false; - - return createEmptyStream(); -}; - -module.exports = { removeProductionMode: removeProductionMode }; diff --git a/src/Umbraco.Web.UI.Client/gulp/util/processJs.js b/src/Umbraco.Web.UI.Client/gulp/util/processJs.js index d8e4ca61d1..e3e393b661 100644 --- a/src/Umbraco.Web.UI.Client/gulp/util/processJs.js +++ b/src/Umbraco.Web.UI.Client/gulp/util/processJs.js @@ -23,11 +23,10 @@ module.exports = function (files, out) { // sort files in stream by path or any custom sort comparator task = task.pipe(babel()) .pipe(sort()); - - if (global.isProd === true) { - //in production, embed the templates - task = task.pipe(embedTemplates({ basePath: "./src/", minimize: { loose: true } })) - } + + //in production, embed the templates + task = task.pipe(embedTemplates({ basePath: "./src/", minimize: { loose: true } })) + task = task.pipe(concat(out)) .pipe(wrap('(function(){\n%= body %\n})();')) .pipe(gulp.dest(config.root + config.targets.js)); diff --git a/src/Umbraco.Web.UI.Client/gulpfile.js b/src/Umbraco.Web.UI.Client/gulpfile.js index 3c1c8646fd..1e4dc591ca 100644 --- a/src/Umbraco.Web.UI.Client/gulpfile.js +++ b/src/Umbraco.Web.UI.Client/gulpfile.js @@ -10,8 +10,6 @@ * and then add the exports command to add the new item into the task menu. */ -global.isProd = true; - const { src, dest, series, parallel, lastRun } = require('gulp'); const { dependencies } = require('./gulp/tasks/dependencies'); @@ -20,7 +18,6 @@ const { less } = require('./gulp/tasks/less'); const { testE2e, testUnit } = require('./gulp/tasks/test'); const { views } = require('./gulp/tasks/views'); const { watchTask } = require('./gulp/tasks/watchTask'); -const { removeProductionMode } = require('./gulp/tasks/removeProductionMode'); // Load local overwrites, can be used to overwrite paths in your local setup. var fs = require('fs'); @@ -41,7 +38,6 @@ try { // *********************************************************** exports.build = series(parallel(dependencies, js, less, views), testUnit); exports.dev = series(parallel(dependencies, js, less, views), watchTask); -exports.fastdev = series(removeProductionMode, parallel(dependencies, js, less, views), watchTask); exports.watch = series(watchTask); // exports.runTests = series(js, testUnit); From 88f6ddeae4c3c09f709b998f6f1105bcb8f605ee Mon Sep 17 00:00:00 2001 From: Jeavon Date: Wed, 13 Nov 2019 12:07:11 +0000 Subject: [PATCH 38/40] Code tweaks from PR review - also led to adding logging for Deserialization issues and therefore needing to mock the logger for the tests --- src/Umbraco.Examine/MediaValueSetBuilder.cs | 17 +++++++++++++++-- .../UmbracoExamine/IndexInitializer.cs | 7 ++++++- .../Models/Mapping/EntityMapDefinition.cs | 3 +-- 3 files changed, 22 insertions(+), 5 deletions(-) diff --git a/src/Umbraco.Examine/MediaValueSetBuilder.cs b/src/Umbraco.Examine/MediaValueSetBuilder.cs index 3e5b9865cc..03e7f4944b 100644 --- a/src/Umbraco.Examine/MediaValueSetBuilder.cs +++ b/src/Umbraco.Examine/MediaValueSetBuilder.cs @@ -4,6 +4,7 @@ using System.Collections.Generic; using System.Linq; using Newtonsoft.Json; using Umbraco.Core; +using Umbraco.Core.Logging; using Umbraco.Core.Models; using Umbraco.Core.PropertyEditors; using Umbraco.Core.PropertyEditors.ValueConverters; @@ -16,14 +17,16 @@ namespace Umbraco.Examine { private readonly UrlSegmentProviderCollection _urlSegmentProviders; private readonly IUserService _userService; + private readonly ILogger _logger; public MediaValueSetBuilder(PropertyEditorCollection propertyEditors, UrlSegmentProviderCollection urlSegmentProviders, - IUserService userService) + IUserService userService, ILogger logger) : base(propertyEditors, false) { _urlSegmentProviders = urlSegmentProviders; _userService = userService; + _logger = logger; } /// @@ -40,7 +43,17 @@ namespace Umbraco.Examine if (umbracoFileSource.DetectIsJson()) { - var cropper = JsonConvert.DeserializeObject(m.GetValue(Constants.Conventions.Media.File)); + ImageCropperValue cropper = null; + try + { + cropper = JsonConvert.DeserializeObject( + m.GetValue(Constants.Conventions.Media.File)); + } + catch (Exception ex) + { + _logger.Error(ex, $"Could not Deserialize ImageCropperValue for item with key {m.Key} "); + } + if (cropper != null) { umbracoFilePath = cropper.Src; diff --git a/src/Umbraco.Tests/UmbracoExamine/IndexInitializer.cs b/src/Umbraco.Tests/UmbracoExamine/IndexInitializer.cs index 6c65ae8345..1653de827d 100644 --- a/src/Umbraco.Tests/UmbracoExamine/IndexInitializer.cs +++ b/src/Umbraco.Tests/UmbracoExamine/IndexInitializer.cs @@ -45,7 +45,7 @@ namespace Umbraco.Tests.UmbracoExamine public static MediaIndexPopulator GetMediaIndexRebuilder(PropertyEditorCollection propertyEditors, IMediaService mediaService) { - var mediaValueSetBuilder = new MediaValueSetBuilder(propertyEditors, new UrlSegmentProviderCollection(new[] { new DefaultUrlSegmentProvider() }), GetMockUserService()); + var mediaValueSetBuilder = new MediaValueSetBuilder(propertyEditors, new UrlSegmentProviderCollection(new[] { new DefaultUrlSegmentProvider() }), GetMockUserService(), GetMockLogger()); var mediaIndexDataSource = new MediaIndexPopulator(null, mediaService, mediaValueSetBuilder); return mediaIndexDataSource; } @@ -146,6 +146,11 @@ namespace Umbraco.Tests.UmbracoExamine return mediaTypeServiceMock.Object; } + public static IProfilingLogger GetMockLogger() + { + return new ProfilingLogger(Mock.Of(), Mock.Of()); + } + public static UmbracoContentIndex GetUmbracoIndexer( IProfilingLogger profilingLogger, Directory luceneDir, diff --git a/src/Umbraco.Web/Models/Mapping/EntityMapDefinition.cs b/src/Umbraco.Web/Models/Mapping/EntityMapDefinition.cs index 424054cd6c..f2099f2554 100644 --- a/src/Umbraco.Web/Models/Mapping/EntityMapDefinition.cs +++ b/src/Umbraco.Web/Models/Mapping/EntityMapDefinition.cs @@ -177,9 +177,8 @@ namespace Umbraco.Web.Models.Mapping target.Name = source.Values.ContainsKey("nodeName") ? source.Values["nodeName"] : "[no name]"; - if (source.Values.ContainsKey(UmbracoExamineIndex.UmbracoFileFieldName)) + if (source.Values.TryGetValue(UmbracoExamineIndex.UmbracoFileFieldName, out var umbracoFile)) { - var umbracoFile = source.Values[UmbracoExamineIndex.UmbracoFileFieldName]; if (umbracoFile != null) { target.Name = $"{target.Name} ({umbracoFile})"; From c0dc545c277cef0b0add95dbd09bfed4589c950e Mon Sep 17 00:00:00 2001 From: Bjarke Berg Date: Thu, 14 Nov 2019 13:54:04 +0100 Subject: [PATCH 39/40] Fix for csproj --- src/Umbraco.Web.UI/Umbraco.Web.UI.csproj | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj b/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj index acd521d7c6..65055bd8e4 100644 --- a/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj +++ b/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj @@ -350,9 +350,6 @@ 8400 / http://localhost:8400/ - 8300 - / - http://localhost:8300/ False False @@ -434,4 +431,4 @@ - \ No newline at end of file + From a97e1318913a24002270b15bad65f3ab4bf7f3ae Mon Sep 17 00:00:00 2001 From: Bjarke Berg Date: Thu, 14 Nov 2019 14:00:49 +0100 Subject: [PATCH 40/40] Bump version o 8.6 (8.5 reserved for MB release) --- src/SolutionInfo.cs | 4 ++-- src/Umbraco.Web.UI/Umbraco.Web.UI.csproj | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/SolutionInfo.cs b/src/SolutionInfo.cs index 5614cb8c41..363677b826 100644 --- a/src/SolutionInfo.cs +++ b/src/SolutionInfo.cs @@ -18,5 +18,5 @@ using System.Resources; [assembly: AssemblyVersion("8.0.0")] // these are FYI and changed automatically -[assembly: AssemblyFileVersion("8.4.0")] -[assembly: AssemblyInformationalVersion("8.4.0")] +[assembly: AssemblyFileVersion("8.6.0")] +[assembly: AssemblyInformationalVersion("8.6.0")] diff --git a/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj b/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj index 65055bd8e4..35fa5b8149 100644 --- a/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj +++ b/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj @@ -347,9 +347,9 @@ False True - 8400 + 8600 / - http://localhost:8400/ + http://localhost:8600/ False False