diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index d67ad0fe2836..4cb593a39b7a 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -72,10 +72,10 @@ Great question! The short version goes like this: ![Clone the fork](img/clonefork.png) - * **Switch to the correct branch** - switch to the `v8/contrib` branch + * **Switch to the correct branch** - switch to the `v9/contrib` branch * **Build** - build your fork of Umbraco locally as described in [building Umbraco from source code](BUILD.md) * **Change** - make your changes, experiment, have fun, explore and learn, and don't be afraid. We welcome all contributions and will [happily give feedback](#questions) - * **Commit** - done? Yay! 🎉 **Important:** create a new branch now and name it after the issue you're fixing, we usually follow the format: `temp-12345`. This means it's a temporary branch for the particular issue you're working on, in this case `12345`. When you have a branch, commit your changes. Don't commit to `v8/contrib`, create a new branch first. + * **Commit** - done? Yay! 🎉 **Important:** create a new branch now and name it after the issue you're fixing, we usually follow the format: `temp-12345`. This means it's a temporary branch for the particular issue you're working on, in this case `12345`. When you have a branch, commit your changes. Don't commit to `v9/contrib`, create a new branch first. * **Push** - great, now you can push the changes up to your fork on GitHub * **Create pull request** - exciting! You're ready to show us your changes (or not quite ready, you just need some feedback to progress - you can now make use of GitHub's draft pull request status, detailed [here](https://github.blog/2019-02-14-introducing-draft-pull-requests/)). GitHub has picked up on the new branch you've pushed and will offer to create a Pull Request. Click that green button and away you go. @@ -173,7 +173,7 @@ To find the general areas for something you're looking to fix or improve, have a ### Which branch should I target for my contributions? -We like to use [Gitflow as much as possible](https://jeffkreeftmeijer.com/git-flow/), but don't worry if you are not familiar with it. The most important thing you need to know is that when you fork the Umbraco repository, the default branch is set to something, usually `v8/contrib`. If you are working on v8, this is the branch you should be targetting. For v7 contributions, please target 'v7/dev'. +We like to use [Gitflow as much as possible](https://jeffkreeftmeijer.com/git-flow/), but don't worry if you are not familiar with it. The most important thing you need to know is that when you fork the Umbraco repository, the default branch is set to something, usually `v9/contrib`. If you are working on v9, this is the branch you should be targetting. For v8 contributions, please target 'v8/contrib' Please note: we are no longer accepting features for v7 but will continue to merge bug fixes as and when they arise. @@ -199,10 +199,10 @@ Then when you want to get the changes from the main repository: ``` git fetch upstream -git rebase upstream/v8/contrib +git rebase upstream/v9/contrib ``` -In this command we're syncing with the `v8/contrib` branch, but you can of course choose another one if needed. +In this command we're syncing with the `v9/contrib` branch, but you can of course choose another one if needed. (More info on how this works: [http://robots.thoughtbot.com/post/5133345960/keeping-a-git-fork-updated](http://robots.thoughtbot.com/post/5133345960/keeping-a-git-fork-updated)) diff --git a/.vscode/launch.json b/.vscode/launch.json index 1c7f8b11d781..ab97269d1f94 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -14,6 +14,7 @@ "args": [], "cwd": "${workspaceFolder}/src/Umbraco.Web.UI", "stopAtEntry": false, + "requireExactSource": false, // Enable launching a web browser when ASP.NET Core starts. For more information: https://aka.ms/VSCode-CS-LaunchJson-WebBrowser "serverReadyAction": { "action": "openExternally", diff --git a/NuGet.Config b/NuGet.Config deleted file mode 100644 index a0d5bc04818d..000000000000 --- a/NuGet.Config +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/src/Umbraco.Core/HealthChecks/Checks/Security/BaseHttpHeaderCheck.cs b/src/Umbraco.Core/HealthChecks/Checks/Security/BaseHttpHeaderCheck.cs index a3e861e18041..b7e5e867c467 100644 --- a/src/Umbraco.Core/HealthChecks/Checks/Security/BaseHttpHeaderCheck.cs +++ b/src/Umbraco.Core/HealthChecks/Checks/Security/BaseHttpHeaderCheck.cs @@ -1,4 +1,4 @@ -// Copyright (c) Umbraco. +// Copyright (c) Umbraco. // See LICENSE for more details. using System; @@ -20,12 +20,26 @@ namespace Umbraco.Cms.Core.HealthChecks.Checks.Security public abstract class BaseHttpHeaderCheck : HealthCheck { private readonly IHostingEnvironment _hostingEnvironment; + private readonly ILocalizedTextService _textService; private readonly string _header; - private readonly string _value; private readonly string _localizedTextPrefix; private readonly bool _metaTagOptionAvailable; private static HttpClient s_httpClient; + [Obsolete("Use ctor without value.")] + protected BaseHttpHeaderCheck( + IHostingEnvironment hostingEnvironment, + ILocalizedTextService textService, + string header, + string value, + string localizedTextPrefix, + bool metaTagOptionAvailable) :this(hostingEnvironment, textService, header, localizedTextPrefix, metaTagOptionAvailable) + { + + } + + [Obsolete("Save ILocalizedTextService in a field on the super class instead of using this")] + protected ILocalizedTextService LocalizedTextService => _textService; /// /// Initializes a new instance of the class. /// @@ -33,26 +47,18 @@ protected BaseHttpHeaderCheck( IHostingEnvironment hostingEnvironment, ILocalizedTextService textService, string header, - string value, string localizedTextPrefix, bool metaTagOptionAvailable) { - LocalizedTextService = textService ?? throw new ArgumentNullException(nameof(textService)); + _textService = textService ?? throw new ArgumentNullException(nameof(textService)); _hostingEnvironment = hostingEnvironment; _header = header; - _value = value; _localizedTextPrefix = localizedTextPrefix; _metaTagOptionAvailable = metaTagOptionAvailable; } private static HttpClient HttpClient => s_httpClient ??= new HttpClient(); - - /// - /// Gets the localized text service. - /// - protected ILocalizedTextService LocalizedTextService { get; } - /// /// Gets a link to an external read more page. /// @@ -95,12 +101,12 @@ protected async Task CheckForHeader() } message = success - ? LocalizedTextService.Localize($"healthcheck", $"{_localizedTextPrefix}CheckHeaderFound") - : LocalizedTextService.Localize($"healthcheck", $"{_localizedTextPrefix}CheckHeaderNotFound"); + ? _textService.Localize($"healthcheck", $"{_localizedTextPrefix}CheckHeaderFound") + : _textService.Localize($"healthcheck", $"{_localizedTextPrefix}CheckHeaderNotFound"); } catch (Exception ex) { - message = LocalizedTextService.Localize("healthcheck","healthCheckInvalidUrl", new[] { url.ToString(), ex.Message }); + message = _textService.Localize("healthcheck","healthCheckInvalidUrl", new[] { url.ToString(), ex.Message }); } return diff --git a/src/Umbraco.Core/HealthChecks/Checks/Security/ClickJackingCheck.cs b/src/Umbraco.Core/HealthChecks/Checks/Security/ClickJackingCheck.cs index 957ee0b71507..8586989f32a8 100644 --- a/src/Umbraco.Core/HealthChecks/Checks/Security/ClickJackingCheck.cs +++ b/src/Umbraco.Core/HealthChecks/Checks/Security/ClickJackingCheck.cs @@ -1,4 +1,4 @@ -// Copyright (c) Umbraco. +// Copyright (c) Umbraco. // See LICENSE for more details. using Umbraco.Cms.Core.Hosting; @@ -20,7 +20,7 @@ public class ClickJackingCheck : BaseHttpHeaderCheck /// Initializes a new instance of the class. /// public ClickJackingCheck(IHostingEnvironment hostingEnvironment, ILocalizedTextService textService) - : base(hostingEnvironment, textService, "X-Frame-Options", "sameorigin", "clickJacking", true) + : base(hostingEnvironment, textService, "X-Frame-Options", "clickJacking", true) { } diff --git a/src/Umbraco.Core/HealthChecks/Checks/Security/ExcessiveHeadersCheck.cs b/src/Umbraco.Core/HealthChecks/Checks/Security/ExcessiveHeadersCheck.cs index cdd8a0493f04..d5eac030389d 100644 --- a/src/Umbraco.Core/HealthChecks/Checks/Security/ExcessiveHeadersCheck.cs +++ b/src/Umbraco.Core/HealthChecks/Checks/Security/ExcessiveHeadersCheck.cs @@ -1,4 +1,4 @@ -// Copyright (c) Umbraco. +// Copyright (c) Umbraco. // See LICENSE for more details. using System; @@ -53,7 +53,7 @@ private async Task CheckForHeaders() { string message; var success = false; - var url = _hostingEnvironment.ApplicationMainUrl.GetLeftPart(UriPartial.Authority);; + var url = _hostingEnvironment.ApplicationMainUrl.GetLeftPart(UriPartial.Authority); // Access the site home page and check for the headers var request = new HttpRequestMessage(HttpMethod.Head, url); @@ -65,7 +65,7 @@ private async Task CheckForHeaders() var headersToCheckFor = new List {"Server", "X-Powered-By", "X-AspNet-Version", "X-AspNetMvc-Version" }; // Ignore if server header is present and it's set to cloudflare - if (allHeaders.InvariantContains("Server") && response.Headers.TryGetValues("Server", out var serverHeaders) && serverHeaders.ToString().InvariantEquals("cloudflare")) + if (allHeaders.InvariantContains("Server") && response.Headers.TryGetValues("Server", out var serverHeaders) && serverHeaders.FirstOrDefault().InvariantEquals("cloudflare")) { headersToCheckFor.Remove("Server"); } diff --git a/src/Umbraco.Core/HealthChecks/Checks/Security/HstsCheck.cs b/src/Umbraco.Core/HealthChecks/Checks/Security/HstsCheck.cs index b2166b88bd0d..7902f4e3f873 100644 --- a/src/Umbraco.Core/HealthChecks/Checks/Security/HstsCheck.cs +++ b/src/Umbraco.Core/HealthChecks/Checks/Security/HstsCheck.cs @@ -1,4 +1,4 @@ -// Copyright (c) Umbraco. +// Copyright (c) Umbraco. // See LICENSE for more details. using Umbraco.Cms.Core.Hosting; @@ -27,7 +27,7 @@ public class HstsCheck : BaseHttpHeaderCheck /// but then you should include subdomains and I wouldn't suggest to do that for Umbraco-sites. /// public HstsCheck(IHostingEnvironment hostingEnvironment, ILocalizedTextService textService) - : base(hostingEnvironment, textService, "Strict-Transport-Security", "max-age=10886400", "hSTS", true) + : base(hostingEnvironment, textService, "Strict-Transport-Security", "hSTS", true) { } diff --git a/src/Umbraco.Core/HealthChecks/Checks/Security/NoSniffCheck.cs b/src/Umbraco.Core/HealthChecks/Checks/Security/NoSniffCheck.cs index 035733e4ee01..78ee2c0e124f 100644 --- a/src/Umbraco.Core/HealthChecks/Checks/Security/NoSniffCheck.cs +++ b/src/Umbraco.Core/HealthChecks/Checks/Security/NoSniffCheck.cs @@ -1,4 +1,4 @@ -// Copyright (c) Umbraco. +// Copyright (c) Umbraco. // See LICENSE for more details. using Umbraco.Cms.Core.Hosting; @@ -20,7 +20,7 @@ public class NoSniffCheck : BaseHttpHeaderCheck /// Initializes a new instance of the class. /// public NoSniffCheck(IHostingEnvironment hostingEnvironment, ILocalizedTextService textService) - : base(hostingEnvironment, textService, "X-Content-Type-Options", "nosniff", "noSniff", false) + : base(hostingEnvironment, textService, "X-Content-Type-Options", "noSniff", false) { } diff --git a/src/Umbraco.Core/HealthChecks/Checks/Security/XssProtectionCheck.cs b/src/Umbraco.Core/HealthChecks/Checks/Security/XssProtectionCheck.cs index 6c05c39f4646..570ca8002d74 100644 --- a/src/Umbraco.Core/HealthChecks/Checks/Security/XssProtectionCheck.cs +++ b/src/Umbraco.Core/HealthChecks/Checks/Security/XssProtectionCheck.cs @@ -1,4 +1,4 @@ -// Copyright (c) Umbraco. +// Copyright (c) Umbraco. // See LICENSE for more details. using Umbraco.Cms.Core.Hosting; @@ -27,7 +27,7 @@ public class XssProtectionCheck : BaseHttpHeaderCheck /// but then you should include subdomains and I wouldn't suggest to do that for Umbraco-sites. /// public XssProtectionCheck(IHostingEnvironment hostingEnvironment, ILocalizedTextService textService) - : base(hostingEnvironment, textService, "X-XSS-Protection", "1; mode=block", "xssProtection", true) + : base(hostingEnvironment, textService, "X-XSS-Protection", "xssProtection", true) { } diff --git a/src/Umbraco.Core/IO/DefaultViewContentProvider.cs b/src/Umbraco.Core/IO/DefaultViewContentProvider.cs new file mode 100644 index 000000000000..7c4225597150 --- /dev/null +++ b/src/Umbraco.Core/IO/DefaultViewContentProvider.cs @@ -0,0 +1,62 @@ +using System.Text; +using Umbraco.Extensions; + +namespace Umbraco.Cms.Core.IO +{ + public class DefaultViewContentProvider : IDefaultViewContentProvider + { + public string GetDefaultFileContent(string layoutPageAlias = null, string modelClassName = null, string modelNamespace = null, string modelNamespaceAlias = null) + { + var content = new StringBuilder(); + + if (string.IsNullOrWhiteSpace(modelNamespaceAlias)) + modelNamespaceAlias = "ContentModels"; + + // either + // @inherits Umbraco.Web.Mvc.UmbracoViewPage + // @inherits Umbraco.Web.Mvc.UmbracoViewPage + content.AppendLine("@using Umbraco.Cms.Web.Common.PublishedModels;"); + content.Append("@inherits Umbraco.Cms.Web.Common.Views.UmbracoViewPage"); + if (modelClassName.IsNullOrWhiteSpace() == false) + { + content.Append("<"); + if (modelNamespace.IsNullOrWhiteSpace() == false) + { + content.Append(modelNamespaceAlias); + content.Append("."); + } + content.Append(modelClassName); + content.Append(">"); + } + content.Append("\r\n"); + + // if required, add + // @using ContentModels = ModelNamespace; + if (modelClassName.IsNullOrWhiteSpace() == false && modelNamespace.IsNullOrWhiteSpace() == false) + { + content.Append("@using "); + content.Append(modelNamespaceAlias); + content.Append(" = "); + content.Append(modelNamespace); + content.Append(";\r\n"); + } + + // either + // Layout = null; + // Layout = "layoutPage.cshtml"; + content.Append("@{\r\n\tLayout = "); + if (layoutPageAlias.IsNullOrWhiteSpace()) + { + content.Append("null"); + } + else + { + content.Append("\""); + content.Append(layoutPageAlias); + content.Append(".cshtml\""); + } + content.Append(";\r\n}"); + return content.ToString(); + } + } +} diff --git a/src/Umbraco.Core/IO/IDefaultViewContentProvider.cs b/src/Umbraco.Core/IO/IDefaultViewContentProvider.cs new file mode 100644 index 000000000000..8c1a775d7ce8 --- /dev/null +++ b/src/Umbraco.Core/IO/IDefaultViewContentProvider.cs @@ -0,0 +1,8 @@ +namespace Umbraco.Cms.Core.IO +{ + public interface IDefaultViewContentProvider + { + string GetDefaultFileContent(string layoutPageAlias = null, string modelClassName = null, + string modelNamespace = null, string modelNamespaceAlias = null); + } +} diff --git a/src/Umbraco.Core/IO/IViewHelper.cs b/src/Umbraco.Core/IO/IViewHelper.cs new file mode 100644 index 000000000000..d53dcbf2b939 --- /dev/null +++ b/src/Umbraco.Core/IO/IViewHelper.cs @@ -0,0 +1,13 @@ +using Umbraco.Cms.Core.Models; + +namespace Umbraco.Cms.Core.IO +{ + public interface IViewHelper + { + bool ViewExists(ITemplate t); + string GetFileContents(ITemplate t); + string CreateView(ITemplate t, bool overWrite = false); + string UpdateViewFile(ITemplate t, string currentAlias = null); + string ViewPath(string alias); + } +} diff --git a/src/Umbraco.Core/IO/ViewHelper.cs b/src/Umbraco.Core/IO/ViewHelper.cs index 258c4a7f640d..56a276080227 100644 --- a/src/Umbraco.Core/IO/ViewHelper.cs +++ b/src/Umbraco.Core/IO/ViewHelper.cs @@ -2,26 +2,34 @@ using System.IO; using System.Linq; using System.Text; +using Microsoft.Extensions.DependencyInjection; using Umbraco.Cms.Core.Models; +using Umbraco.Cms.Web.Common.DependencyInjection; using Umbraco.Extensions; namespace Umbraco.Cms.Core.IO { - public class ViewHelper + public class ViewHelper : IViewHelper { private readonly IFileSystem _viewFileSystem; + private readonly IDefaultViewContentProvider _defaultViewContentProvider; + [Obsolete("Use ctor with all params")] public ViewHelper(IFileSystem viewFileSystem) { - if (viewFileSystem == null) throw new ArgumentNullException(nameof(viewFileSystem)); - _viewFileSystem = viewFileSystem; + _viewFileSystem = viewFileSystem ?? throw new ArgumentNullException(nameof(viewFileSystem)); + _defaultViewContentProvider = StaticServiceProvider.Instance.GetRequiredService(); } - internal bool ViewExists(ITemplate t) + public ViewHelper(FileSystems fileSystems, IDefaultViewContentProvider defaultViewContentProvider) { - return _viewFileSystem.FileExists(ViewPath(t.Alias)); + _viewFileSystem = fileSystems.MvcViewsFileSystem ?? throw new ArgumentNullException(nameof(fileSystems)); + _defaultViewContentProvider = defaultViewContentProvider ?? throw new ArgumentNullException(nameof(defaultViewContentProvider)); } + public bool ViewExists(ITemplate t) => _viewFileSystem.FileExists(ViewPath(t.Alias)); + + public string GetFileContents(ITemplate t) { var viewContent = ""; @@ -60,58 +68,13 @@ public string CreateView(ITemplate t, bool overWrite = false) return viewContent; } - public static string GetDefaultFileContent(string layoutPageAlias = null, string modelClassName = null, string modelNamespace = null, string modelNamespaceAlias = null) + [Obsolete("Inject IDefaultViewContentProvider instead")] + public static string GetDefaultFileContent(string layoutPageAlias = null, string modelClassName = null, + string modelNamespace = null, string modelNamespaceAlias = null) { - var content = new StringBuilder(); - - if (string.IsNullOrWhiteSpace(modelNamespaceAlias)) - modelNamespaceAlias = "ContentModels"; - - // either - // @inherits Umbraco.Web.Mvc.UmbracoViewPage - // @inherits Umbraco.Web.Mvc.UmbracoViewPage - content.AppendLine("@using Umbraco.Cms.Web.Common.PublishedModels;"); - content.Append("@inherits Umbraco.Cms.Web.Common.Views.UmbracoViewPage"); - if (modelClassName.IsNullOrWhiteSpace() == false) - { - content.Append("<"); - if (modelNamespace.IsNullOrWhiteSpace() == false) - { - content.Append(modelNamespaceAlias); - content.Append("."); - } - content.Append(modelClassName); - content.Append(">"); - } - content.Append("\r\n"); - - // if required, add - // @using ContentModels = ModelNamespace; - if (modelClassName.IsNullOrWhiteSpace() == false && modelNamespace.IsNullOrWhiteSpace() == false) - { - content.Append("@using "); - content.Append(modelNamespaceAlias); - content.Append(" = "); - content.Append(modelNamespace); - content.Append(";\r\n"); - } - - // either - // Layout = null; - // Layout = "layoutPage.cshtml"; - content.Append("@{\r\n\tLayout = "); - if (layoutPageAlias.IsNullOrWhiteSpace()) - { - content.Append("null"); - } - else - { - content.Append("\""); - content.Append(layoutPageAlias); - content.Append(".cshtml\""); - } - content.Append(";\r\n}"); - return content.ToString(); + var viewContentProvider = StaticServiceProvider.Instance.GetRequiredService(); + return viewContentProvider.GetDefaultFileContent(layoutPageAlias, modelClassName, modelNamespace, + modelNamespaceAlias); } private string SaveTemplateToFile(ITemplate template) @@ -157,12 +120,12 @@ public string ViewPath(string alias) return _viewFileSystem.GetRelativePath(alias.Replace(" ", "") + ".cshtml"); } - private static string EnsureInheritedLayout(ITemplate template) + private string EnsureInheritedLayout(ITemplate template) { var design = template.Content; if (string.IsNullOrEmpty(design)) - design = GetDefaultFileContent(template.MasterTemplateAlias); + design = _defaultViewContentProvider.GetDefaultFileContent(template.MasterTemplateAlias); return design; } diff --git a/src/Umbraco.Examine.Lucene/BackOfficeExamineSearcher.cs b/src/Umbraco.Examine.Lucene/BackOfficeExamineSearcher.cs index a77bee7c4426..b8a942edc58e 100644 --- a/src/Umbraco.Examine.Lucene/BackOfficeExamineSearcher.cs +++ b/src/Umbraco.Examine.Lucene/BackOfficeExamineSearcher.cs @@ -145,9 +145,7 @@ public IEnumerable Search(string query, UmbracoEntityTypes entity totalFound = result.TotalItemCount; - var pagedResult = result.Skip(Convert.ToInt32(pageIndex)); - - return pagedResult; + return result; } private bool BuildQuery(StringBuilder sb, string query, string searchFrom, List fields, string type) diff --git a/src/Umbraco.Examine.Lucene/Umbraco.Examine.Lucene.csproj b/src/Umbraco.Examine.Lucene/Umbraco.Examine.Lucene.csproj index 118a895073c6..1c12ad5be326 100644 --- a/src/Umbraco.Examine.Lucene/Umbraco.Examine.Lucene.csproj +++ b/src/Umbraco.Examine.Lucene/Umbraco.Examine.Lucene.csproj @@ -21,7 +21,7 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/src/Umbraco.Infrastructure/DependencyInjection/UmbracoBuilder.FileSystems.cs b/src/Umbraco.Infrastructure/DependencyInjection/UmbracoBuilder.FileSystems.cs index edb8033f3dc4..6582cfb0c6e6 100644 --- a/src/Umbraco.Infrastructure/DependencyInjection/UmbracoBuilder.FileSystems.cs +++ b/src/Umbraco.Infrastructure/DependencyInjection/UmbracoBuilder.FileSystems.cs @@ -39,6 +39,9 @@ internal static IUmbracoBuilder AddFileSystems(this IUmbracoBuilder builder) // register the scheme for media paths builder.Services.AddUnique(); + builder.Services.AddUnique(); + builder.Services.AddUnique(); + builder.SetMediaFileSystem(factory => { IIOHelper ioHelper = factory.GetRequiredService(); diff --git a/src/Umbraco.Infrastructure/DependencyInjection/UmbracoBuilder.Uniques.cs b/src/Umbraco.Infrastructure/DependencyInjection/UmbracoBuilder.Uniques.cs index b311b1f0dacc..e3839e152b9a 100644 --- a/src/Umbraco.Infrastructure/DependencyInjection/UmbracoBuilder.Uniques.cs +++ b/src/Umbraco.Infrastructure/DependencyInjection/UmbracoBuilder.Uniques.cs @@ -27,6 +27,19 @@ public static IUmbracoBuilder SetCultureDictionaryFactory(this IUmbracoBuilde return builder; } + /// + /// Sets the default view content provider + /// + /// The type of the provider. + /// The builder. + /// + public static IUmbracoBuilder SetDefaultViewContentProvider(this IUmbracoBuilder builder) + where T : class, IDefaultViewContentProvider + { + builder.Services.AddUnique(); + return builder; + } + /// /// Sets the culture dictionary factory. /// diff --git a/src/Umbraco.Infrastructure/Examine/ExamineUmbracoIndexingHandler.cs b/src/Umbraco.Infrastructure/Examine/ExamineUmbracoIndexingHandler.cs index 4fbbb35a6d82..0d881888a14d 100644 --- a/src/Umbraco.Infrastructure/Examine/ExamineUmbracoIndexingHandler.cs +++ b/src/Umbraco.Infrastructure/Examine/ExamineUmbracoIndexingHandler.cs @@ -194,9 +194,8 @@ public void DeleteDocumentsForContentTypes(IReadOnlyCollection removedConte .Field("nodeType", id.ToInvariantString()) .Execute(QueryOptions.SkipTake(page * pageSize, pageSize)); total = results.TotalItemCount; - var paged = results.Skip(page * pageSize); - - foreach (ISearchResult item in paged) + + foreach (ISearchResult item in results) { if (int.TryParse(item.Id, NumberStyles.Integer, CultureInfo.InvariantCulture, out int contentId)) { diff --git a/src/Umbraco.Infrastructure/Install/InstallSteps/NewInstallStep.cs b/src/Umbraco.Infrastructure/Install/InstallSteps/NewInstallStep.cs index 73b9d702b75c..4ef8fa4e284e 100644 --- a/src/Umbraco.Infrastructure/Install/InstallSteps/NewInstallStep.cs +++ b/src/Umbraco.Infrastructure/Install/InstallSteps/NewInstallStep.cs @@ -117,7 +117,8 @@ public override object ViewModel { minCharLength = _passwordConfiguration.RequiredLength, minNonAlphaNumericLength = _passwordConfiguration.GetMinNonAlphaNumericChars(), - quickInstallAvailable = DatabaseConfigureStep.IsSqlCeAvailable() + quickInstallAvailable = DatabaseConfigureStep.IsSqlCeAvailable() || DatabaseConfigureStep.IsLocalDbAvailable(), + customInstallAvailable = !GetInstallState().HasFlag(InstallState.ConnectionStringConfigured) }; } } diff --git a/src/Umbraco.Infrastructure/Mail/EmailSender.cs b/src/Umbraco.Infrastructure/Mail/EmailSender.cs index e5fbde2aacf0..4ca3506fa97c 100644 --- a/src/Umbraco.Infrastructure/Mail/EmailSender.cs +++ b/src/Umbraco.Infrastructure/Mail/EmailSender.cs @@ -1,10 +1,15 @@ // Copyright (c) Umbraco. // See LICENSE for more details. +using System; +using System.IO; using System.Net.Mail; using System.Threading.Tasks; +using MailKit.Net.Smtp; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; +using MimeKit; +using MimeKit.IO; using Umbraco.Cms.Core.Configuration.Models; using Umbraco.Cms.Core.Events; using Umbraco.Cms.Core.Mail; @@ -70,12 +75,56 @@ private async Task SendAsyncInternal(EmailMessage message, string emailType, boo } } - if (_globalSettings.IsSmtpServerConfigured == false) + var isPickupDirectoryConfigured = !string.IsNullOrWhiteSpace(_globalSettings.Smtp?.PickupDirectoryLocation); + + if (_globalSettings.IsSmtpServerConfigured == false && !isPickupDirectoryConfigured) { _logger.LogDebug("Could not send email for {Subject}. It was not handled by a notification handler and there is no SMTP configured.", message.Subject); return; } + if (isPickupDirectoryConfigured && !string.IsNullOrWhiteSpace(_globalSettings.Smtp?.From)) + { + // The following code snippet is the recommended way to handle PickupDirectoryLocation. + // See more https://github.com/jstedfast/MailKit/blob/master/FAQ.md#q-how-can-i-send-email-to-a-specifiedpickupdirectory + do { + var path = Path.Combine(_globalSettings.Smtp?.PickupDirectoryLocation, Guid.NewGuid () + ".eml"); + Stream stream; + + try + { + stream = File.Open(path, FileMode.CreateNew); + } + catch (IOException) + { + if (File.Exists(path)) + { + continue; + } + throw; + } + + try { + using (stream) + { + using var filtered = new FilteredStream(stream); + filtered.Add(new SmtpDataFilter()); + + FormatOptions options = FormatOptions.Default.Clone(); + options.NewLineFormat = NewLineFormat.Dos; + + await message.ToMimeMessage(_globalSettings.Smtp?.From).WriteToAsync(options, filtered); + filtered.Flush(); + return; + + } + } catch { + File.Delete(path); + throw; + } + } while (true); + } + using var client = new SmtpClient(); await client.ConnectAsync(_globalSettings.Smtp.Host, diff --git a/src/Umbraco.Infrastructure/Persistence/Repositories/Implement/TemplateRepository.cs b/src/Umbraco.Infrastructure/Persistence/Repositories/Implement/TemplateRepository.cs index b0cabe53128d..52ecd1f7791e 100644 --- a/src/Umbraco.Infrastructure/Persistence/Repositories/Implement/TemplateRepository.cs +++ b/src/Umbraco.Infrastructure/Persistence/Repositories/Implement/TemplateRepository.cs @@ -29,15 +29,15 @@ internal class TemplateRepository : EntityRepositoryBase, ITempl private readonly IIOHelper _ioHelper; private readonly IShortStringHelper _shortStringHelper; private readonly IFileSystem _viewsFileSystem; - private readonly ViewHelper _viewHelper; + private readonly IViewHelper _viewHelper; - public TemplateRepository(IScopeAccessor scopeAccessor, AppCaches cache, ILogger logger, FileSystems fileSystems, IIOHelper ioHelper, IShortStringHelper shortStringHelper) + public TemplateRepository(IScopeAccessor scopeAccessor, AppCaches cache, ILogger logger, FileSystems fileSystems, IIOHelper ioHelper, IShortStringHelper shortStringHelper, IViewHelper viewHelper) : base(scopeAccessor, cache, logger) { _ioHelper = ioHelper; _shortStringHelper = shortStringHelper; _viewsFileSystem = fileSystems.MvcViewsFileSystem; - _viewHelper = new ViewHelper(_viewsFileSystem); + _viewHelper = viewHelper; } protected override IRepositoryCachePolicy CreateCachePolicy() => diff --git a/src/Umbraco.Infrastructure/PropertyEditors/BlockEditorPropertyEditor.cs b/src/Umbraco.Infrastructure/PropertyEditors/BlockEditorPropertyEditor.cs index 550a64b14da6..93e7d5be5067 100644 --- a/src/Umbraco.Infrastructure/PropertyEditors/BlockEditorPropertyEditor.cs +++ b/src/Umbraco.Infrastructure/PropertyEditors/BlockEditorPropertyEditor.cs @@ -7,7 +7,6 @@ using System.Linq; using Microsoft.Extensions.Logging; using Newtonsoft.Json; -using Umbraco.Cms.Core.Hosting; using Umbraco.Cms.Core.IO; using Umbraco.Cms.Core.Models; using Umbraco.Cms.Core.Models.Blocks; @@ -264,7 +263,7 @@ public IEnumerable Validate(object value, string valueType, ob _textService.Localize("validation", "entriesShort", new[] { validationLimit.Min.ToString(), - (validationLimit.Min - blockEditorData.Layout.Count()).ToString() + (validationLimit.Min - (blockEditorData?.Layout.Count() ?? 0)).ToString() }), new[] { "minCount" }); } diff --git a/src/Umbraco.Infrastructure/PublishedContentQuery.cs b/src/Umbraco.Infrastructure/PublishedContentQuery.cs index e149e092d849..d8119f919c71 100644 --- a/src/Umbraco.Infrastructure/PublishedContentQuery.cs +++ b/src/Umbraco.Infrastructure/PublishedContentQuery.cs @@ -295,7 +295,7 @@ public IEnumerable Search(string term, int skip, int take totalRecords = results.TotalItemCount; return new CultureContextualSearchResults( - results.Skip(skip).ToPublishedSearchResults(_publishedSnapshot.Content), _variationContextAccessor, + results.ToPublishedSearchResults(_publishedSnapshot.Content), _variationContextAccessor, culture); } @@ -324,7 +324,7 @@ public IEnumerable Search(IQueryExecutor query, int skip, totalRecords = results.TotalItemCount; - return results.Skip(skip).ToPublishedSearchResults(_publishedSnapshot); + return results.ToPublishedSearchResults(_publishedSnapshot); } /// diff --git a/src/Umbraco.Infrastructure/Umbraco.Infrastructure.csproj b/src/Umbraco.Infrastructure/Umbraco.Infrastructure.csproj index 1d2f8bc505f9..6b5e769c48e1 100644 --- a/src/Umbraco.Infrastructure/Umbraco.Infrastructure.csproj +++ b/src/Umbraco.Infrastructure/Umbraco.Infrastructure.csproj @@ -1,4 +1,4 @@ - + netstandard2.0 @@ -45,12 +45,12 @@ - + - + all diff --git a/src/Umbraco.PublishedCache.NuCache/ContentStore.cs b/src/Umbraco.PublishedCache.NuCache/ContentStore.cs index 42aec80e51a4..240e6c8861a6 100644 --- a/src/Umbraco.PublishedCache.NuCache/ContentStore.cs +++ b/src/Umbraco.PublishedCache.NuCache/ContentStore.cs @@ -528,7 +528,7 @@ private bool BuildKit(ContentNodeKit kit, out LinkedNode parent) parent = GetParentLink(kit.Node, null); if (parent == null) { - _logger.LogWarning("Skip item id={kit.Node.Id}, could not find parent id={kit.Node.ParentContentId}.", kit.Node.Id, kit.Node.ParentContentId); + _logger.LogWarning("Skip item id={kitNodeId}, could not find parent id={kitNodeParentContentId}.", kit.Node.Id, kit.Node.ParentContentId); return false; } @@ -537,21 +537,21 @@ private bool BuildKit(ContentNodeKit kit, out LinkedNode parent) // because the data sort operation is by path. if (parent.Value == null) { - _logger.LogWarning("Skip item id={kit.Node.Id}, no Data assigned for linked node with path {kit.Node.Path} and parent id {kit.Node.ParentContentId}. This can indicate data corruption for the Path value for node {kit.Node.Id}. See the Health Check dashboard in Settings to resolve data integrity issues.", kit.Node.Id, kit.Node.ParentContentId); + _logger.LogWarning("Skip item id={kitNodeId}, no Data assigned for linked node with path {kitNodePath} and parent id {kitNodeParentContentId}. This can indicate data corruption for the Path value for node {kitNodeId}. See the Health Check dashboard in Settings to resolve data integrity issues.", kit.Node.Id, kit.Node.Path, kit.Node.ParentContentId, kit.Node.Id); return false; } // make sure the kit is valid if (kit.DraftData == null && kit.PublishedData == null) { - _logger.LogWarning("Skip item id={kit.Node.Id}, both draft and published data are null.", kit.Node.Id); + _logger.LogWarning("Skip item id={kitNodeId}, both draft and published data are null.", kit.Node.Id); return false; } // unknown = bad if (_contentTypesById.TryGetValue(kit.ContentTypeId, out var link) == false || link.Value == null) { - _logger.LogWarning("Skip item id={kit.Node.Id}, could not find content type id={kit.ContentTypeId}.", kit.Node.Id, kit.ContentTypeId); + _logger.LogWarning("Skip item id={kitNodeId}, could not find content type id={kitContentTypeId}.", kit.Node.Id, kit.ContentTypeId); return false; } @@ -727,7 +727,7 @@ public bool SetAllFastSortedLocked(IEnumerable kits, bool fromDb previousNode = null; // there is no previous sibling } - _logger.LogDebug("Set {thisNode.Id} with parent {thisNode.ParentContentId}", thisNode.Id, thisNode.ParentContentId); + _logger.LogDebug("Set {thisNodeId} with parent {thisNodeParentContentId}", thisNode.Id, thisNode.ParentContentId); SetValueLocked(_contentNodes, thisNode.Id, thisNode); // if we are initializing from the database source ensure the local db is updated @@ -784,7 +784,7 @@ public bool SetAllLocked(IEnumerable kits) ok = false; continue; // skip that one } - _logger.LogDebug("Set {kit.Node.Id} with parent {kit.Node.ParentContentId}", kit.Node.Id, kit.Node.ParentContentId); + _logger.LogDebug("Set {kitNodeId} with parent {kitNodeParentContentId}", kit.Node.Id, kit.Node.ParentContentId); SetValueLocked(_contentNodes, kit.Node.Id, kit.Node); if (_localDb != null) RegisterChange(kit.Node.Id, kit); diff --git a/src/Umbraco.Tests.AcceptanceTest/cypress/integration/Languages/languages.ts b/src/Umbraco.Tests.AcceptanceTest/cypress/integration/Languages/languages.ts new file mode 100644 index 000000000000..123109816482 --- /dev/null +++ b/src/Umbraco.Tests.AcceptanceTest/cypress/integration/Languages/languages.ts @@ -0,0 +1,38 @@ +/// +context('Languages', () => { + + beforeEach(() => { + cy.umbracoLogin(Cypress.env('username'), Cypress.env('password'), false); + }); + + it('Deletes language', () => { + // Setup + const language1 = 'da'; + const language2 = 'en-GB'; + cy.umbracoEnsureLanguageNotExists(language1); + cy.umbracoEnsureLanguageNotExists(language2); + cy.umbracoCreateLanguage(language1, true, '1'); + cy.umbracoCreateLanguage(language2, true, '1'); + cy.umbracoSection('settings'); + + // Enter language tree and select the language we just created + cy.umbracoTreeItem('settings', ['Languages']).click(); + + // Assert there are 3 languages + cy.get('tbody > tr').should('have.length', 3); + + // Delete the Danish language + cy.get('tr').contains('Danish').parents('tr').within(() => { + cy.get('umb-button[label-key="general_delete"]').click() + }); + cy.umbracoButtonByLabelKey('contentTypeEditor_yesDelete').click(); + + // Assert there is only 2 language + cy.get('tbody > tr').should('have.length', 3); + + // Cleanup + cy.umbracoEnsureLanguageNotExists(language1); + cy.umbracoEnsureLanguageNotExists(language2); + }); + +}); \ No newline at end of file diff --git a/src/Umbraco.Web.BackOffice/Controllers/ExamineManagementController.cs b/src/Umbraco.Web.BackOffice/Controllers/ExamineManagementController.cs index de3125ad6416..008582b6b3b8 100644 --- a/src/Umbraco.Web.BackOffice/Controllers/ExamineManagementController.cs +++ b/src/Umbraco.Web.BackOffice/Controllers/ExamineManagementController.cs @@ -91,12 +91,10 @@ public ActionResult GetSearchResults(string searcherName, string return SearchResults.Empty(); } - var pagedResults = results.Skip(pageIndex * pageSize); - return new SearchResults { TotalRecords = results.TotalItemCount, - Results = pagedResults.Select(x => new SearchResult + Results = results.Select(x => new SearchResult { Id = x.Id, Score = x.Score, diff --git a/src/Umbraco.Web.BackOffice/Controllers/MediaController.cs b/src/Umbraco.Web.BackOffice/Controllers/MediaController.cs index d54bd7a093aa..14a90805864e 100644 --- a/src/Umbraco.Web.BackOffice/Controllers/MediaController.cs +++ b/src/Umbraco.Web.BackOffice/Controllers/MediaController.cs @@ -858,7 +858,7 @@ public async Task PostAddFile([FromForm] string path, [FromForm] } } - return Ok(); + return Ok(tempFiles); } private IMedia FindInChildren(int mediaId, string nameToFind, string contentTypeAlias) diff --git a/src/Umbraco.Web.BackOffice/Controllers/TemplateController.cs b/src/Umbraco.Web.BackOffice/Controllers/TemplateController.cs index 0a800693f80c..23c955219aee 100644 --- a/src/Umbraco.Web.BackOffice/Controllers/TemplateController.cs +++ b/src/Umbraco.Web.BackOffice/Controllers/TemplateController.cs @@ -3,6 +3,7 @@ using System.Linq; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.DependencyInjection; using Umbraco.Cms.Core; using Umbraco.Cms.Core.IO; using Umbraco.Cms.Core.Mapping; @@ -12,6 +13,7 @@ using Umbraco.Cms.Core.Strings; using Umbraco.Cms.Web.Common.Attributes; using Umbraco.Cms.Web.Common.Authorization; +using Umbraco.Cms.Web.Common.DependencyInjection; using Constants = Umbraco.Cms.Core.Constants; namespace Umbraco.Cms.Web.BackOffice.Controllers @@ -24,15 +26,28 @@ public class TemplateController : BackOfficeNotificationsController private readonly IFileService _fileService; private readonly IUmbracoMapper _umbracoMapper; private readonly IShortStringHelper _shortStringHelper; + private readonly IDefaultViewContentProvider _defaultViewContentProvider; + [ActivatorUtilitiesConstructor] public TemplateController( IFileService fileService, IUmbracoMapper umbracoMapper, - IShortStringHelper shortStringHelper) + IShortStringHelper shortStringHelper, + IDefaultViewContentProvider defaultViewContentProvider) { _fileService = fileService ?? throw new ArgumentNullException(nameof(fileService)); _umbracoMapper = umbracoMapper ?? throw new ArgumentNullException(nameof(umbracoMapper)); _shortStringHelper = shortStringHelper ?? throw new ArgumentNullException(nameof(shortStringHelper)); + _defaultViewContentProvider = defaultViewContentProvider ?? throw new ArgumentNullException(nameof(defaultViewContentProvider)); + } + + [Obsolete("Use ctor will all params")] + public TemplateController( + IFileService fileService, + IUmbracoMapper umbracoMapper, + IShortStringHelper shortStringHelper) + : this(fileService, umbracoMapper, shortStringHelper, StaticServiceProvider.Instance.GetRequiredService()) + { } /// @@ -136,10 +151,10 @@ public TemplateDisplay GetScaffold(int id) } } - var content = ViewHelper.GetDefaultFileContent( layoutPageAlias: dt.MasterTemplateAlias ); + var content = _defaultViewContentProvider.GetDefaultFileContent( layoutPageAlias: dt.MasterTemplateAlias ); var scaffold = _umbracoMapper.Map(dt); - scaffold.Content = content + "\r\n\r\n@* the fun starts here *@\r\n\r\n"; + scaffold.Content = content; return scaffold; } diff --git a/src/Umbraco.Web.BackOffice/PropertyEditors/TagsDataController.cs b/src/Umbraco.Web.BackOffice/PropertyEditors/TagsDataController.cs index 17d015abc803..7f02de479448 100644 --- a/src/Umbraco.Web.BackOffice/PropertyEditors/TagsDataController.cs +++ b/src/Umbraco.Web.BackOffice/PropertyEditors/TagsDataController.cs @@ -1,10 +1,11 @@ -using System; +using System; using System.Collections.Generic; using System.Linq; using Umbraco.Cms.Core.Models; using Umbraco.Cms.Core.PublishedCache; using Umbraco.Cms.Web.BackOffice.Controllers; using Umbraco.Cms.Web.Common.Attributes; +using Umbraco.Cms.Web.Common.Filters; using Umbraco.Extensions; using Constants = Umbraco.Cms.Core.Constants; @@ -33,6 +34,8 @@ public TagsDataController(ITagQuery tagQuery) /// /// /// + /// + [AllowHttpJsonConfigration] public IEnumerable GetTags(string tagGroup, string culture, string query = null) { if (culture == string.Empty) culture = null; diff --git a/src/Umbraco.Web.BackOffice/Trees/ContentTreeControllerBase.cs b/src/Umbraco.Web.BackOffice/Trees/ContentTreeControllerBase.cs index 1bddb12cdeb3..8bf84357031c 100644 --- a/src/Umbraco.Web.BackOffice/Trees/ContentTreeControllerBase.cs +++ b/src/Umbraco.Web.BackOffice/Trees/ContentTreeControllerBase.cs @@ -68,7 +68,7 @@ AppCaches appCaches /// /// /// - public ActionResult GetTreeNode([FromRoute] string id, [ModelBinder(typeof(HttpQueryStringModelBinder))]FormCollection queryStrings) + public ActionResult GetTreeNode([FromRoute] string id, [ModelBinder(typeof(HttpQueryStringModelBinder))] FormCollection queryStrings) { int asInt; Guid asGuid = Guid.Empty; @@ -325,7 +325,8 @@ private IEnumerable GetChildrenFromEntityService(int entityId) /// protected bool HasPathAccess(IUmbracoEntity entity, FormCollection queryStrings) { - if (entity == null) return false; + if (entity == null) + return false; return RecycleBinId == Constants.System.RecycleBinContent ? _backofficeSecurityAccessor.BackOfficeSecurity.CurrentUser.HasContentPathAccess(entity, _entityService, _appCaches) : _backofficeSecurityAccessor.BackOfficeSecurity.CurrentUser.HasMediaPathAccess(entity, _entityService, _appCaches); @@ -469,13 +470,13 @@ protected sealed override ActionResult GetMenuForNode(string // only add empty recycle bin if the current user is allowed to delete by default if (deleteAllowed) { - menu.Items.Add(new MenuItem("emptyrecyclebin", LocalizedTextService) - { - Icon = "trash", - OpensDialog = true - }); - menu.Items.Add(new RefreshNode(LocalizedTextService, true)); - } + menu.Items.Add(new MenuItem("emptyRecycleBin", LocalizedTextService) + { + Icon = "trash", + OpensDialog = true + }); + menu.Items.Add(new RefreshNode(LocalizedTextService, true)); + } return menu; } @@ -608,7 +609,8 @@ internal IEntitySlim GetEntityFromId(string id) /// internal bool IgnoreUserStartNodes(FormCollection queryStrings) { - if (_ignoreUserStartNodes.HasValue) return _ignoreUserStartNodes.Value; + if (_ignoreUserStartNodes.HasValue) + return _ignoreUserStartNodes.Value; var dataTypeKey = queryStrings.GetValue(TreeQueryStringParameters.DataTypeKey); _ignoreUserStartNodes = dataTypeKey.HasValue && _dataTypeService.IsDataTypeIgnoringUserStartNodes(dataTypeKey.Value); diff --git a/src/Umbraco.Web.BackOffice/Trees/ContentTypeTreeController.cs b/src/Umbraco.Web.BackOffice/Trees/ContentTypeTreeController.cs index c4112cc77e39..ecc5b78a51e9 100644 --- a/src/Umbraco.Web.BackOffice/Trees/ContentTypeTreeController.cs +++ b/src/Umbraco.Web.BackOffice/Trees/ContentTypeTreeController.cs @@ -76,7 +76,8 @@ protected override ActionResult GetTreeNodes(string id, Form })); //if the request is for folders only then just return - if (queryStrings["foldersonly"].ToString().IsNullOrWhiteSpace() == false && queryStrings["foldersonly"] == "1") return nodes; + if (queryStrings["foldersonly"].ToString().IsNullOrWhiteSpace() == false && queryStrings["foldersonly"] == "1") + return nodes; var children = _entityService.GetChildren(intId, UmbracoObjectTypes.DocumentType).ToArray(); var contentTypes = _contentTypeService.GetAll(children.Select(c => c.Id).ToArray()).ToDictionary(c => c.Id); @@ -117,7 +118,7 @@ protected override ActionResult GetMenuForNode(string id, Fo // root actions menu.Items.Add(LocalizedTextService, opensDialog: true); - menu.Items.Add(new MenuItem("importdocumenttype", LocalizedTextService) + menu.Items.Add(new MenuItem("importDocumentType", LocalizedTextService) { Icon = "page-up", SeparatorBefore = true, diff --git a/src/Umbraco.Web.BackOffice/Trees/TreeCollectionBuilder.cs b/src/Umbraco.Web.BackOffice/Trees/TreeCollectionBuilder.cs index 37a857f78d14..d8d8afe13ada 100644 --- a/src/Umbraco.Web.BackOffice/Trees/TreeCollectionBuilder.cs +++ b/src/Umbraco.Web.BackOffice/Trees/TreeCollectionBuilder.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Linq; using Microsoft.Extensions.DependencyInjection; using Umbraco.Cms.Core.Composing; using Umbraco.Cms.Core.Trees; @@ -56,5 +57,16 @@ public void AddTreeControllers(IEnumerable controllerTypes) foreach (var controllerType in controllerTypes) AddTreeController(controllerType); } + + public void RemoveTreeController() => RemoveTreeController(typeof(T)); + + public void RemoveTreeController(Type type) + { + var tree = _trees.FirstOrDefault(it => it.TreeControllerType == type); + if (tree != null) + { + _trees.Remove(tree); + } + } } } diff --git a/src/Umbraco.Web.Common/ActionsResults/PublishedContentNotFoundResult.cs b/src/Umbraco.Web.Common/ActionsResults/PublishedContentNotFoundResult.cs index 2ef9a5e4b34f..0eb30bcd0377 100644 --- a/src/Umbraco.Web.Common/ActionsResults/PublishedContentNotFoundResult.cs +++ b/src/Umbraco.Web.Common/ActionsResults/PublishedContentNotFoundResult.cs @@ -44,18 +44,14 @@ public async Task ExecuteResultAsync(ActionContext context) reason = "No template exists to render the document at URL '{0}'."; } - await response.WriteAsync("

Page not found

"); - await response.WriteAsync("

"); - await response.WriteAsync(string.Format(reason, WebUtility.HtmlEncode(_umbracoContext.OriginalRequestUrl.PathAndQuery))); - await response.WriteAsync("

"); - if (string.IsNullOrWhiteSpace(_message) == false) + var viewResult = new ViewResult { - await response.WriteAsync("

" + _message + "

"); - } + ViewName = "~/umbraco/UmbracoWebsite/NotFound.cshtml" + }; + context.HttpContext.Items.Add("reason", string.Format(reason, WebUtility.HtmlEncode(_umbracoContext.OriginalRequestUrl.PathAndQuery))); + context.HttpContext.Items.Add("message", _message); - await response.WriteAsync("

This page can be replaced with a custom 404. Check the documentation for Custom 404 Error Pages.

"); - await response.WriteAsync("

This page is intentionally left ugly ;-)

"); - await response.WriteAsync(""); + await viewResult.ExecuteResultAsync(context); } } } diff --git a/src/Umbraco.Web.Common/Authorization/FeatureAuthorizeHandler.cs b/src/Umbraco.Web.Common/Authorization/FeatureAuthorizeHandler.cs index 0a4981d6c6e8..283accb08506 100644 --- a/src/Umbraco.Web.Common/Authorization/FeatureAuthorizeHandler.cs +++ b/src/Umbraco.Web.Common/Authorization/FeatureAuthorizeHandler.cs @@ -47,6 +47,13 @@ protected override Task HandleRequirementAsync(AuthorizationHandlerContext conte break; } + case Microsoft.AspNetCore.Mvc.Filters.AuthorizationFilterContext authorizationFilterContext: + { + IEndpointFeature endpointFeature = authorizationFilterContext.HttpContext.Features.Get(); + endpoint = endpointFeature.Endpoint; + break; + } + case Endpoint resourceEndpoint: { endpoint = resourceEndpoint; diff --git a/src/Umbraco.Web.Common/Extensions/FriendlyImageCropperTemplateExtensions.cs b/src/Umbraco.Web.Common/Extensions/FriendlyImageCropperTemplateExtensions.cs index 22ddc1551189..c59e7b112625 100644 --- a/src/Umbraco.Web.Common/Extensions/FriendlyImageCropperTemplateExtensions.cs +++ b/src/Umbraco.Web.Common/Extensions/FriendlyImageCropperTemplateExtensions.cs @@ -32,6 +32,15 @@ public static string GetCropUrl( UrlMode urlMode = UrlMode.Default) => mediaItem.GetCropUrl(cropAlias, ImageUrlGenerator, PublishedValueFallback, PublishedUrlProvider, urlMode); + /// + /// Gets the underlying image processing service URL by the crop alias (from the "umbracoFile" property alias in the MediaWithCrops content item) on the MediaWithCrops item. + /// + /// The MediaWithCrops item. + /// The crop alias e.g. thumbnail. + /// The url mode. + /// + /// The URL of the cropped image. + /// public static string GetCropUrl(this MediaWithCrops mediaWithCrops, string cropAlias, UrlMode urlMode = UrlMode.Default) => ImageCropperTemplateCoreExtensions.GetCropUrl(mediaWithCrops, cropAlias, ImageUrlGenerator, PublishedValueFallback, PublishedUrlProvider, urlMode); @@ -69,6 +78,16 @@ public static string GetCropUrl( UrlMode urlMode = UrlMode.Default) => mediaItem.GetCropUrl(propertyAlias, cropAlias, ImageUrlGenerator, PublishedValueFallback, PublishedUrlProvider, urlMode); + /// + /// Gets the underlying image processing service URL by the crop alias using the specified property containing the image cropper JSON data on the MediaWithCrops content item. + /// + /// The MediaWithCrops item. + /// The property alias of the property containing the JSON data e.g. umbracoFile. + /// The crop alias e.g. thumbnail. + /// The url mode. + /// + /// The URL of the cropped image. + /// public static string GetCropUrl(this MediaWithCrops mediaWithCrops, string propertyAlias, string cropAlias, UrlMode urlMode = UrlMode.Default) => ImageCropperTemplateCoreExtensions.GetCropUrl(mediaWithCrops, propertyAlias, cropAlias, ImageUrlGenerator, PublishedValueFallback, PublishedUrlProvider, urlMode); @@ -126,6 +145,60 @@ public static string GetCropUrl( urlMode ); + /// + /// Gets the underlying image processing service URL from the MediaWithCrops item. + /// + /// The MediaWithCrops item. + /// The width of the output image. + /// The height of the output image. + /// Property alias of the property containing the JSON data. + /// The crop alias. + /// Quality percentage of the output image. + /// The image crop mode. + /// The image crop anchor. + /// Use focal point, to generate an output image using the focal point instead of the predefined crop. + /// Use crop dimensions to have the output image sized according to the predefined crop sizes, this will override the width and height parameters. + /// Add a serialized date of the last edit of the item to ensure client cache refresh when updated. + /// These are any query string parameters (formatted as query strings) that the underlying image processing service supports. For example: + /// + /// The url mode. + /// + /// The URL of the cropped image. + /// + public static string GetCropUrl( + this MediaWithCrops mediaWithCrops, + int? width = null, + int? height = null, + string propertyAlias = Cms.Core.Constants.Conventions.Media.File, + string cropAlias = null, + int? quality = null, + ImageCropMode? imageCropMode = null, + ImageCropAnchor? imageCropAnchor = null, + bool preferFocalPoint = false, + bool useCropDimensions = false, + bool cacheBuster = true, + string furtherOptions = null, + UrlMode urlMode = UrlMode.Default) + => mediaWithCrops.GetCropUrl( + ImageUrlGenerator, + PublishedValueFallback, + PublishedUrlProvider, + width, + height, + propertyAlias, + cropAlias, + quality, + imageCropMode, + imageCropAnchor, + preferFocalPoint, + useCropDimensions, + cacheBuster, + furtherOptions, + urlMode + ); + /// /// Gets the underlying image processing service URL from the image path. /// diff --git a/src/Umbraco.Web.Common/Extensions/ImageCropperTemplateCoreExtensions.cs b/src/Umbraco.Web.Common/Extensions/ImageCropperTemplateCoreExtensions.cs index a3e96ebebb47..f335a81ae78a 100644 --- a/src/Umbraco.Web.Common/Extensions/ImageCropperTemplateCoreExtensions.cs +++ b/src/Umbraco.Web.Common/Extensions/ImageCropperTemplateCoreExtensions.cs @@ -32,6 +32,18 @@ public static string GetCropUrl( IPublishedUrlProvider publishedUrlProvider, UrlMode urlMode = UrlMode.Default) => mediaItem.GetCropUrl(imageUrlGenerator, publishedValueFallback, publishedUrlProvider, cropAlias: cropAlias, useCropDimensions: true, urlMode: urlMode); + /// + /// Gets the underlying image processing service URL by the crop alias (from the "umbracoFile" property alias in the MediaWithCrops content item) on the MediaWithCrops item. + /// + /// The MediaWithCrops item. + /// The crop alias e.g. thumbnail. + /// The image URL generator. + /// The published value fallback. + /// The published URL provider. + /// The url mode. + /// + /// The URL of the cropped image. + /// public static string GetCropUrl( this MediaWithCrops mediaWithCrops, string cropAlias, @@ -84,6 +96,19 @@ public static string GetCropUrl( IPublishedUrlProvider publishedUrlProvider, UrlMode urlMode = UrlMode.Default) => mediaItem.GetCropUrl(imageUrlGenerator, publishedValueFallback, publishedUrlProvider, propertyAlias: propertyAlias, cropAlias: cropAlias, useCropDimensions: true, urlMode: urlMode); + /// + /// Gets the underlying image processing service URL by the crop alias using the specified property containing the image cropper JSON data on the MediaWithCrops content item. + /// + /// The MediaWithCrops item. + /// The property alias of the property containing the JSON data e.g. umbracoFile. + /// The crop alias e.g. thumbnail. + /// The image URL generator. + /// The published value fallback. + /// The published URL provider. + /// The url mode. + /// + /// The URL of the cropped image. + /// public static string GetCropUrl(this MediaWithCrops mediaWithCrops, IPublishedValueFallback publishedValueFallback, IPublishedUrlProvider publishedUrlProvider, @@ -135,6 +160,31 @@ public static string GetCropUrl( string furtherOptions = null, UrlMode urlMode = UrlMode.Default) => mediaItem.GetCropUrl(imageUrlGenerator, publishedValueFallback, publishedUrlProvider, null, false, width, height, propertyAlias, cropAlias, quality, imageCropMode, imageCropAnchor, preferFocalPoint, useCropDimensions, cacheBuster, furtherOptions, urlMode); + /// + /// Gets the underlying image processing service URL from the MediaWithCrops item. + /// + /// The MediaWithCrops item. + /// The image URL generator. + /// The published value fallback. + /// The published URL provider. + /// The width of the output image. + /// The height of the output image. + /// Property alias of the property containing the JSON data. + /// The crop alias. + /// Quality percentage of the output image. + /// The image crop mode. + /// The image crop anchor. + /// Use focal point, to generate an output image using the focal point instead of the predefined crop. + /// Use crop dimensions to have the output image sized according to the predefined crop sizes, this will override the width and height parameters. + /// Add a serialized date of the last edit of the item to ensure client cache refresh when updated. + /// These are any query string parameters (formatted as query strings) that ImageProcessor supports. For example: + /// + /// The url mode. + /// + /// The URL of the cropped image. + /// public static string GetCropUrl( this MediaWithCrops mediaWithCrops, IImageUrlGenerator imageUrlGenerator, diff --git a/src/Umbraco.Web.Common/Filters/AllowHttpJsonConfigrationAttribute.cs b/src/Umbraco.Web.Common/Filters/AllowHttpJsonConfigrationAttribute.cs new file mode 100644 index 000000000000..31fddc65f107 --- /dev/null +++ b/src/Umbraco.Web.Common/Filters/AllowHttpJsonConfigrationAttribute.cs @@ -0,0 +1,42 @@ +using System; +using System.Buffers; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Mvc.Filters; +using Microsoft.Extensions.Options; +using Newtonsoft.Json; +using Newtonsoft.Json.Converters; +using Newtonsoft.Json.Serialization; +using Umbraco.Cms.Web.Common.Formatters; + +namespace Umbraco.Cms.Web.Common.Filters +{ + public class AllowHttpJsonConfigrationAttribute : TypeFilterAttribute + { + /// + /// This filter overwrites AngularJsonOnlyConfigurationAttribute and get the api back to its defualt behavior + /// + public AllowHttpJsonConfigrationAttribute() : base(typeof(AllowJsonXHRConfigrationFilter)) + { + Order = 2; // this value must be more than the AngularJsonOnlyConfigurationAttribute on order to overwrtie it + } + + private class AllowJsonXHRConfigrationFilter : IResultFilter + { + public void OnResultExecuted(ResultExecutedContext context) + { + } + + public void OnResultExecuting(ResultExecutingContext context) + { + if (context.Result is ObjectResult objectResult) + { + objectResult.Formatters.RemoveType(); + } + } + } + } +} diff --git a/src/Umbraco.Web.Common/ModelsBuilder/ModelsBuilderNotificationHandler.cs b/src/Umbraco.Web.Common/ModelsBuilder/ModelsBuilderNotificationHandler.cs index 90a48c401768..ea8408b21200 100644 --- a/src/Umbraco.Web.Common/ModelsBuilder/ModelsBuilderNotificationHandler.cs +++ b/src/Umbraco.Web.Common/ModelsBuilder/ModelsBuilderNotificationHandler.cs @@ -26,15 +26,17 @@ internal class ModelsBuilderNotificationHandler : private readonly ModelsBuilderSettings _config; private readonly IShortStringHelper _shortStringHelper; private readonly IModelsBuilderDashboardProvider _modelsBuilderDashboardProvider; + private readonly IDefaultViewContentProvider _defaultViewContentProvider; public ModelsBuilderNotificationHandler( IOptions config, IShortStringHelper shortStringHelper, - IModelsBuilderDashboardProvider modelsBuilderDashboardProvider) + IModelsBuilderDashboardProvider modelsBuilderDashboardProvider, IDefaultViewContentProvider defaultViewContentProvider) { _config = config.Value; _shortStringHelper = shortStringHelper; _modelsBuilderDashboardProvider = modelsBuilderDashboardProvider; + _defaultViewContentProvider = defaultViewContentProvider; } /// @@ -123,7 +125,7 @@ public void Handle(TemplateSavingNotification notification) // we do not support configuring this at the moment, so just let Umbraco use its default value // var modelNamespaceAlias = ...; - var markup = ViewHelper.GetDefaultFileContent( + var markup = _defaultViewContentProvider.GetDefaultFileContent( modelClassName: className, modelNamespace: modelNamespace/*, modelNamespaceAlias: modelNamespaceAlias*/); diff --git a/src/Umbraco.Web.UI.Client/src/common/mocks/resources/tree.mocks.js b/src/Umbraco.Web.UI.Client/src/common/mocks/resources/tree.mocks.js index 6bc785552872..3d2c77f2b4eb 100644 --- a/src/Umbraco.Web.UI.Client/src/common/mocks/resources/tree.mocks.js +++ b/src/Umbraco.Web.UI.Client/src/common/mocks/resources/tree.mocks.js @@ -28,7 +28,7 @@ angular.module('umbraco.mocks'). { separator: true, name: "Reload", cssclass: "refresh", alias: "users", metaData: {} }, - { separator: true, name: "Empty Recycle Bin", cssclass: "trash", alias: "emptyrecyclebin", metaData: {} } + { separator: true, name: "Empty Recycle Bin", cssclass: "trash", alias: "emptyRecycleBin", metaData: {} } ]; var result = { diff --git a/src/Umbraco.Web.UI.Client/src/common/services/tinymce.service.js b/src/Umbraco.Web.UI.Client/src/common/services/tinymce.service.js index 6c6237263f49..e6eb430201bb 100644 --- a/src/Umbraco.Web.UI.Client/src/common/services/tinymce.service.js +++ b/src/Umbraco.Web.UI.Client/src/common/services/tinymce.service.js @@ -1278,11 +1278,22 @@ function tinyMceService($rootScope, $q, imageHelper, $locale, $http, $timeout, s function insertLink() { if (anchorElm) { editor.dom.setAttribs(anchorElm, createElemAttributes()); - editor.selection.select(anchorElm); editor.execCommand('mceEndTyping'); } else { - editor.execCommand('mceInsertLink', false, createElemAttributes()); + var selectedContent = editor.selection.getContent(); + // If there is no selected content, we can't insert a link + // as TinyMCE needs selected content for this, so instead we + // create a new dom element and insert it, using the chosen + // link name as the content. + if (selectedContent !== "") { + editor.execCommand('mceInsertLink', false, createElemAttributes()); + } else { + // Using the target url as a fallback, as href might be confusing with a local link + var linkContent = typeof target.name !== "undefined" && target.name !== "" ? target.name : target.url + var domElement = editor.dom.createHTML("a", createElemAttributes(), linkContent); + editor.execCommand('mceInsertContent', false, domElement); + } } } diff --git a/src/Umbraco.Web.UI.Client/src/installer/steps/user.html b/src/Umbraco.Web.UI.Client/src/installer/steps/user.html index 4dd8afd51205..e314a16319b0 100644 --- a/src/Umbraco.Web.UI.Client/src/installer/steps/user.html +++ b/src/Umbraco.Web.UI.Client/src/installer/steps/user.html @@ -1,4 +1,4 @@ -
+

Install Umbraco

Enter your name, email and password to install Umbraco with its default settings, alternatively you can customize your installation

@@ -59,7 +59,7 @@

Install Umbraco

- +
diff --git a/src/Umbraco.Web.UI.Client/src/less/property-editors.less b/src/Umbraco.Web.UI.Client/src/less/property-editors.less index 040ec42c0c37..fd699b79d0a9 100644 --- a/src/Umbraco.Web.UI.Client/src/less/property-editors.less +++ b/src/Umbraco.Web.UI.Client/src/less/property-editors.less @@ -607,6 +607,7 @@ box-sizing: border-box; line-height: 0; contain: content; + position: relative; .checkeredBackground(); &:focus, &:focus-within { diff --git a/src/Umbraco.Web.UI.Client/src/views/components/blockcard/umb-block-card.less b/src/Umbraco.Web.UI.Client/src/views/components/blockcard/umb-block-card.less index bfd72c021699..d5823651022d 100644 --- a/src/Umbraco.Web.UI.Client/src/views/components/blockcard/umb-block-card.less +++ b/src/Umbraco.Web.UI.Client/src/views/components/blockcard/umb-block-card.less @@ -58,7 +58,7 @@ umb-block-card { padding-bottom: 10/16*100%; background-color: @gray-12; - background-size: cover; + background-size: contain; background-position: 50% 50%; background-repeat: no-repeat; diff --git a/src/Umbraco.Web.UI.Client/src/views/dictionary/dictionary.list.controller.js b/src/Umbraco.Web.UI.Client/src/views/dictionary/dictionary.list.controller.js index e55dfd44a106..669a0d518336 100644 --- a/src/Umbraco.Web.UI.Client/src/views/dictionary/dictionary.list.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/dictionary/dictionary.list.controller.js @@ -1,4 +1,4 @@ -/** +/** * @ngdoc controller * @name Umbraco.Editors.Dictionary.ListController * @function @@ -6,7 +6,7 @@ * @description * The controller for listting dictionary items */ -function DictionaryListController($scope, $location, dictionaryResource, localizationService, appState) { +function DictionaryListController($scope, $location, dictionaryResource, localizationService, appState, navigationService) { var vm = this; vm.title = "Dictionary overview"; vm.loading = false; @@ -31,7 +31,17 @@ function DictionaryListController($scope, $location, dictionaryResource, localiz $location.path("/" + currentSection + "/dictionary/edit/" + id); } + function createNewItem() { + var rootNode = appState.getTreeState("currentRootNode").root; + //We need to load the menu first before we can access the menu actions. + navigationService.showMenu({ node: rootNode }).then(function () { + const action = appState.getMenuState("menuActions").find(item => item.alias === "create"); + navigationService.executeMenuAction(action, rootNode, appState.getSectionState("currentSection")); + }); + } + vm.clickItem = clickItem; + vm.createNewItem = createNewItem; function onInit() { localizationService.localize("dictionaryItem_overviewTitle").then(function (value) { diff --git a/src/Umbraco.Web.UI.Client/src/views/dictionary/list.html b/src/Umbraco.Web.UI.Client/src/views/dictionary/list.html index 928aba0607d6..14c7bb4c5cb5 100644 --- a/src/Umbraco.Web.UI.Client/src/views/dictionary/list.html +++ b/src/Umbraco.Web.UI.Client/src/views/dictionary/list.html @@ -1,4 +1,4 @@ -
+
@@ -13,43 +13,55 @@ - - - - - There are no dictionary items. - - - - - - - - - - - - - - - - - - - -
Name{{column.displayName}}
- - - -
+ + + + + + + + + + + + + + There are no dictionary items. + + + + + + + + + + + + + + + + + + + +
Name{{column.displayName}}
+ + + +
diff --git a/src/Umbraco.Web.UI.Client/src/views/prevalueeditors/treesource.html b/src/Umbraco.Web.UI.Client/src/views/prevalueeditors/treesource.html index f56a6c8656ad..0ab66c964efb 100644 --- a/src/Umbraco.Web.UI.Client/src/views/prevalueeditors/treesource.html +++ b/src/Umbraco.Web.UI.Client/src/views/prevalueeditors/treesource.html @@ -27,7 +27,7 @@
- +
@@ -36,32 +36,37 @@ + placeholder="Enter XPath query">
  • - +

    - Use Xpath query to set a root node on the tree, either based on a search from the root of the content tree, or by using a context-aware placeholder. + Use an XPath query to set a root node on the tree, either based on a search from the root of the content tree, or by using a context-aware placeholder.

    - Placeholders finds the nearest published ID and runs its query from there, so for instance: - -

    $parent/newsArticle
    - - Will try to get the parent if available, but will then fall back to the nearest ancestor and query for all news articles there. + A placeholder finds the nearest published ID and runs its query from there, so for instance: +

    + +
    $parent/newsArticle
    + +

    + Will try to get the parent if available, but will then fall back to the nearest ancestor and query for all news article children there.

    Available placeholders:
    - $current: current page or closest found ancestor
    - $parent: parent page or closest found ancestor
    - $root: root of the content tree
    - $site: Ancestor node at level 1
    + $current: Current page or closest found ancestor
    + $parent: Parent page or closest found ancestor
    + $root: Root of the content tree
    + $site: Ancestor node at level 1
    +

    +

    + Note: The placeholder can only be used at the beginning of the query.

  • diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/listview/listview.controller.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/listview/listview.controller.js index 76e6759a475e..c66ff1a46171 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/listview/listview.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/listview/listview.controller.js @@ -380,7 +380,7 @@ function listViewController($scope, $interpolate, $routeParams, $injector, $time }); } - $scope.delete = function () { + $scope.delete = function (numberOfItems, totalItems) { const dialog = { view: "views/propertyeditors/listview/overlays/delete.html", @@ -394,7 +394,9 @@ function listViewController($scope, $interpolate, $routeParams, $injector, $time }, close: function () { overlayService.close(); - } + }, + numberOfItems: numberOfItems, + totalItems: totalItems }; localizationService.localize("general_delete").then(value => { diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/listview/listview.html b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/listview/listview.html index 92ad56b045a7..7fad01fe6c2c 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/listview/listview.html +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/listview/listview.html @@ -190,7 +190,7 @@ button-style="white" label-key="actions_delete" icon="icon-trash" - action="delete()" + action="delete(selection.length, listViewResultSet.items.length)" disabled="actionInProgress" size="xs" add-ellipsis="true"> diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/listview/overlays/delete.html b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/listview/overlays/delete.html index 1c99aa594e42..74b3cce7e52a 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/listview/overlays/delete.html +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/listview/overlays/delete.html @@ -1,7 +1,7 @@

    - ? + ?

    diff --git a/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj b/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj index bae39162f470..622766b4b15e 100644 --- a/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj +++ b/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj @@ -43,6 +43,7 @@ + diff --git a/src/Umbraco.Web.UI/Views/Partials/blocklist/default.cshtml b/src/Umbraco.Web.UI/Views/Partials/blocklist/default.cshtml index fffd5e58bb60..d5944b93c3a8 100644 --- a/src/Umbraco.Web.UI/Views/Partials/blocklist/default.cshtml +++ b/src/Umbraco.Web.UI/Views/Partials/blocklist/default.cshtml @@ -8,6 +8,6 @@ if (block?.ContentUdi == null) { continue; } var data = block.Content; - @await Html.PartialAsync("BlockList/Components/" + data.ContentType.Alias, block) + @await Html.PartialAsync("blocklist/Components/" + data.ContentType.Alias, block) }
    diff --git a/src/Umbraco.Web.UI/umbraco/UmbracoWebsite/NotFound.cshtml b/src/Umbraco.Web.UI/umbraco/UmbracoWebsite/NotFound.cshtml new file mode 100644 index 000000000000..62a149f2ab9d --- /dev/null +++ b/src/Umbraco.Web.UI/umbraco/UmbracoWebsite/NotFound.cshtml @@ -0,0 +1,84 @@ +@using Microsoft.Extensions.Options +@using Umbraco.Cms.Core.Configuration.Models +@using Umbraco.Cms.Core.Hosting +@using Umbraco.Cms.Core.Routing +@using Umbraco.Extensions +@inject IHostingEnvironment hostingEnvironment +@inject IOptions globalSettings +@{ + var backOfficePath = globalSettings.Value.GetBackOfficePath(hostingEnvironment); +} + + + + + + + + Page Not Found + + + + + + +
    +
    +
    +

    Page Not Found

    + @if (hostingEnvironment.IsDebugMode) + { + + var reason = (string)Context.Items["reason"]; + var message = (string)Context.Items["message"]; + + if (!reason.IsNullOrWhiteSpace()) + { +

    @reason

    + } + if (!message.IsNullOrWhiteSpace()) + { +

    @message

    + } + +
    + +
    +
    +

    This page can be replaced

    +

    + Custom error handling might make your site look more on-brand and minimize the impact of errors on user experience - for example, a custom 404 with some helpful links (or a search function) could bring some value to the site. +

    + + Implementing custom error pages → +
    + +
    +

    Be a part of the community

    +

    The Umbraco community is the best of its kind, be sure to visit, and if you have any questions, we're sure that you can get your answers from the community.

    + + our.Umbraco → +
    +
    + + } +
    +
    + +
    + + + diff --git a/src/Umbraco.Web.UI/umbraco/config/lang/cs.xml b/src/Umbraco.Web.UI/umbraco/config/lang/cs.xml index 148ebf23532b..af701cd5e392 100644 --- a/src/Umbraco.Web.UI/umbraco/config/lang/cs.xml +++ b/src/Umbraco.Web.UI/umbraco/config/lang/cs.xml @@ -16,10 +16,10 @@ Vytvořit skupinu Odstranit Deaktivovat - Vyprázdnit koš + Vyprázdnit koš Aktivovat Exportovat typ dokumentu - Importovat typ dokumentu + Importovat typ dokumentu Importovat balíček Editovat na stránce Odhlásit @@ -765,21 +765,12 @@ Instalátor se nemůže připojit k databázi. - Nelze uložit soubor web.config. Modifikujte, prosím, připojovací řetězec manuálně. Vyše databáze byla nalezena a je identifikována jako Nastavení databáze instalovat, abyste nainstalovali Umbraco %0% databázi ]]> následující pro pokračování.]]> - Databáze nenalezena! Zkontrolujte, prosím, že informace v "připojovacím řetězci" souboru "web.config" jsou správné.

    -

    Pro pokračování otevřete, prosím, soubor "web.config" (za pužití Visual Studia nebo Vašeho oblíbeného tedtového editoru), přejděte na jeho konec, přidejte připojovací řetězec pro Vaši databázi v klíčí nazvaném "umbracoDbDSN" a soubor uložte.

    -

    - Klikněte na tlačítko zopakovat, až budete hotovi.
    - Další informace o editování souboru web.config zde.

    ]]>
    - - Pokud je to nezbytné, kontaktujte vašeho poskytovatele hostingu. - Jestliže instalujete na místní počítač nebo server, budete potřebovat informace od Vašeho systémového administrátora.]]> Stiskněte tlačítko povýšit pro povýšení Vaší databáze na Umbraco %0%

    @@ -794,7 +785,6 @@ Heslo výchozího uživatele bylo úspěšně změněno od doby instalace!

    Netřeba nic dalšího dělat. Klikněte na Následující pro pokračování.]]> Heslo je změněno! Mějte skvělý start, sledujte naše uváděcí videa - Kliknutím na tlačítko následující (nebo modifikováním umbracoConfigurationStatus v souboru web.config) přijímáte licenci tohoto software tak, jak je uvedena v poli níže. Upozorňujeme, že tato distribuce Umbraca se skládá ze dvou různých licencí, open source MIT licence pro framework a Umbraco freeware licence, která pokrývá UI. Není nainstalováno. Dotčené soubory a složky Další informace o nastavování oprávnění pro Umbraco zde @@ -854,7 +844,6 @@ Další pomoc a informace Abyste získali pomoc od naší oceňované komunity, projděte si dokumentaci, nebo si pusťte některá videa zdarma o tom, jak vytvořit jednoduchý web, jak používat balíčky a rychlý úvod do terminologie umbraca]]> Umbraco %0% je nainstalováno a připraveno k použití - soubor /web.config a upravit klíč AppSetting umbracoConfigurationStatus dole na hodnotu '%0%'.]]> ihned začít kliknutím na tlačítko "Spustit Umbraco" níže.
    Jestliže je pro Vás Umbraco nové, spoustu zdrojů naleznete na naších stránkách "začínáme".]]>
    Spustit Umbraco @@ -1938,8 +1927,6 @@ Platnost certifikátu SSL vašeho webu vyprší za %0% dní. Chyba při pingování adresy URL %0% - '%1%' Aktuálně prohlížíte web pomocí schématu HTTPS. - AppSetting 'Umbraco.Core.UseHttps' je v souboru web.config nastaven na 'false'. Jakmile vstoupíte na tento web pomocí schématu HTTPS, mělo by být nastaveno na 'true'. - AppSetting 'Umbraco.Core.UseHttps' je v souboru web.config nastaven na '%0%', vaše cookies %1% jsou označeny jako zabezpečené. Režim kompilace ladění je zakázán. Režim ladění je aktuálně povolen. Před spuštěním webu se doporučuje toto nastavení deaktivovat. @@ -1962,10 +1949,7 @@ --> %0%.]]> Nebyly nalezeny žádné hlavičky odhalující informace o technologii webových stránek. - V souboru Web.config nelze najít system.net/mailsettings. - V části system.net/mailsettings v souboru web.config není hostitel nakonfigurován. Nastavení SMTP jsou správně nakonfigurována a služba funguje jak má. - Server SMTP konfigurovaný s hostitelem '%0%' a portem '%1%' nelze nalézt. Zkontrolujte prosím, zda jsou nastavení SMTP v souboru Web.config a v sekci system.net/mailsettings správná. %0%.]]> %0%.]]>

    Výsledky plánovaných kontrol Umbraco Health Checks provedených na %0% v %1% jsou následující:

    %2%]]>
    diff --git a/src/Umbraco.Web.UI/umbraco/config/lang/cy.xml b/src/Umbraco.Web.UI/umbraco/config/lang/cy.xml index 0a414d23df04..ed078653ab31 100644 --- a/src/Umbraco.Web.UI/umbraco/config/lang/cy.xml +++ b/src/Umbraco.Web.UI/umbraco/config/lang/cy.xml @@ -929,7 +929,6 @@ Ni all y gosodydd gysylltu â'r gronfa ddata. - Methwyd achub y ffeil web.config. Ceisiwch newid y llinyn gyswllt yn uniongyrchol. Canfwyd eich cronfa ddata ac mae'n cael ei adnabod fel Ffurfwedd gronfa ddata @@ -970,7 +969,6 @@ Mae cyfrinair y defnyddiwr Diofyn wedi'i newid yn llwyddiannus ers y gosodiad!

    Does dim angen unrhyw weithredoedd pellach. Cliciwch Nesaf i barhau.]]> Mae'r cyfrinair wedi'i newid! Cewch gychwyn gwych, gwyliwch ein fideos rhaglith - Wrth glicio'r botwm nesaf (neu newid y umbracoConfigurationStatus yn web.config), rydych yn derbyn y trwydded ar gyfer y meddalwedd yma fel y nodir yn y blwch isod. Sylwch fod y dosbarthiad Umbraco yma yn cynnwys 2 drwydded gwahanol, y trwydded cod agored MIT ar gyfer y fframwaith ac y trwydded Umbraco rhadwedd sy'n ymdrin â'r Rhyngwyneb Defnyddiwr. Heb osod eto. Ffeiliau a ffolderi wedi'u effeithio Mwy o wybodaeth am osod hawliau ar gyfer Umbraco yma @@ -1053,10 +1051,6 @@ Rydych wedi gosod Runway, felly beth am weld sut mae eich gwefan newydd yn edryc Cewch gymorth o'n cymuned gwobrwyol, porwch drwy ein dogfennaeth neu gwyliwch fideos yn rhad ac am ddim ar sut i adeiladu gwefan syml, sut i ddefnyddio pecynnau a chanllaw cyflym i dermeg Umbraco]]> Mae Umbraco wedi'i osod %0% ac mae'n barod i'w ddefnyddio - - /web.config a diweddaru'r allwedd AppSetting UmbracoConfigurationStatus yng ngwaelod y gwerth o '%0%'.]]> - yn syth wrth glicio ar y botwm "Cychwyn Umbraco" isod.
    Os ydych yn newydd i Umbraco, gallwch ddarganfod digonedd o adnoddau ar ein tudalennau cychwyn allan.]]> @@ -2407,8 +2401,6 @@ Er mwyn gweinyddu eich gwefan, agorwch swyddfa gefn Umbraco a dechreuwch ychwang Mae tystysgrif SSL eich gwefan am derfynu mewn %0% diwrnod. Gwall yn pingio'r URL %0% - '%1%' Rydych yn bresennol %0% yn gweld y wefan yn defnyddio'r cynllun HTTPS. - Mae'r appSetting 'umbracoUseSSL' wedi'i osod at 'false' yn eich ffeil web.config. Unwaith rydych yn ymweld â'r safle gan ddefnyddio'r cynllun HTTPS, dylai hynny gael ei osod i 'true'. - Mae'r appSetting 'umbracoUseSSL' wedi'i osod at '%0%' yn eich ffeil web.config, mae eich cwcis %1% marcio yn ddiogel. Ni ellir diweddaru'r gosodiad 'umbracoUseSSL' yn eich ffeil web.config. Gwall: %0% Galluogi HTTPS @@ -2459,10 +2451,7 @@ Er mwyn gweinyddu eich gwefan, agorwch swyddfa gefn Umbraco a dechreuwch ychwang --> %0%.]]> Dim peniadau sy'n datgelu gwynodaeth am dechnoleg eich gwefan wedi'u canfod. - Ni ellir darganfod system.net/mailsettings yn y ffeil Web.config. - Yn yr adran system.net/mailsettings o'r ffeil Web.config, nid yw'r "host" wedi ffurfweddu. Gosodiadau SMTP wedi ffurfweddu'n gywir ac mae'r gwasanaeth yn gweithio fel y disgwylir. - Ni ellir cysylltu â gweinydd SMTP sydd wedi ffurfweddu gyda "host" '%0%' a phorth '%1%'. Gwiriwch fod y gosodiadau SMTP yn y ffeil Web.config, system.net/mailsettings yn gywir. %0%.]]> %0%.]]>

    Canlyniadau'r gwiriad Statws Iechyd Umbraco ar amserlen rhedwyd ar %0% am %1% fel y ganlyn:

    %2%]]>
    diff --git a/src/Umbraco.Web.UI/umbraco/config/lang/da.xml b/src/Umbraco.Web.UI/umbraco/config/lang/da.xml index e1ea44225e4e..7e29e6b9784f 100644 --- a/src/Umbraco.Web.UI/umbraco/config/lang/da.xml +++ b/src/Umbraco.Web.UI/umbraco/config/lang/da.xml @@ -18,10 +18,10 @@ Slet Deaktivér Edit settings - Tøm papirkurv + Tøm papirkurv Aktivér Eksportér dokumenttype - Importér dokumenttype + Importér dokumenttype Importér pakke Redigér i Canvas Log af diff --git a/src/Umbraco.Web.UI/umbraco/config/lang/de.xml b/src/Umbraco.Web.UI/umbraco/config/lang/de.xml index cc9b047bc462..8f2ba350d0a6 100644 --- a/src/Umbraco.Web.UI/umbraco/config/lang/de.xml +++ b/src/Umbraco.Web.UI/umbraco/config/lang/de.xml @@ -16,10 +16,10 @@ Neue Gruppe Entfernen Deaktivieren - Papierkorb leeren + Papierkorb leeren Aktivieren Dokumenttyp exportieren - Dokumenttyp importieren + Dokumenttyp importieren Paket importieren 'Canvas'-Modus starten Abmelden @@ -765,7 +765,6 @@ Mit dieser Datenbank kann leider keine Verbindung hergestellt werden. - Die "web.config"-Datei konnte nicht angepasst werden (Zugriffsrechte?). Bitte passen Sie die Verbindungszeichenfolge manuell an. Die Datenbank ist erreichbar und wurde identifiziert als Datenbank @@ -774,13 +773,6 @@ ]]> Die Datenbank wurde für Umbraco %0% konfiguriert. Klicken Sie auf <strong>weiter</strong>, um fortzufahren. - - Die angegebene Datenbank ist leider nicht erreichbar. Bitte prüfen Sie die Verbindungszeichenfolge ("Connection String") in der "web.config"-Datei.

    -

    Um fortzufahren, passen Sie bitte die "web.config"-Datei mit einem beliebigen Text-Editor an. Scrollen Sie dazu nach unten, fügen Sie die Verbindungszeichenfolge für die zuverbindende Datenbank als Eintrag "UmbracoDbDSN" hinzu und speichern Sie die Datei.

    -

    Klicken Sie nach erfolgter Anpassung auf Wiederholen.
    Wenn Sie weitere technische Informationen benötigen, besuchen Sie The Umbraco documentation wik.

    - ]]> -
    Um diesen Schritt abzuschließen, müssen Sie die notwendigen Informationen zur Datenbankverbindung angeben.<br />Bitte kontaktieren Sie Ihren Provider bzw. Server-Administrator für weitere Informationen. <strong>Das Kennwort des Standard-Benutzers wurde seit der Installation verändert.</strong></p><p>Es sind keine weiteren Aktionen notwendig. Klicken Sie auf <b>Weiter</b> um fortzufahren. Das Kennwort wurde geändert! Schauen Sie sich die Einführungsvideos für einen schnellen und einfachen Start an. - Mit der Installation stimmen Sie der angezeigten Lizenz für diese Software zu. Bitte beachten Sie, dass diese Umbraco-Distribution aus zwei Lizenzen besteht. Einer freien Open-Source MIT-Lizenz für das Framework und der Umbraco-Freeware-Lizenz für die Verwaltungsoberfläche. Noch nicht installiert. Betroffene Verzeichnisse und Dateien Weitere Informationen zum Thema "Dateiberechtigungen" für Umbraco @@ -854,7 +845,6 @@ <h3>Zur neuen Seite</h3>Sie haben Runway installiert, schauen Sie sich doch mal auf Ihrer Website um. <h3>Weitere Hilfe und Informationen</h3>Hilfe von unserer preisgekrönten Community, Dokumentation und kostenfreie Videos, wie Sie eine einfache Website erstellen, ein Packages nutzen und eine schnelle Einführung in alle Umbraco-Begriffe Umbraco %0% wurde installiert und kann verwendet werden - Um die Installation abzuschließen, müssen Sie die <strong>"web.config"-Datei</strong> von Hand anpassen und den AppSetting-Schlüssel <strong>UmbracoConfigurationStatus</strong> auf den Wert <strong>'%0%'</strong> ändern. Sie können <strong>sofort starten</strong>, in dem Sie auf "Umbraco starten" klicken. <h3>Umbraco starten</h3>Um Ihre Website zu verwalten, öffnen Sie einfach den Administrationsbereich und beginnen Sie damit, Inhalte hinzuzufügen sowie Vorlagen und Stylesheets zu bearbeiten oder neue Funktionen einzurichten Verbindung zur Datenbank fehlgeschlagen. @@ -2004,8 +1994,6 @@ Ihr Website-Zertifikat (SSL) wird in %0% Tagen ablaufen. Fehler beim PINGen der URL %0% - '%1%' Sie betrachten diese Website %0% unter Verwendung des HTTPS-Schemas. - Der Schlüssel 'Umbraco.Core.UseHttps' im Abschnitt 'appSettings' der 'web.config'-Datei ist auf 'false' gesetzt. Sobald Sie diese Site über HTTPS nutzen, sollte dieser auf 'true' gestellt werden. - Der Schlüssel 'Umbraco.Core.UseHttps' im Abschnitt 'appSettings' der 'web.config'-Datei ist auf '%0%' gesetzt, Cookies sind %1% als sicher markiert. 'Debug' Kompilierungsmodus ist abgeschaltet. 'Debug' Kompilierungsmodus ist gegenwertig eingeschaltet. Es ist empfehlenswert diesen vor Live-Gang abzuschalten. Modo Debug en compilación está desactivado. Modo Debug en compilación está activado. Se recomienda desactivarlo antes de publicar el sitio. @@ -1528,10 +1522,7 @@ --> %0%.]]> No se ha encontrado ninguna cabecera que revele información sobre la tecnología del sitio. - No se encontró system.net/mailsettings en Web.config. - En la sección system.net/mailsettings section de web.config, el host no está configurado. Los valores SMTP están configurados correctamente y el servicio opera con normalidad. - El servidor SMTP configurado con host '%0%' y puerto '%1%' no se pudo alcanzar. Por favor revisa que la configuración en la sección system.net/mailsettings del archivo Web.config es correcta. %0%.]]> %0%.]]>

    Los resultados de los Chequeos de Salud de Umbraco programados para ejecutarse el %0% a las %1% son:

    %2%]]>
    diff --git a/src/Umbraco.Web.UI/umbraco/config/lang/fr.xml b/src/Umbraco.Web.UI/umbraco/config/lang/fr.xml index 1caf58cf6034..786104e6e57d 100644 --- a/src/Umbraco.Web.UI/umbraco/config/lang/fr.xml +++ b/src/Umbraco.Web.UI/umbraco/config/lang/fr.xml @@ -16,10 +16,10 @@ Créer un groupe Supprimer Désactiver - Vider la corbeille + Vider la corbeille Activer Exporter le type de document - Importer un type de document + Importer un type de document Importer un package Editer dans Canvas Déconnexion @@ -388,6 +388,7 @@ Nom Fermer cette fenêtre Êtes-vous certain(e) de vouloir supprimer + %0% des %1% éléments]]> Êtes-vous certain(e) de vouloir désactiver Êtes-vous certain(e)? Êtes-vous certain(e)? @@ -773,19 +774,12 @@ Le programme d'installation ne parvient pas à se connecter à la base de données. - Impossible de sauvegarder le fichier web.config. Veuillez modifier la "connection string" manuellement. Votre base de données a été détectée et est identifiée comme étant Configuration de la base de données installer pour installer la base de données Umbraco %0% ]]> Suivant pour poursuivre.]]> - Base de données non trouvée ! Veuillez vérifier les informations de la "connection string" dans le fichier web.config.

    -

    Pour poursuivre, veuillez éditer le fichier "web.config" (avec Visual Studio ou votre éditeur de texte favori), scroller jusqu'en bas, ajouter le "connection string" pour votre base de données dans la ligne avec la clé "umbracoDbDSN" et sauvegarder le fichier.

    -

    - Cliquez sur le bouton Réessayer lorsque cela est fait. -
    - Plus d'informations sur l'édition du fichier web.config ici.

    ]]>
    Veuillez contacter votre fournisseur de services internet si nécessaire. Si vous installez Umbraco sur un ordinateur ou un serveur local, vous aurez peut-être besoin de consulter votre administrateur système.]]> @@ -804,7 +798,6 @@ Le mot de passe par défaut a été modifié avec succès depuis l'installation!

    Aucune autre action n'est requise. Cliquez sur Suivant pour poursuivre.]]> Le mot de passe a été modifié ! Pour bien commencer, regardez nos vidéos d'introduction - En cliquant sur le bouton "Suivant" (ou en modifiant umbracoConfigurationStatus dans le fichier web.config), vous acceptez la licence de ce logiciel telle que spécifiée dans le champ ci-dessous. Veuillez noter que cette distribution Umbraco consiste en deux licences différentes, la licence open source MIT pour le framework et la licence Umbraco freeware qui couvre l'UI. Pas encore installé. Fichiers et dossiers concernés Plus d'informations sur la configuration des permissions @@ -867,8 +860,6 @@ Vous avez installé Runway, alors pourquoi ne pas jeter un oeil au look de votre Aide et informations complémentaires Obtenez de l'aide de notre communauté "award winning", parcourez la documentation ou regardez quelques vidéos gratuites sur la manière de construire un site simple, d'utiliser les packages ainsi qu'un guide rapide sur la terminologie Umbraco]]> Umbraco %0% est installé et prêt à être utilisé - fichier /web.config et mettre à jour le paramètre AppSetting umbracoConfigurationStatus situé en bas à la valeur '%0%'.]]> démarrer instantanément en cliquant sur le bouton "Lancer Umbraco" ci-dessous.
    Si vous débutez avec Umbraco, vous pouvez trouver une foule de ressources dans nos pages "Getting Started".]]>
    Lancer Umbraco @@ -1971,8 +1962,6 @@ Pour gérer votre site, ouvrez simplement le backoffice Umbraco et commencez à Le certificat SSL de votre site web va expirer dans %0% jours. Erreur en essayant de contacter l'URL %0% - '%1%' Vous êtes actuellement %0% à voir le site via le schéma HTTPS. - La valeur appSetting 'Umbraco.Core.UseHttps' est fixée à 'false' dans votre fichier web.config. Une fois que vous donnerez accès à ce site en utilisant le schéma HTTPS, cette valeur devra être mise à 'true'. - La valeur appSetting 'Umbraco.Core.UseHttps' est fixée à '%0%' dans votre fichier web.config, vos cookies sont %1% marqués comme étant sécurisés. Le mode de compilation Debug est désactivé. Le mode de compilation Debug est actuellement activé. Il est recommandé de désactiver ce paramètre avant la mise en ligne. @@ -1998,10 +1987,7 @@ Pour gérer votre site, ouvrez simplement le backoffice Umbraco et commencez à --> %0%.]]> Aucun header révélant des informations à propos de la technologie du site web n'a été trouvé. - La section system.net/mailsettings n'a pas pu être trouvée dans le fichier Web.config. - Dans la section system.net/mailsettings du fichier Web.config, le "host" n'est pas configuré. La configuration SMTP est correcte et le service fonctionne comme prévu. - Le serveur SMTP configuré avec le host '%0%' et le port '%1%' n'a pas pu être contacté. Veuillez vérifier et vous assurer que la configuration SMTP est correcte dans la section system.net/mailsettings du fichier Web.config. %0%.]]> %0%.]]>

    Les résultats de l'exécution du Umbraco Health Checks planifiée le %0% à %1% sont les suivants :

    %2%]]>
    diff --git a/src/Umbraco.Web.UI/umbraco/config/lang/he.xml b/src/Umbraco.Web.UI/umbraco/config/lang/he.xml index ee03ca6fc9ea..9ee8bbf014ec 100644 --- a/src/Umbraco.Web.UI/umbraco/config/lang/he.xml +++ b/src/Umbraco.Web.UI/umbraco/config/lang/he.xml @@ -13,9 +13,9 @@ צור חבילה מחק נטרל - רוקן סל מיחזור + רוקן סל מיחזור ייצא סוג קובץ - ייבא סוג מסמך + ייבא סוג מסמך ייבא חבילה ערוך במצב "קנבס" יציאה @@ -346,19 +346,12 @@ ההתקנה לא מצליחה להתחבר לבסיס הנתונים. - אין אפשרות לשמור את הקובץ Web.config file. הגדר את ה- connection string באופן ידני. בסיס הנתונים שלך נמצא והוא מזוהה כ הגדרת בסיס נתונים 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.]]> @@ -377,7 +370,6 @@ The Default user's password has been successfully changed since the installation!

    No further actions needs to be taken. Click Next to proceed.]]> הסיסמה שונתה! התחל מכאן, צפה בסרטוני ההדרכה עבור אומברקו - על ידי לחיצה על 'הבא', הנך מאשר את פרטי התקנון כפי שמפורט בתיבת הטקטס למטה. שים לב, הפצה זו של אומברקו כוללת שני גירסאות שונות של רשיון,קוד פתוח ברשיון MIT עבור ה- framework ורשיון Umbraco freeware המכסה את ה- UI. לא הותקן עדיין. קבצים ותיקיות המושפעים מידע נוסף אודות התקנה ורשאות עבור אומרקו ניתן לקרוא כאן @@ -440,8 +432,6 @@ 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]]> אומברקו %0% מותקנת ומוכנה לשימוש - /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 diff --git a/src/Umbraco.Web.UI/umbraco/config/lang/it.xml b/src/Umbraco.Web.UI/umbraco/config/lang/it.xml index ffc1e8272b8d..a0d89bff2df4 100644 --- a/src/Umbraco.Web.UI/umbraco/config/lang/it.xml +++ b/src/Umbraco.Web.UI/umbraco/config/lang/it.xml @@ -917,8 +917,6 @@ - - @@ -928,14 +926,6 @@ Avanti per proseguire.]]> - - Database non trovato! Perfavore, controlla che le informazioni della stringa di connessione nel file "web.config" siano corrette.

    -

    Per procedere, modifica il file "web.config" (utilizzando Visual Studio o l'editor di testo che preferisci), scorri in basso, aggiungi la stringa di connessione per il database nel parametro chiamato "umbracoDbDSN" e salva il file.

    -

    - Clicca il tasto riprova quando hai - finito.
    - Maggiori dettagli per la modifica del file web.config qui.

    ]]> -
    Se è necessario contatta il tuo ISP per reperire le informazioni necessarie. @@ -964,8 +954,6 @@ La password dell'utente di default è stata modificata con successo

    Non è necessario eseguire altre operazioni. Clicca il tasto Avanti per continuare.]]> - - @@ -1053,10 +1041,6 @@ Hai installato Runway, quindi perché non dare uno sguardo al vostro nuovo sito Fatti aiutare dalla nostra community, consulta la documentazione o guarda alcuni video gratuiti su come costruire un semplice sito web, come usare i pacchetti e una guida rapida alla terminologia Umbraco]]> - - /web.config e aggiornare la chiave AppSetting UmbracoConfigurationStatus impostando il valore '%0%'.]]> - iniziare immediatamente cliccando sul bottone "Avvia Umbraco".
    Se sei nuovo su Umbraco, si possono trovare un sacco di risorse sulle nostre pagine Getting Started.]]> diff --git a/src/Umbraco.Web.UI/umbraco/config/lang/ja.xml b/src/Umbraco.Web.UI/umbraco/config/lang/ja.xml index 9775668df9ef..4b98adad2659 100644 --- a/src/Umbraco.Web.UI/umbraco/config/lang/ja.xml +++ b/src/Umbraco.Web.UI/umbraco/config/lang/ja.xml @@ -14,9 +14,9 @@ パッケージの作成 削除 無効 - ごみ箱を空にする + ごみ箱を空にする ドキュメントタイプの書出 - ドキュメントタイプの読込 + ドキュメントタイプの読込 パッケージの読み込み ライブ編集 ログアウト @@ -461,19 +461,12 @@ インストーラーはデータベースに接続できませんでした。 - web.configファイルを保存できませんでした。接続文字列を手作業で編集してください。 データベースが見つかりました。識別子: データベースの設定 インストールボタンを押すと Umbraco %0% のデータベースへインストールします ]]> 次へを押して続行してください。]]> - データベースを見つけられません!"web.config"ファイルの中の"接続文字列"を確認してください。

    -

    続行するには"web.config"ファイルを編集(Visual Studioないし使い慣れたテキストエディタで)し、下の方にスクロールし、"umbracoDbDSN"という名前のキーでデータベースの接続文字列を追加して保存します。

    -

    - 再施行ボタンをクリックして - 続けます。
    - より詳細にはこちらの web.config を編集します。

    ]]>
    必要ならISPに連絡するなどしてみてください。 もしローカルのパソコンないしサーバーへインストールするのなら、システム管理者に情報を確認してください。]]> @@ -492,7 +485,6 @@ インストール後にデフォルトユーザーのパスワードが変更されています!

    これ以上のアクションは必要ありません。次へをクリックして続行してください。]]> パスワードは変更されました! 始めに、ビデオによる解説を見ましょう - 次へボタンをクリック(またはweb.configのumbracoConfigurationStatusを編集)すると、あなたはここに示されるこのソフトウェアのライセンスを承諾したと見做されます。注意として、UmbracoはMITライセンスをフレームワークへ、フリーウェアライセンスをUIへ、それぞれ異なる2つのライセンスを採用しています。 まだインストールは完了していません。 影響するファイルとフォルダ Umbracoに必要なアクセス権の設定についての詳細はこちらをどうぞ @@ -555,8 +547,6 @@ Runwayをインストールして作られた新しいウェブサイトがど 追加の情報と手助け 我々の認めるコミュニティから手助けを得られるでしょう。どうしたら簡単なサイトを構築できるか、どうしたらパッケージを使えるかについてのビデオや文書、またUmbracoの用語のクイックガイドも見る事ができます。]]> Umbraco %0% のインストールは完了、準備が整いました - /web.config fileを手作業で編集し、'%0%'の下にあるumbracoConfigurationStatusキーを設定してください。]]> 今すぐ開始できます。
    もしUmbracoの初心者なら、 私たちの初心者向けのたくさんの情報を参考にしてください。]]>
    Umbracoの開始 diff --git a/src/Umbraco.Web.UI/umbraco/config/lang/ko.xml b/src/Umbraco.Web.UI/umbraco/config/lang/ko.xml index 1bf5d052ddd4..792dd6700c2f 100644 --- a/src/Umbraco.Web.UI/umbraco/config/lang/ko.xml +++ b/src/Umbraco.Web.UI/umbraco/config/lang/ko.xml @@ -13,9 +13,9 @@ 패키지 새로 만들기 삭제 비활성 - 휴지통 비우기 + 휴지통 비우기 추출 문서 유형 - 등록 문서 유형 + 등록 문서 유형 패키지 등록 캔버스 내용 편집 종료 @@ -346,16 +346,10 @@ 인스톨러가 데이터베이스에 연결할 수 없습니다. - web.config를 저장할 수 없습니다.connection string을 수동으로 수정하세요. 데이터베이스가 확인되었으며 정보는 데이터베이스 설정 설치 버튼을 누르면 Umbraco %0% 데이터베이스가 설치됩니다.]]> 다음을 누르세요.]]> - 데이터베이스를 찾을 수 없습니다. “web.config”파일의 "connection string"이 바르게 설정되었는지 확인하세요.

    -

    "web.config" 파일에 맨아래에 ,키네임을 "UmbracoDbDSN"로 하여 사용하시는 데이터베이스의 connection string 정보를 입력하시고 파일을 저장하세요.

    -

    - 완료 후재시도버튼을 누르세요.
    - web.config의 더많은 정보는 여기에 있습니다.

    ]]>
    필요하시다면 사용하시는 ISP쪽에 문의하시기 바랍니다.. 로컬 머신이나 서버에 설치되어 있다면 해당 시스템 관리자에게 문의하시기 바랍니다.]]> @@ -367,7 +361,6 @@ 설치후 기본사용자의 암호가 성공적으로 변경되었습니다!

    더 이상 과정이 필요없으시면 다음을 눌러주세요.]]> 비밀번호가 변경되었습니다! 편리한 시작을 위해, 소개 Video를 시청하세요 - 다음버튼을 누르시면 (또는Web.config에 UmbracoConfigurationStatus를 수정하시면), 여러분은 아래에 명시된 소프트웨어 라이센스를 수락합니다. Umbraco 배포는 2가지 다른 라이센스로 구성되어 있습니다. 프레임워크에는 오픈소스 MIT라이센스가 UI에는 Umbraco 프리웨어 라이센스가 적용됩니다. 아직 설치되지 않았습니다. 영향받는 파일과 폴더 Umbraco권한관리을 위해 더정보가 필요하시면 여기를 누르세요 @@ -427,7 +420,6 @@ 고급 도움말과 정보 우수 커뮤니티에서 도음을 받으세요. 간단한 사이트제작이나 패키지 사용법, Umbraco기술의 퀵가이드를 제공하는 문서를 보시거나 무료 비디오를 시청하세요.]]> Umbraco %0% 가 설치되어 사용준비가 되었습니다. - /web.config file을 수동으로 편집해야 합니다. AppSetting 키의 UmbracoConfigurationStatus'%0%'의 값으로 설정하세요.]]> Umbraco 와 첫만남이시면
    아래의 "Umbraco 접속하기" 버튼을 클릭하여 즉시 시작하실 수 있습니다. 시작페이지에서 풍부한 리소소를 제공받을 수 있습니다.]]>
    Umbraco 실행 diff --git a/src/Umbraco.Web.UI/umbraco/config/lang/nb.xml b/src/Umbraco.Web.UI/umbraco/config/lang/nb.xml index 9f518fa319ef..1c4796918973 100644 --- a/src/Umbraco.Web.UI/umbraco/config/lang/nb.xml +++ b/src/Umbraco.Web.UI/umbraco/config/lang/nb.xml @@ -14,9 +14,9 @@ Opprett pakke Slett Deaktiver - Tøm papirkurv + Tøm papirkurv Eksporter dokumenttype - Importer dokumenttype + Importer dokumenttype Importer pakke Rediger i Canvas Logg av @@ -411,12 +411,10 @@ Installasjonsprogrammet kan ikke koble til databasen - Kunne ikke lagre Web.Config-filen. Vennligst endre databasens tilkoblingsstreng manuelt. Din database er funnet og identifisert som Databasekonfigurasjon installer-knappen for å installere Umbraco %0% databasen]]> Neste for å fortsette.]]> - Databasen ble ikke funnet! Vennligst sjekk at informasjonen i "connection string" i "web.config"-filen er korrekt.

    For å fortsette, vennligst rediger "web.config"-filen (bruk Visual Studio eller din favoritteditor), rull ned til bunnen, og legg til tilkoblingsstrengen for din database i nøkkelen "umbracoDbDSN" og lagre filen.

    Klikk prøv på nytt når du er ferdig.
    Mer informasjon om redigering av web.config her.

    ]]>
    Vennligst kontakt din ISP om nødvendig. Hvis du installerer på en lokal maskin eller server, må du kanskje skaffe informasjonen fra din systemadministrator.]]> Trykk på knappen oppgrader for å oppgradere databasen din til Umbraco %0%

    Ikke vær urolig - intet innhold vil bli slettet og alt vil fortsette å virke etterpå!

    ]]>
    Trykk Neste for å fortsette.]]> @@ -426,7 +424,6 @@ Passordet til standardbrukeren har blitt forandret etter installasjonen!

    Ingen videre handling er nødvendig. Klikk Neste for å fortsette.]]> Passordet er blitt endret! Få en god start med våre introduksjonsvideoer - Ved å klikke på Neste-knappen (eller endre UmbracoConfigurationStatus i Web.config), godtar du lisensen for denne programvaren som angitt i boksen nedenfor. Legg merke til at denne Umbraco distribusjon består av to ulike lisenser, åpen kilde MIT lisens for rammen og Umbraco frivareverktøy lisens som dekker brukergrensesnittet. Ikke installert. Berørte filer og mapper Mer informasjon om å sette opp rettigheter for Umbraco her @@ -460,7 +457,6 @@ Se ditt nye nettsted Du har installert Runway, hvorfor ikke se hvordan ditt nettsted ser ut.]]> Mer hjelp og info Få hjelp fra vårt prisbelønte samfunn, bla gjennom dokumentasjonen eller se noen gratis videoer på hvordan man bygger et enkelt nettsted, hvordan bruke pakker og en rask guide til Umbraco terminologi]]> Umbraco %0% er installert og klar til bruk - web.config filen, og oppdatere AppSetting-nøkkelen UmbracoConfigurationStatus til verdien '%0%']]> starte øyeblikkelig ved å klikke på "Start Umbraco" knappen nedenfor.
    Hvis du er ny på Umbraco, kan du finne mange ressurser på våre komme-i-gang sider.]]>
    Start Umbraco For å administrere din webside, åpne Umbraco og begynn å legge til innhold, oppdatere maler og stilark eller utvide funksjonaliteten]]> Tilkobling til databasen mislyktes. diff --git a/src/Umbraco.Web.UI/umbraco/config/lang/nl.xml b/src/Umbraco.Web.UI/umbraco/config/lang/nl.xml index 3ef84f2354d2..cd675f7056e1 100644 --- a/src/Umbraco.Web.UI/umbraco/config/lang/nl.xml +++ b/src/Umbraco.Web.UI/umbraco/config/lang/nl.xml @@ -18,10 +18,10 @@ Verwijderen Uitschakelen Instellingen wijzigen - Prullenbak leegmaken + Prullenbak leegmaken Inschakelen Documenttype exporteren - Documenttype importeren + Documenttype importeren Package importeren Aanpassen in Canvas Afsluiten @@ -867,17 +867,12 @@ De installer kan geen connectie met de database maken. - De web.config kon niet worden opgeslagen. Gelieve de connectiestring handmatig - aan te passen. - Je database is gevonden en is geïdentificeerd als Database configuratie installeren om de Umbraco %0% database te installeren]]> Volgende om door te gaan.]]> - - De database kon niet gevonden worden! Gelieve na te kijken of de informatie in de "connection string" van het "web.config" bestand correct is.

    Om door te gaan, gelieve het "web.config" bestand aan te passen (met behulp van Visual Studio of je favoriete tekstverwerker), scroll in het bestand naar beneden, voeg de connection string voor je database toe in de key met naam "umbracoDbDSN" en sla het bestand op.

    Klik op de knop opnieuw proberen als je hiermee klaar bent.
    Meer informatie over het aanpassen van de web.config vind je hier.

    ]]>
    Gelieve contact op te nemen met je ISP indien nodig. Wanneer je installeert op een lokale computer of server, dan heb je waarschijnlijk informatie nodig van je systeembeheerder.]]> @@ -894,9 +889,6 @@ Het wachtwoord van de default gebruiker is sinds installatie met succes veranderd.

    Geen verdere actie noodzakelijk. Klik Volgende om verder te gaan.]]> Het wachtwoord is veranderd! Neem een jumpstart en bekijk onze introductie videos - Nog niet geïnstalleerd. Betreffende bestanden en mappen Meer informatie over het instellen van machtigingen voor Umbraco @@ -951,8 +943,6 @@ Echter, Runway biedt een gemakkelijke basis om je snel op weg te helpen. Als je Meer hulp en informatie Vind hulp in onze bekroonde community, blader door de documentatie of bekijk enkele gratis videos over het bouwen van een eenvoudige site, het gebruiken van packages en een overzicht van Umbraco terminologie]]> Umbraco %0% is geïnstalleerd en klaar voor gebruik. - - /web.config bestand aanpassen, en de Appsetting key UmbracoConfigurationStatus onder in het bestand veranderen naar '%0%'.]]> meteen beginnen door de "Launch Umbraco" knop hieronder te klikken.
    Als je een beginnende Umbraco gebruiker bent, dan kun je you can find veel informatie op onze "getting started" pagina's vinden.]]>
    @@ -2106,12 +2096,6 @@ Echter, Runway biedt een gemakkelijke basis om je snel op weg te helpen. Als je Het SSL certificaat van de website zal vervallen binnen %0% dagen. Fout bij pingen van URL %0% - '%1%' De site wordt momenteel %0% bekeken via HTTPS. - De appSetting 'Umbraco.Core.UseHttps' in web.config staat op - 'false'. Indien HTTPS gebruikt wordt moet deze op 'true' staan. - - De appSetting 'Umbraco.Core.UseHttps' in web.config is ingesteld op - '%0%'. Cookies zijn %1% ingesteld als secure. - Debug compilatie mode staat uit. Debug compilatie mode staat momenteel aan. Wij raden aan deze @@ -2150,15 +2134,8 @@ Echter, Runway biedt een gemakkelijke basis om je snel op weg te helpen. Als je Er zijn geen headers gevonden die informatie vrijgeven over de gebruikte website technologie! - In de Web.config werd system.net/mailsettings niet gevonden - In de Web.config sectie system.net/mailsettings is de host niet - geconfigureerd. - SMTP instellingen zijn correct ingesteld en werken zoals verwacht. - De SMTP server geconfigureerd met host '%0%' en poort '%1%' kon niet - gevonden worden. Controleer of de SMTP instellingen in Web.config file system.net/mailsettings correct zijn. - %0%.]]> diff --git a/src/Umbraco.Web.UI/umbraco/config/lang/pl.xml b/src/Umbraco.Web.UI/umbraco/config/lang/pl.xml index 77e01ae766b3..dfbc324df603 100644 --- a/src/Umbraco.Web.UI/umbraco/config/lang/pl.xml +++ b/src/Umbraco.Web.UI/umbraco/config/lang/pl.xml @@ -15,10 +15,10 @@ Stwórz grupę Usuń Deaktywuj - Opróżnij kosz + Opróżnij kosz Aktywuj Eksportuj typ dokumentu - Importuj typ dokumentu + Importuj typ dokumentu Importuj zbiór Edytuj na stronie Wyjście @@ -576,19 +576,12 @@ Instalator nie mógł połączyć się z bazą danych. - Nie udało się zapisać pliku web.config. Zmodyfikuj parametry połączenia ręcznie. Twoja baza danych została znaleziona i zidentyfikowana jako Konfiguracja bazy danych instaluj, aby zainstalować bazę danych Umbraco %0% ]]> Dalej, aby kontynuować.]]> - Nie odnaleziono bazy danych! Sprawdź, czy informacje w sekcji "connection string" w pliku "web.config" są prawidłowe.

    -

    Aby kontynuować, dokonaj edycji pliku "web.config" (używając Visual Studio lub dowolnego edytora tekstu), przemieść kursor na koniec pliku, dodaj parametry połączenia do Twojej bazy danych w kluczu o nazwie "umbracoDbDSN" i zapisz plik.

    -

    - Kliknij ponów próbę kiedy - skończysz.
    - Tu znajdziesz więcej informacji na temat edycji pliku "web.config".

    ]]>
    Skontaktuj się z Twoim dostawą usług internetowych jeśli zajdzie taka potrzeba. W przypadku instalacji na lokalnej maszynie lub serwerze możesz potrzebować pomocy administratora.]]> @@ -607,7 +600,6 @@ Naciśnij przycisk instaluj, aby zainstalować bazę danych Umb Hasło domyślnego użytkownika zostało zmienione od czasu instalacji!

    Żadne dodatkowe czynności nie są konieczne. Naciśnij Dalej, aby kontynuować.]]> Hasło zostało zmienione! Aby szybko wejść w świat Umbraco, obejrzyj nasze filmy wprowadzające - Klikając przycisk dalej (lub modyfikując klucz UmbracoConfigurationStatus w pliku web.config), akceptujesz licencję na niniejsze oprogramowanie zgodnie ze specyfikacją w poniższym polu. Zauważ, że ta dystrybucja Umbraco składa się z dwoch licencji - licencja MIT typu open source dla kodu oraz licencja "Umbraco freeware", która dotyczy interfejsu użytkownika. Nie zainstalowane. Zmienione pliki i foldery Więcej informacji na temat ustalania pozwoleń dla Umbraco znajdziesz tutaj @@ -670,8 +662,6 @@ Naciśnij przycisk instaluj, aby zainstalować bazę danych Umb Dalsza pomoc i informacje Zaczerpnij pomocy z naszej nagrodzonej społeczności, przeglądaj dokumentację lub obejrzyj niektóre darmowe filmy o tym, jak budować proste strony, jak używać pakietów i szybki przewodnik po terminologii Umbraco]]> Umbraco %0% zostało zainstalowane i jest gotowe do użycia - plik web.config i zaktualizować klucz AppSetting o nazwie UmbracoConfigurationStatus na dole do wartości '%0%'.]]> rozpocząć natychmiast klikając przycisk "Uruchom Umbraco" poniżej.
    Jeżeli jesteś nowy dla Umbraco znajdziesz mnóstwo materiałów na naszych stronach "jak rozpocząć".]]>
    Uruchom Umbraco @@ -1345,8 +1335,6 @@ Naciśnij przycisk instaluj, aby zainstalować bazę danych Umb Certyfikat SSL Twojej strony wygaśnie za %0% dni. Błąd pingowania adresu URL %0% - '%1%' Oglądasz %0% stronę używając HTTPS. - appSetting 'Umbraco.Core.UseHttps' został ustawiony na 'false' w Twoim pliku web.config. Po uzyskaniu dostępu do strony, używając HTTPS, powinieneś go ustawić na 'true'. - appSetting 'Umbraco.Core.UseHttps' został ustawiony na '%0%' w Twoim pliku web.config, Twoje ciasteczka są %1% ustawione jako bezpieczne. Tryb kompilacji debugowania jest wyłączony. Tryb kompilacji debugowania jest obecnie włączony. Zaleca się wyłączenie tego ustawienia przed wypuszczeniem strony na produkcję. @@ -1363,10 +1351,7 @@ Naciśnij przycisk instaluj, aby zainstalować bazę danych Umb --> %0%.]]> Nie znaleziono żadnych nagłówków, ujawniających informacji o technologii strony. - Nie znaleziono system.net/mailsettings w pliku Web.config. - Host nie jest skonfigurowany w sekcji system.net/mailsettings pliku Web.config. Ustawienia SMTP są skonfigurowane poprawnie i serwis działa według oczekiwań. - Nie można połączyć się z serwerem SMTP skonfigurowanym z hostem '%0%' i portem '%1%'. Proszę sprawdzić ponownie, czy ustawienia system.net/mailsettings w pliku Web.config są poprawne. %0%.]]> %0%.]]> diff --git a/src/Umbraco.Web.UI/umbraco/config/lang/pt.xml b/src/Umbraco.Web.UI/umbraco/config/lang/pt.xml index ad6db137ba18..542b03abc1c7 100644 --- a/src/Umbraco.Web.UI/umbraco/config/lang/pt.xml +++ b/src/Umbraco.Web.UI/umbraco/config/lang/pt.xml @@ -13,9 +13,9 @@ Criar Pacote Remover Desabilitar - Esvaziar Lixeira + Esvaziar Lixeira Exportar Tipo de Documento - Importar Tipo de Documento + Importar Tipo de Documento Importar Pacote Editar na Tela Sair @@ -344,15 +344,10 @@ O instalador não pôde conectar-se ao banco de dados. - Não foi possível salvar o arquivo web.config. Favor modificar a linha de conexão manualmente. Seu banco de dados foi encontrado e identificado como Configuração do Banco de Dados instalar para instalar o banco de dados do Umbraco %0%]]> Próximo para prosseguir.]]> - Banco de dados não encontrado! Favor checar se a informação no "connection string" do "web.config" esteja correta.

    -

    Para prosseguir, favor editar o arquivo "web.config" (usando Visual Studio ou seu editor de texto favorito), role até embaixo, adicione a connection string para seu banco de dados com a chave de nome "UmbracoDbDSN" e salve o arquivo

    -

    Clique o botão tentar novamente quando terminar.
    - Mais informações em como editar o web.config aqui.

    ]]>
    Favor contatar seu provedor de internet ou hospedagem web se necessário. Se você estiver instalando em uma máquina ou servidor local é possível que você precise dessas informações por um administrador de sistema.]]> Pressione o botão atualizar para atualizar seu banco de dados para Umbraco %0%

    @@ -367,7 +362,6 @@ A senha do usuário padrão foi alterada com sucesso desde a instalação!

    Nenhuma ação posterior é necessária. Clique Próximo para prosseguir.]]> Senha foi alterada! Comece com o pé direito, assista nossos vídeos introdutórios - Ao clicar no próximo botão (ou modificando o UmbracoConfigurationStatus no web.config), você aceita a licença deste software cmo especificado na caixa abaixo. Note que esta distribuição de Umbraco consiste em duas licenças diferentes, a licença aberta MIT para a framework e a licença de software livre (freeware) Umbraco que cobre o UI. Nenhum instalado ainda. Pastas e arquivos afetados Mais informações em como configurar permissões para Umbraco aqui @@ -421,7 +415,6 @@ Você instalou Runway, então por que não ver como é seu novo website.]]>Ajuda adicional e informações Consiga ajuda de nossa comunidade ganhadora de prêmios, navegue a documentação e assista alguns vídeos grátis sobre como construir um site simples, como usar pacotes e um guia prático sobre a terminologia Umbraco]]> Umbraco %0% está instalado e pronto para uso - web.config e atualizar a chave AppSettings UmbracoConfigurationStatus no final para '%0%'.]]> iniciar instantâneamente clicando em "Lançar Umbraco" abaixo.
    Se você é novo com Umbraco você pode encontrar vários recursos em nossa página para iniciantes.]]>
    Lançar Umbraco Para gerenciar seu website, simplesmente abra a área administrativa do Umbraco para começar adicionando conteúdo, atualizando modelos e stylesheets e adicionando nova funcionalidade]]> diff --git a/src/Umbraco.Web.UI/umbraco/config/lang/ru.xml b/src/Umbraco.Web.UI/umbraco/config/lang/ru.xml index 6d5a6c154303..9c1d9e12fb2d 100644 --- a/src/Umbraco.Web.UI/umbraco/config/lang/ru.xml +++ b/src/Umbraco.Web.UI/umbraco/config/lang/ru.xml @@ -17,11 +17,11 @@ Значение по умолчанию Удалить Отключить - Очистить корзину + Очистить корзину Включить Экспорт Экспортировать - Импортировать + Импортировать Импортировать пакет Править на месте Выйти @@ -427,7 +427,6 @@ Ваши данные сохранены, но для того, чтобы опубликовать этот документ, Вы должны сначала исправить следующие ошибки: - Текущий провайдер ролей пользователей не поддерживает изменение пароля (необходимо свойству EnablePasswordRetrieval в файле web.config присвоить значение true) %0% уже существует Обнаружены следующие ошибки: Обнаружены следующие ошибки: @@ -661,8 +660,6 @@ Сертификат Вашего веб-сайта отмечен как проверенный. Ошибка проверки сертификата: '%0%' Сейчас Вы %0% просматриваете сайт, используя протокол HTTPS. - Параметр 'Umbraco.Core.UseHttps' в секции 'appSetting' установлен в 'false' в файле web.config. Если Вам необходим доступ к сайту по протоколу HTTPS, нужно установить данный параметр в 'true'. - Параметр 'Umbraco.Core.UseHttps' в секции 'appSetting' в файле установлен в '%0%', значения cookies %1% маркированы как безопасные. Режим компиляции с отладкой выключен. Режим компиляции с отладкой сейчас включен. Рекомендуется выключить перед размещением сайта в сети. @@ -688,10 +685,7 @@ --> %0%.]]> Заголовки, позволяющие выяснить базовую технологию сайта, не обнаружены. - В файле Web.config, не обнаружено параметров работы с отправкой электронной почты (секция 'system.net/mailsettings'). - В файле Web.config в секции 'system.net/mailsettings' не обнаружены настройки почтового хоста. Параметры отправки электронной почты (SMTP) настроены корректно, сервис работает как ожидается. - Сервер SMTP сконфигурирован на использование хоста '%0%' на порту '%1%', который в настоящее время недоступен. Пожалуйста, убедитесь, что настройки SMTP в файле Web.config в секции 'system.net/mailsettings' верны. %0%.]]> %0%.]]>

    Зафиксированы следующие результаты автоматической проверки состояния Umbraco по расписанию, запущенной на %0% в %1%:

    %2%]]>
    @@ -705,18 +699,12 @@ Программа установки не может установить подключение к базе данных. - Невозможно сохранить изменения в файл web.config. Пожалуйста, вручную измените настройки строки подключения к базе данных. База данных обнаружена и идентифицирована как Конфигурация базы данных Установить чтобы установить базу данных Umbraco %0% ]]> Далее для продолжения.]]> - База данных не найдена! Пожалуйста, проверьте настройки строки подключения ("connection string") в файле конфигурации "web.config"

    -

    Для настройки откройте файл "web.config" с помощью любого текстового редактора и добавьте нужную информацию в строку подключения (параметр "UmbracoDbDSN"), - затем сохраните файл.

    -

    Нажмите кнопку "Повторить" когда все будет готово
    - Более подробно о внесении изменений в файл "web.config" рассказано здесь.

    ]]>
    Пожалуйста, свяжитесь с Вашим хостинг-провайдером, если есть необходимость, а если устанавливаете на локальную рабочую станцию или сервер, то получите информацию у Вашего системного администратора.]]> @@ -734,7 +722,6 @@ Пароль пользователя по-умолчанию успешно изменен в процессе установки!

    Нет надобности в каких-либо дальнейших действиях. Нажмите кнопку Далее для продолжения.]]> Пароль изменен! Для начального обзора возможностей системы рекомендуем посмотреть ознакомительные видеоматериалы - Далее (или модифицируя вручную ключ "UmbracoConfigurationStatus" в файле "web.config"), Вы принимаете лицензионное соглашение для данного программного обеспечения, расположенное ниже. Пожалуйста, обратите внимание, что установочный пакет Umbraco отвечает двум различным типам лицензий: лицензии MIT на программные продукты с открытым исходным кодом в части ядра системы и свободной лицензии Umbraco в части пользовательского интерфейса.]]> Система не установлена. Затронутые файлы и папки Более подробно об установке разрешений для Umbraco рассказано здесь @@ -797,8 +784,6 @@ Дальнейшее изучение и помощь Получайте помощь от нашего замечательного сообщества пользователей, изучайте документацию или просматривайте наши свободно распространяемые видео-материалы о том, как создать собственный несложный сайт, как использовать расширения и пакеты, а также краткое руководство по терминологии Umbraco.]]> Система Umbraco %0% установлена и готова к работе - web.config и изменить значение ключа UmbracoConfigurationStatus в секции AppSetting, установив его равным '%0%'.]]> прямо сейчас, воспользовавшись ссылкой "Начать работу с Umbraco".
    Если Вы новичок в мире Umbraco, Вы сможете найти много полезных ссылок на ресурсы на странице "Начало работы".]]>
    Начните работу с Umbraco diff --git a/src/Umbraco.Web.UI/umbraco/config/lang/sv.xml b/src/Umbraco.Web.UI/umbraco/config/lang/sv.xml index 9a00dcdb197b..e0e2235ae98d 100644 --- a/src/Umbraco.Web.UI/umbraco/config/lang/sv.xml +++ b/src/Umbraco.Web.UI/umbraco/config/lang/sv.xml @@ -20,9 +20,9 @@ Standardvärde Ta bort Avaktivera - Töm papperskorgen + Töm papperskorgen Exportera dokumenttyp - Importera dokumenttyp + Importera dokumenttyp Importera paket Redigera i Canvas Logga ut @@ -483,12 +483,10 @@ Installationsprogrammet kan inte ansluta till databasen. - Kunde inte spara filen web.config. Vänligen ändra databasanslutnings-inställningarna manuellt. Din databas har lokaliserats och är identifierad som Databaskonfiguration installera]]> Nästa för att fortsätta.]]> - Databasen kunde inte hittas! Kontrollera att informationen i databasanslutnings-inställningarna i filen "web.config" är rätt.

    För att fortsätta måste du redigera filen "web.config" (du kan använda Visual Studio eller din favorit text-redigerare), bläddra till slutet, lägg till databasanslutnings-inställningarna för din databas i fältet som heter "umbracoDbDSN" och spara filen.

    Klicka på Försök igen knappen när du är klar.
    Mer information om att redigera web.config hittar du här.

    ]]>
    Eventuellt kan du behöva kontakta ditt webb-hotell. Om du installerar på en lokal maskin eller server kan du få informationen från din systemadministratör.]]> Tryck Uppgradera knappen för att uppgradera din databas till Umbraco %0%

    Du behöver inte vara orolig. Inget innehåll kommer att raderas och efteråt kommer allt att fungera som vanligt!

    ]]>
    Tryck Nästa för att fortsätta.]]> @@ -498,7 +496,6 @@ Standardanvändarens lösenord har ändrats sedan installationen!

    Du behöver inte göra något ytterligare här. Klicka Nästa för att fortsätta.]]> Lösenordet är ändrat! Få en flygande start, kolla på våra introduktionsvideor - Genom att klicka på Nästa knappen (eller redigera UmbracoConfigurationStatus i web.config), accepterar du licensavtalet för den här mjukvaran som det är skrivet i rutan nedan. Observera att den här Umbracodistributionen består av två olika licensavtal, "the open source MIT license" för ramverket och "the Umbraco freeware license" som täcker användargränssnittet. Inte installerad än. Berörda filer och mappar Här hittar du mer information om att sätta rättigheter för Umbraco @@ -533,7 +530,6 @@ Besök din nya webbplats Du installerade Runway, så varför inte se hur din nya webbplats ser ut.]]> Ytterligare hjälp och information Få hjälp från våra prisbelönta community, bläddra i dokumentationen eller titta på några gratis videor om hur man bygger en enkel webbplats, hur du använder paket eller en snabbguide till Umbracos terminologi]]> Umbraco %0% är installerat och klart för användning - /web.config filen och ändra AppSettingsnyckeln UmbracoConfigurationStatus på slutet till %0%]]> börja omedelbart genom att klicka på "Starta Umbraco"-knappen nedan.
    Om du är en ny Umbraco användarekan du hitta massor av resurser på våra kom igång sidor.]]>
    Starta Umbraco För att administrera din webbplats öppnar du bara Umbraco backoffice och börjar lägga till innehåll, uppdatera mallar och stilmallar eller lägga till nya funktioner.]]> Anslutningen till databasen misslyckades. diff --git a/src/Umbraco.Web.UI/umbraco/config/lang/tr.xml b/src/Umbraco.Web.UI/umbraco/config/lang/tr.xml index 41794d5d1133..58c0f7f94bfb 100644 --- a/src/Umbraco.Web.UI/umbraco/config/lang/tr.xml +++ b/src/Umbraco.Web.UI/umbraco/config/lang/tr.xml @@ -17,10 +17,10 @@ Sil Devre Dışı Bırak Ayarları düzenle - Geri dönüşüm kutusunu boşalt + Geri dönüşüm kutusunu boşalt Etkinleştir Belge Türünü Dışa Aktar - Belge Türünü İçe Aktar + Belge Türünü İçe Aktar Paketi İçe Aktar Kanvas'ta Düzenle Çıkış @@ -790,7 +790,6 @@ Yükleyici veritabanına bağlanamıyor. - web.config dosyası kaydedilemedi. Lütfen bağlantı dizesini manuel olarak değiştirin. ​​Veritabanınız bulundu ve tanımlandı Veritabanı yapılandırması @@ -799,14 +798,6 @@ ]]> İleri'ye basın.]]> - - ​​ Veritabanı bulunamadı! Lütfen "web.config" dosyasının "bağlantı dizesindeki" bilgilerin doğru olup olmadığını kontrol edin.

    -

    Devam etmek için lütfen "web.config" dosyasını düzenleyin (Visual Studio veya favori metin düzenleyicinizi kullanarak), en alta kaydırın, veritabanınız için "UmbracoDbDSN" adlı anahtara bağlantı dizesini ekleyin ve dosyayı kaydedin.

    -

    - Yeniden dene düğmesini tıklayın. - bitti.
    - Web.config'i düzenleme hakkında daha fazla bilgi burada.

    ]]> -
    Lütfen gerekirse ISS'niz ile iletişime geçin. @@ -831,7 +822,6 @@ Varsayılan kullanıcının şifresi kurulumdan bu yana başarıyla değiştirildi!

    Başka işlem yapılmasına gerek yok. Devam etmek için İleri 'yi tıklayın.]]> Şifre değiştirildi! Harika bir başlangıç ​​yapın, tanıtım videolarımızı izleyin - Sonraki düğmeye tıklayarak (veya web.config'deki umbracoConfigurationStatus'u değiştirerek), bu yazılımın lisansını aşağıdaki kutuda belirtildiği şekilde kabul etmiş olursunuz. Bu Umbraco dağıtımının iki farklı lisanstan oluştuğuna dikkat edin, çerçeve için açık kaynak MIT lisansı ve kullanıcı arayüzünü kapsayan ücretsiz Umbraco lisansı. Henüz yüklenmedi. Etkilenen dosyalar ve klasörler Umbraco için izinlerin ayarlanmasıyla ilgili daha fazla bilgiyi burada bulabilirsiniz @@ -914,10 +904,6 @@ Runway'i kurdunuz, öyleyse neden yeni web sitenizin nasıl göründüğüne bak Ödüllü topluluğumuzdan yardım alın, belgelere göz atın veya basit bir sitenin nasıl oluşturulacağı, paketlerin nasıl kullanılacağı ve Umbraco terminolojisine yönelik hızlı bir kılavuzla ilgili bazı ücretsiz videolar izleyin]]> Umbraco %0% yüklendi ve kullanıma hazır - - /web.config dosyasını manuel olarak düzenleyin ve alttaki AppSetting anahtarını UmbracoConfigurationStatus '%0%' değerine güncelleyin.]]> - anında başlayabilirsiniz .
    Umbraco'da yeniyseniz , başlangıç ​​sayfalarımızda birçok kaynak bulabilirsiniz.]]> @@ -2070,8 +2056,6 @@ Web sitenizi yönetmek için, Umbraco'nun arka ofisini açın ve içerik eklemey Web sitenizin SSL sertifikasının süresi %0% gün içinde doluyor. URL %0% - '%1%' pinglenirken hata oluştu Şu anda HTTPS şemasını kullanarak siteyi %0% görüntülüyorsunuz. - appSetting 'Umbraco.Core.Https' web.config dosyanızda 'false' olarak ayarlandı. Bu siteye HTTPS şemasını kullanarak eriştiğinizde, bu 'doğru' olarak ayarlanmalıdır. - appSetting 'Umbraco.Core.Https' web.config dosyanızda '%0%' olarak ayarlandı, çerezleriniz%1% güvenli olarak işaretlendi. Hata ayıklama derleme modu devre dışı. Hata ayıklama derleme modu şu anda etkin. Yayınlanmadan önce bu ayarı devre dışı bırakmanız önerilir. @@ -2094,10 +2078,7 @@ Web sitenizi yönetmek için, Umbraco'nun arka ofisini açın ve içerik eklemey --> ​​%0%.]]> ​​Web sitesi teknolojisi hakkında bilgi veren hiçbir başlık bulunamadı. - ​​Web.config dosyasında system.net/mailsettings bulunamadı. - Web.config dosyası system.net/mailsettings bölümünde, ana bilgisayar yapılandırılmamış. SMTP ayarları doğru yapılandırıldı ve hizmet beklendiği gibi çalışıyor. - '%0%' ana bilgisayarı ve '%1%' bağlantı noktası ile yapılandırılan SMTP sunucusuna ulaşılamadı. Lütfen Web.config dosyasındaki system.net/mailsettings içindeki SMTP ayarlarının doğruluğunu kontrol edin. %0% olarak ayarlandı]]> %0%.]]>

    %0% tarihinde %1% ile çalıştırılan planlanmış Umbraco Sağlık Kontrollerinin sonuçları aşağıdaki gibidir:

    %2%]]>
    diff --git a/src/Umbraco.Web.UI/umbraco/config/lang/zh.xml b/src/Umbraco.Web.UI/umbraco/config/lang/zh.xml index cf2db35e9cd3..423e5cca36dc 100644 --- a/src/Umbraco.Web.UI/umbraco/config/lang/zh.xml +++ b/src/Umbraco.Web.UI/umbraco/config/lang/zh.xml @@ -14,9 +14,9 @@ 创建扩展包 删除 禁用 - 清空回收站 + 清空回收站 导出文档类型 - 导入文档类型 + 导入文档类型 导入扩展包 实时编辑模式 退出 @@ -482,19 +482,12 @@ 无法连接到数据库。 - 无法保存web.config文件,请手工修改。 发现数据库 数据库配置 安装进行 %0% 数据库配置 ]]> 下一步继续。]]> - 数据库未找到!请检查数据库连接串设置。

    -

    您可以自行编辑“web.config”文件,键名为 “UmbracoDbDSN”

    -

    - 当自行编辑后,单击重试按钮
    。 - 如何编辑web.config

    - ]]>
    如有必要,请联系您的系统管理员。 如果您是本机安装,请使用管理员账号。]]> @@ -512,7 +505,6 @@ 安装过程中默认用户密码已更改

    点击下一步继续。]]> 密码已更改 作为入门者,从视频教程开始吧! - 点击下一步 (或在Web.config中自行修改UmbracoConfigurationStatus),意味着您接受上述许可协议。 安装失败。 受影响的文件和文件夹 此处查看更多信息 @@ -575,8 +567,6 @@ 更多的帮助信息 从社区获取帮助]]> 系统 %0% 安装完毕 - /web.config file 的 AppSetting 键 - UmbracoConfigurationStatus'%0%'。]]> 立即开始请点“运行系统”
    如果您是新手, 您可以得到相当丰富的学习资源。]]>
    运行系统 管理您的网站, 运行后台添加内容, @@ -1153,8 +1143,6 @@ Certificate validation error: '%0%' 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. Debug compilation mode is disabled. Debug compilation mode is currently enabled. It is recommended to disable this setting before go live. @@ -1174,10 +1162,7 @@ --> %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%.]]> diff --git a/src/Umbraco.Web.UI/umbraco/config/lang/zh_tw.xml b/src/Umbraco.Web.UI/umbraco/config/lang/zh_tw.xml index 0fee4e6a1838..8d5cf16de28b 100644 --- a/src/Umbraco.Web.UI/umbraco/config/lang/zh_tw.xml +++ b/src/Umbraco.Web.UI/umbraco/config/lang/zh_tw.xml @@ -14,9 +14,9 @@ 創建擴展包 刪除 禁用 - 清空回收站 + 清空回收站 匯出文檔類型 - 導入文檔類型 + 導入文檔類型 導入擴展包 即時編輯模式 退出 @@ -475,19 +475,12 @@ 無法連接到資料庫。 - 無法保存web.config檔,請手工修改。 發現資料庫 資料庫配置 安裝 按鈕來安裝Umbraco資料庫 %0% ]]> 下一步繼續。]]> - 沒有找到資料庫!請確認檔案"web.config"中的字串"connection string"是否正確。

    -

    請編輯檔案"web.config" (例如使用Visual Studio或您喜歡的編輯器),移動到檔案底部,並在名稱為"UmbracoDbDSN"的字串中設定資料庫連結資訊,並存檔。

    -

    - 點選重試按鈕當上述步驟完成。
    - - 在此查詢更多編輯web.config的資訊。

    ]]>
    若需要時,請聯繫您的網路公司。如果您在本地機器或伺服器安裝的話,您也許需要聯絡系統管理者。]]> 安裝後預設使用者的密碼已經成功修改!

    不需更多的操作步驟。點選下一步繼續。]]> 密碼已更改 作為入門者,從視頻教程開始吧! - 點擊下一步 (或在Web.config中自行修改UmbracoConfigurationStatus),意味著您接受上述授權合約。 安裝失敗。 受影響的檔和資料夾 此處查看更多資訊 @@ -567,7 +559,6 @@ 更多的幫忙與資訊 從我們獲獎的社群得到幫助,瀏覽文件,或觀看免費影片來瞭解如何輕鬆架設網站,如何使用插件,和瞭解Umbraco項目名稱的快速上手指引。]]> 系統 %0% 安裝完畢 - /web.config 檔案並且更新AppSetting中的字串UmbracoConfigurationStatus 內容為 '%0%'。]]> 快速開始指引。
    如果您是Umbraco的新成員, 您可以在其中找到相當多的資源。]]>
    啟動Umbraco @@ -1134,8 +1125,6 @@ 憑證驗證錯誤:%0% 網址探查錯誤:%0% - '%1%' 您目前使用HTTPS瀏覽本站:%0% - 在您的web.config檔案中,appSetting的Umbraco.Core.UseHttps是設為false。當您開始使用HTTPS時,應將其改為 true。 - 在您的web.config檔案中,appSetting的Umbraco.Core.UseHttps是設為 %0%,您的cookies %0% 標成安全。 偵錯編輯模式關閉。 偵錯編輯模式目前已開啟。上線前建議將其關閉。 @@ -1155,10 +1144,7 @@ --> %0%。]]> 在標頭中沒有找到揭露網站技術的資訊。 - 在 Web.config 檔案中,找不到 system.net/mailsettings。 - 在 Web.config 檔案中的 system.net/mailsettings,沒有設定 host 。 SMTP設定正確,而且服務正常運作。 - SMTP伺服器 %0% : %1% 無法連接。請確認在Web.config 檔案中 system.net/mailsettings 設定正確。 %0%。]]> %0%。]]> diff --git a/tests/Umbraco.Tests.AcceptanceTest/cypress/integration/DataTypes/dataTypes.ts b/tests/Umbraco.Tests.AcceptanceTest/cypress/integration/DataTypes/dataTypes.ts index 9e1e6cc185dd..942d42a9bf77 100644 --- a/tests/Umbraco.Tests.AcceptanceTest/cypress/integration/DataTypes/dataTypes.ts +++ b/tests/Umbraco.Tests.AcceptanceTest/cypress/integration/DataTypes/dataTypes.ts @@ -2,6 +2,7 @@ import { AliasHelper, ApprovedColorPickerDataTypeBuilder, + TextBoxDataTypeBuilder, } from 'umbraco-cypress-testhelpers'; context('DataTypes', () => { @@ -61,6 +62,48 @@ context('DataTypes', () => { cy.umbracoEnsureTemplateNameNotExists(name); }); + it('Tests Textbox Maxlength', () => { + cy.deleteAllContent(); + const name = 'Textbox Maxlength Test'; + const alias = AliasHelper.toAlias(name); + + cy.umbracoEnsureDocumentTypeNameNotExists(name); + cy.umbracoEnsureDataTypeNameNotExists(name); + + const textBoxDataType = new TextBoxDataTypeBuilder() + .withName(name) + .withMaxChars(10) + .build() + + cy.umbracoCreateDocTypeWithContent(name, alias, textBoxDataType); + + // Act + // Enter content + // Assert no helptext with (max-2) chars & can save + cy.umbracoRefreshContentTree(); + cy.umbracoTreeItem("content", [name]).click(); + cy.get('input[name="textbox"]').type('12345678'); + cy.get('localize[key="textbox_characters_left"]').should('not.exist'); + cy.umbracoButtonByLabelKey('buttons_saveAndPublish').click(); + cy.umbracoSuccessNotification().should('be.visible'); + cy.get('.property-error').should('not.be.visible'); + + // Add char and assert helptext appears - no publish to save time & has been asserted above & below + cy.get('input[name="textbox"]').type('9'); + cy.get('localize[key="textbox_characters_left"]').contains('characters left').should('exist'); + cy.get('.property-error').should('not.be.visible'); + + // Add char and assert errortext appears and can't save + cy.get('input[name="textbox"]').type('10'); // 1 char over max + cy.get('localize[key="textbox_characters_exceed"]').contains('too many').should('exist'); + cy.umbracoButtonByLabelKey('buttons_saveAndPublish').click(); + cy.get('.property-error').should('be.visible'); + + // Clean + cy.umbracoEnsureDataTypeNameNotExists(name); + cy.umbracoEnsureDocumentTypeNameNotExists(name); + }) + // it('Tests Checkbox List', () => { // const name = 'CheckBox List'; // const alias = AliasHelper.toAlias(name); diff --git a/tests/Umbraco.Tests.AcceptanceTest/cypress/integration/Members/memberGroups.js b/tests/Umbraco.Tests.AcceptanceTest/cypress/integration/Members/memberGroups.js index be9b93134d01..6add16b4ee68 100644 --- a/tests/Umbraco.Tests.AcceptanceTest/cypress/integration/Members/memberGroups.js +++ b/tests/Umbraco.Tests.AcceptanceTest/cypress/integration/Members/memberGroups.js @@ -1,4 +1,4 @@ -context('User Groups', () => { +context('Member Groups', () => { beforeEach(() => { cy.umbracoLogin(Cypress.env('username'), Cypress.env('password')); diff --git a/tests/Umbraco.Tests.AcceptanceTest/cypress/integration/Users/users.ts b/tests/Umbraco.Tests.AcceptanceTest/cypress/integration/Users/users.ts index e122b2156432..12a9bee7a20b 100644 --- a/tests/Umbraco.Tests.AcceptanceTest/cypress/integration/Users/users.ts +++ b/tests/Umbraco.Tests.AcceptanceTest/cypress/integration/Users/users.ts @@ -32,4 +32,109 @@ context('Users', () => { }); -}); + it('Update user', () => { + // Set userdata + const name = "Alice Bobson"; + const email = "alice-bobson@acceptancetest.umbraco"; + const startContentIds = []; + const startMediaIds = []; + const userGroups = ["admin"]; + + var userData = + { + "id": -1, + "parentId": -1, + "name": name, + "username": email, + "culture": "en-US", + "email": email, + "startContentIds": startContentIds, + "startMediaIds": startMediaIds, + "userGroups": userGroups, + "message": "" + }; + + // Ensure user doesn't exist + cy.umbracoEnsureUserEmailNotExists(email); + + // Create user through API + cy.getCookie('UMB-XSRF-TOKEN', { log: false }).then((token) => { + cy.request({ + method: 'POST', + url: '/umbraco/backoffice/umbracoapi/users/PostCreateUser', + followRedirect: true, + headers: { + Accept: 'application/json', + 'X-UMB-XSRF-TOKEN': token.value, + }, + body: userData, + log: false, + }).then((response) => { + return; + }); + }); + + // Go to the user and edit their name + cy.umbracoSection('users'); + cy.get('.umb-user-card__name').contains(name).click(); + cy.get('#headerName').type('{movetoend}son'); + cy.umbracoButtonByLabelKey('buttons_save').click(); + + // assert save succeeds + cy.umbracoSuccessNotification().should('be.visible'); + cy.umbracoEnsureUserEmailNotExists(email); + }) + + it('Delete user', () => { + // Set userdata + const name = "Alice Bobson"; + const email = "alice-bobson@acceptancetest.umbraco"; + const startContentIds = []; + const startMediaIds = []; + const userGroups = ["admin"]; + + var userData = + { + "id": -1, + "parentId": -1, + "name": name, + "username": email, + "culture": "en-US", + "email": email, + "startContentIds": startContentIds, + "startMediaIds": startMediaIds, + "userGroups": userGroups, + "message": "" + }; + + // Ensure user doesn't exist + cy.umbracoEnsureUserEmailNotExists(email); + + // Create user through API + cy.getCookie('UMB-XSRF-TOKEN', { log: false }).then((token) => { + cy.request({ + method: 'POST', + url: '/umbraco/backoffice/umbracoapi/users/PostCreateUser', + followRedirect: true, + headers: { + Accept: 'application/json', + 'X-UMB-XSRF-TOKEN': token.value, + }, + body: userData, + log: false, + }).then((response) => { + return; + }); + }); + + // Go to the user and delete them + cy.umbracoSection('users'); + cy.get('.umb-user-card__name').contains(name).click(); + cy.umbracoButtonByLabelKey("user_deleteUser").click(); + cy.get('umb-button[label="Yes, delete"]').click(); + + // assert deletion succeeds + cy.umbracoSuccessNotification().should('be.visible'); + cy.umbracoEnsureUserEmailNotExists(email); + }) +}); \ No newline at end of file diff --git a/tests/Umbraco.Tests.AcceptanceTest/cypress/support/commands.js b/tests/Umbraco.Tests.AcceptanceTest/cypress/support/commands.js index 5b0be47114e1..34da26d04e5f 100644 --- a/tests/Umbraco.Tests.AcceptanceTest/cypress/support/commands.js +++ b/tests/Umbraco.Tests.AcceptanceTest/cypress/support/commands.js @@ -26,5 +26,73 @@ import {Command} from 'umbraco-cypress-testhelpers'; import {Chainable} from './chainable'; +import { JsonHelper } from 'umbraco-cypress-testhelpers'; new Chainable(); new Command().registerCypressCommands(); + +Cypress.Commands.add('umbracoCreateLanguage', (culture, isMandatory = false, fallbackLanguageId = 1) => { + + var langData = + { + "culture": culture, + "isMandatory": isMandatory, + "fallbackLanguageId": fallbackLanguageId + }; + + // Create language through API + cy.getCookie('UMB-XSRF-TOKEN', { log: false }).then((token) => { + cy.request({ + method: 'POST', + url: '/umbraco/backoffice/umbracoapi/language/SaveLanguage', + followRedirect: true, + headers: { + Accept: 'application/json', + 'X-UMB-XSRF-TOKEN': token.value, + }, + body: langData, + log: false, + }).then((response) => { + return; + }); + }); +}); + +Cypress.Commands.add('umbracoEnsureLanguageNotExists', (culture) => { + cy.getCookie('UMB-XSRF-TOKEN', { log: false }).then((token) => { + console.log('hit commands') + cy.request({ + method: 'GET', + url: '/umbraco/backoffice/umbracoapi/language/GetAllLanguages', + followRedirect: true, + headers: { + Accept: 'application/json', + 'X-UMB-XSRF-TOKEN': token.value, + }, + log: false, + }).then((response) => { + const searchBody = JsonHelper.getBody(response); + if (searchBody.length > 0) { + let languageId = null; + for (const sb of searchBody) { + if (sb.culture === culture) { + languageId = sb.id; + } + } + + if (languageId !== null) { + cy.request({ + method: 'POST', + url: '/umbraco/backoffice/umbracoapi/language/DeleteLanguage?id=' + languageId, + followRedirect: false, + headers: { + ContentType: 'application/json', + 'X-UMB-XSRF-TOKEN': token.value, + }, + }).then((resp) => { + return; + }); + } + } + }); + }); +}); \ No newline at end of file diff --git a/tests/Umbraco.Tests.Integration.SqlCe/Umbraco.Tests.Integration.SqlCe.csproj b/tests/Umbraco.Tests.Integration.SqlCe/Umbraco.Tests.Integration.SqlCe.csproj index b4631e56dc62..24c20104668f 100644 --- a/tests/Umbraco.Tests.Integration.SqlCe/Umbraco.Tests.Integration.SqlCe.csproj +++ b/tests/Umbraco.Tests.Integration.SqlCe/Umbraco.Tests.Integration.SqlCe.csproj @@ -6,7 +6,7 @@ - + diff --git a/tests/Umbraco.Tests.Integration/Umbraco.Infrastructure/Persistence/Repositories/ContentTypeRepositoryTest.cs b/tests/Umbraco.Tests.Integration/Umbraco.Infrastructure/Persistence/Repositories/ContentTypeRepositoryTest.cs index decd1d7c5c88..9f79414b550f 100644 --- a/tests/Umbraco.Tests.Integration/Umbraco.Infrastructure/Persistence/Repositories/ContentTypeRepositoryTest.cs +++ b/tests/Umbraco.Tests.Integration/Umbraco.Infrastructure/Persistence/Repositories/ContentTypeRepositoryTest.cs @@ -5,6 +5,7 @@ using System.Collections.Generic; using System.Linq; using Microsoft.Extensions.Logging; +using Moq; using NUnit.Framework; using Umbraco.Cms.Core.Cache; using Umbraco.Cms.Core.IO; @@ -73,7 +74,7 @@ public void Maps_Templates_Correctly() IScopeProvider provider = ScopeProvider; using (IScope scope = provider.CreateScope()) { - var templateRepo = new TemplateRepository((IScopeAccessor)provider, AppCaches.Disabled, LoggerFactory.CreateLogger(), FileSystems, IOHelper, ShortStringHelper); + var templateRepo = new TemplateRepository((IScopeAccessor)provider, AppCaches.Disabled, LoggerFactory.CreateLogger(), FileSystems, IOHelper, ShortStringHelper, Mock.Of()); ContentTypeRepository repository = ContentTypeRepository; Template[] templates = new[] { diff --git a/tests/Umbraco.Tests.Integration/Umbraco.Infrastructure/Persistence/Repositories/DocumentRepositoryTest.cs b/tests/Umbraco.Tests.Integration/Umbraco.Infrastructure/Persistence/Repositories/DocumentRepositoryTest.cs index a7e164183935..7207718071fb 100644 --- a/tests/Umbraco.Tests.Integration/Umbraco.Infrastructure/Persistence/Repositories/DocumentRepositoryTest.cs +++ b/tests/Umbraco.Tests.Integration/Umbraco.Infrastructure/Persistence/Repositories/DocumentRepositoryTest.cs @@ -114,7 +114,7 @@ private DocumentRepository CreateRepository(IScopeAccessor scopeAccessor, out Co appCaches ??= AppCaches; - templateRepository = new TemplateRepository(scopeAccessor, appCaches, LoggerFactory.CreateLogger(), FileSystems, IOHelper, ShortStringHelper); + templateRepository = new TemplateRepository(scopeAccessor, appCaches, LoggerFactory.CreateLogger(), FileSystems, IOHelper, ShortStringHelper, Mock.Of()); var tagRepository = new TagRepository(scopeAccessor, appCaches, LoggerFactory.CreateLogger()); var commonRepository = new ContentTypeCommonRepository(scopeAccessor, templateRepository, appCaches, ShortStringHelper); var languageRepository = new LanguageRepository(scopeAccessor, appCaches, LoggerFactory.CreateLogger(), globalSettings); diff --git a/tests/Umbraco.Tests.Integration/Umbraco.Infrastructure/Persistence/Repositories/TemplateRepositoryTest.cs b/tests/Umbraco.Tests.Integration/Umbraco.Infrastructure/Persistence/Repositories/TemplateRepositoryTest.cs index d137ef8d055b..80eb61d21f91 100644 --- a/tests/Umbraco.Tests.Integration/Umbraco.Infrastructure/Persistence/Repositories/TemplateRepositoryTest.cs +++ b/tests/Umbraco.Tests.Integration/Umbraco.Infrastructure/Persistence/Repositories/TemplateRepositoryTest.cs @@ -38,10 +38,11 @@ public class TemplateRepositoryTest : UmbracoIntegrationTest private IHostingEnvironment HostingEnvironment => GetRequiredService(); private FileSystems FileSystems => GetRequiredService(); + private IViewHelper ViewHelper => GetRequiredService(); private ITemplateRepository CreateRepository(IScopeProvider provider) => - new TemplateRepository((IScopeAccessor)provider, AppCaches.Disabled, LoggerFactory.CreateLogger(), FileSystems, IOHelper, ShortStringHelper); - + new TemplateRepository((IScopeAccessor)provider, AppCaches.Disabled, LoggerFactory.CreateLogger(), FileSystems, IOHelper, ShortStringHelper, ViewHelper); + [Test] public void Can_Instantiate_Repository() { @@ -90,16 +91,14 @@ public void Can_Perform_Add_View_With_Default_Content() // Act var template = new Template(ShortStringHelper, "test", "test") { - Content = ViewHelper.GetDefaultFileContent() + Content = "mock-content" }; repository.Save(template); // Assert Assert.That(repository.Get("test"), Is.Not.Null); Assert.That(FileSystems.MvcViewsFileSystem.FileExists("test.cshtml"), Is.True); - Assert.AreEqual( - @"@usingUmbraco.Cms.Web.Common.PublishedModels;@inheritsUmbraco.Cms.Web.Common.Views.UmbracoViewPage@{Layout=null;}".StripWhitespace(), - template.Content.StripWhitespace()); + Assert.AreEqual("mock-content", template.Content.StripWhitespace()); } } @@ -144,13 +143,13 @@ public void Can_Perform_Add_Unique_Alias() // Act var template = new Template(ShortStringHelper, "test", "test") { - Content = ViewHelper.GetDefaultFileContent() + Content = "mock-content" }; repository.Save(template); var template2 = new Template(ShortStringHelper, "test", "test") { - Content = ViewHelper.GetDefaultFileContent() + Content = "mock-content" }; repository.Save(template2); @@ -172,13 +171,13 @@ public void Can_Perform_Update_Unique_Alias() // Act var template = new Template(ShortStringHelper, "test", "test") { - Content = ViewHelper.GetDefaultFileContent() + Content = "mock-content" }; repository.Save(template); var template2 = new Template(ShortStringHelper, "test1", "test1") { - Content = ViewHelper.GetDefaultFileContent() + Content = "mock-content" }; repository.Save(template2); @@ -205,7 +204,7 @@ public void Can_Perform_Update_View() // Act var template = new Template(ShortStringHelper, "test", "test") { - Content = ViewHelper.GetDefaultFileContent() + Content = "mock-content" }; repository.Save(template); @@ -216,7 +215,7 @@ public void Can_Perform_Update_View() // Assert Assert.That(FileSystems.MvcViewsFileSystem.FileExists("test.cshtml"), Is.True); - Assert.That(updated.Content, Is.EqualTo(ViewHelper.GetDefaultFileContent() + "")); + Assert.That(updated.Content, Is.EqualTo("mock-content" + "")); } } @@ -232,7 +231,7 @@ public void Can_Perform_Delete_View() var template = new Template(ShortStringHelper, "test", "test") { - Content = ViewHelper.GetDefaultFileContent() + Content = "mock-content" }; repository.Save(template); diff --git a/tests/Umbraco.Tests.Integration/Umbraco.Tests.Integration.csproj b/tests/Umbraco.Tests.Integration/Umbraco.Tests.Integration.csproj index ca6096835aff..36c901773ee9 100644 --- a/tests/Umbraco.Tests.Integration/Umbraco.Tests.Integration.csproj +++ b/tests/Umbraco.Tests.Integration/Umbraco.Tests.Integration.csproj @@ -81,7 +81,7 @@ - + diff --git a/tests/Umbraco.Tests.UnitTests/Umbraco.Core/Templates/ViewHelperTests.cs b/tests/Umbraco.Tests.UnitTests/Umbraco.Core/Templates/DefaultViewContentProviderTests.cs similarity index 71% rename from tests/Umbraco.Tests.UnitTests/Umbraco.Core/Templates/ViewHelperTests.cs rename to tests/Umbraco.Tests.UnitTests/Umbraco.Core/Templates/DefaultViewContentProviderTests.cs index 446659467b6a..d43d88f001ad 100644 --- a/tests/Umbraco.Tests.UnitTests/Umbraco.Core/Templates/ViewHelperTests.cs +++ b/tests/Umbraco.Tests.UnitTests/Umbraco.Core/Templates/DefaultViewContentProviderTests.cs @@ -7,12 +7,14 @@ namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Core.Templates { [TestFixture] - public class ViewHelperTests + public class DefaultViewContentProviderTests { + private IDefaultViewContentProvider DefaultViewContentProvider => new DefaultViewContentProvider(); + [Test] public void NoOptions() { - var view = ViewHelper.GetDefaultFileContent(); + var view = DefaultViewContentProvider.GetDefaultFileContent(); Assert.AreEqual( FixView(@"@using Umbraco.Cms.Web.Common.PublishedModels; @inherits Umbraco.Cms.Web.Common.Views.UmbracoViewPage @@ -24,7 +26,7 @@ @inherits Umbraco.Cms.Web.Common.Views.UmbracoViewPage [Test] public void Layout() { - var view = ViewHelper.GetDefaultFileContent(layoutPageAlias: "Dharznoik"); + var view = DefaultViewContentProvider.GetDefaultFileContent(layoutPageAlias: "Dharznoik"); Assert.AreEqual( FixView(@"@using Umbraco.Cms.Web.Common.PublishedModels; @inherits Umbraco.Cms.Web.Common.Views.UmbracoViewPage @@ -36,7 +38,7 @@ @inherits Umbraco.Cms.Web.Common.Views.UmbracoViewPage [Test] public void ClassName() { - var view = ViewHelper.GetDefaultFileContent(modelClassName: "ClassName"); + var view = DefaultViewContentProvider.GetDefaultFileContent(modelClassName: "ClassName"); Assert.AreEqual( FixView(@"@using Umbraco.Cms.Web.Common.PublishedModels; @inherits Umbraco.Cms.Web.Common.Views.UmbracoViewPage @@ -48,7 +50,7 @@ @inherits Umbraco.Cms.Web.Common.Views.UmbracoViewPage [Test] public void Namespace() { - var view = ViewHelper.GetDefaultFileContent(modelNamespace: "Models"); + var view = DefaultViewContentProvider.GetDefaultFileContent(modelNamespace: "Models"); Assert.AreEqual( FixView(@"@using Umbraco.Cms.Web.Common.PublishedModels; @inherits Umbraco.Cms.Web.Common.Views.UmbracoViewPage @@ -60,7 +62,7 @@ @inherits Umbraco.Cms.Web.Common.Views.UmbracoViewPage [Test] public void ClassNameAndNamespace() { - var view = ViewHelper.GetDefaultFileContent(modelClassName: "ClassName", modelNamespace: "My.Models"); + var view = DefaultViewContentProvider.GetDefaultFileContent(modelClassName: "ClassName", modelNamespace: "My.Models"); Assert.AreEqual( FixView(@"@using Umbraco.Cms.Web.Common.PublishedModels; @inherits Umbraco.Cms.Web.Common.Views.UmbracoViewPage @@ -73,7 +75,7 @@ @inherits Umbraco.Cms.Web.Common.Views.UmbracoViewPage [Test] public void ClassNameAndNamespaceAndAlias() { - var view = ViewHelper.GetDefaultFileContent(modelClassName: "ClassName", modelNamespace: "My.Models", modelNamespaceAlias: "MyModels"); + var view = DefaultViewContentProvider.GetDefaultFileContent(modelClassName: "ClassName", modelNamespace: "My.Models", modelNamespaceAlias: "MyModels"); Assert.AreEqual( FixView(@"@using Umbraco.Cms.Web.Common.PublishedModels; @inherits Umbraco.Cms.Web.Common.Views.UmbracoViewPage @@ -86,7 +88,7 @@ @inherits Umbraco.Cms.Web.Common.Views.UmbracoViewPage [Test] public void Combined() { - var view = ViewHelper.GetDefaultFileContent(layoutPageAlias: "Dharznoik", modelClassName: "ClassName", modelNamespace: "My.Models", modelNamespaceAlias: "MyModels"); + var view = DefaultViewContentProvider.GetDefaultFileContent(layoutPageAlias: "Dharznoik", modelClassName: "ClassName", modelNamespace: "My.Models", modelNamespaceAlias: "MyModels"); Assert.AreEqual( FixView(@"@using Umbraco.Cms.Web.Common.PublishedModels; @inherits Umbraco.Cms.Web.Common.Views.UmbracoViewPage diff --git a/tests/Umbraco.Tests.UnitTests/Umbraco.ModelsBuilder.Embedded/BuilderTests.cs b/tests/Umbraco.Tests.UnitTests/Umbraco.ModelsBuilder.Embedded/BuilderTests.cs index 4dea81facbce..73f38da362b1 100644 --- a/tests/Umbraco.Tests.UnitTests/Umbraco.ModelsBuilder.Embedded/BuilderTests.cs +++ b/tests/Umbraco.Tests.UnitTests/Umbraco.ModelsBuilder.Embedded/BuilderTests.cs @@ -26,6 +26,7 @@ public void GenerateSimpleType() Id = 1, Alias = "type1", ClrName = "Type1", + Name = "type1Name", ParentId = 0, BaseType = null, ItemType = TypeModel.ItemTypes.Content, @@ -34,6 +35,7 @@ public void GenerateSimpleType() { Alias = "prop1", ClrName = "Prop1", + Name = "prop1Name", ModelClrType = typeof(string), }); @@ -67,6 +69,7 @@ public void GenerateSimpleType() namespace Umbraco.Cms.Web.Common.PublishedModels { + ///

    type1Name [PublishedModel(""type1"")] public partial class Type1 : PublishedContentModel { @@ -97,6 +100,9 @@ public Type1(IPublishedContent content, IPublishedValueFallback publishedValueFa // properties + /// + /// prop1Name + /// [global::System.CodeDom.Compiler.GeneratedCodeAttribute(""Umbraco.ModelsBuilder.Embedded"", """ + version + @""")] [global::System.Diagnostics.CodeAnalysis.MaybeNull] [ImplementPropertyType(""prop1"")] @@ -271,6 +277,388 @@ public void GenerateAmbiguous() Assert.IsTrue(gen.Contains(" global::Umbraco.Cms.Core.Exceptions.BootFailedException Prop3")); } + [Test] + public void GenerateInheritedType() + { + var parentType = new TypeModel + { + Id = 1, + Alias = "parentType", + ClrName = "ParentType", + Name = "parentTypeName", + ParentId = 0, + IsParent = true, + BaseType = null, + ItemType = TypeModel.ItemTypes.Content, + }; + parentType.Properties.Add(new PropertyModel + { + Alias = "prop1", + ClrName = "Prop1", + Name = "prop1Name", + ModelClrType = typeof(string), + }); + + var childType = new TypeModel + { + Id = 2, + Alias = "childType", + ClrName = "ChildType", + Name = "childTypeName", + ParentId = 1, + BaseType = parentType, + ItemType = TypeModel.ItemTypes.Content, + }; + + TypeModel[] docTypes = new[] { parentType, childType }; + + var modelsBuilderConfig = new ModelsBuilderSettings(); + var builder = new TextBuilder(modelsBuilderConfig, docTypes); + + var sb = new StringBuilder(); + builder.Generate(sb, builder.GetModelsToGenerate().First()); + var genParent = sb.ToString(); + + SemVersion version = ApiVersion.Current.Version; + + var expectedParent = @"//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// +// Umbraco.ModelsBuilder.Embedded v" + version + @" +// +// Changes to this file will be lost if the code is regenerated. +// +//------------------------------------------------------------------------------ + +using System; +using System.Linq.Expressions; +using Umbraco.Cms.Core.Models.PublishedContent; +using Umbraco.Cms.Core.PublishedCache; +using Umbraco.Cms.Infrastructure.ModelsBuilder; +using Umbraco.Cms.Core; +using Umbraco.Extensions; + +namespace Umbraco.Cms.Web.Common.PublishedModels +{ + /// parentTypeName + [PublishedModel(""parentType"")] + public partial class ParentType : PublishedContentModel + { + // helpers +#pragma warning disable 0109 // new is redundant + [global::System.CodeDom.Compiler.GeneratedCodeAttribute(""Umbraco.ModelsBuilder.Embedded"", """ + version + @""")] + public new const string ModelTypeAlias = ""parentType""; + [global::System.CodeDom.Compiler.GeneratedCodeAttribute(""Umbraco.ModelsBuilder.Embedded"", """ + version + @""")] + public new const PublishedItemType ModelItemType = PublishedItemType.Content; + [global::System.CodeDom.Compiler.GeneratedCodeAttribute(""Umbraco.ModelsBuilder.Embedded"", """ + version + @""")] + [return: global::System.Diagnostics.CodeAnalysis.MaybeNull] + public new static IPublishedContentType GetModelContentType(IPublishedSnapshotAccessor publishedSnapshotAccessor) + => PublishedModelUtility.GetModelContentType(publishedSnapshotAccessor, ModelItemType, ModelTypeAlias); + [global::System.CodeDom.Compiler.GeneratedCodeAttribute(""Umbraco.ModelsBuilder.Embedded"", """ + version + @""")] + [return: global::System.Diagnostics.CodeAnalysis.MaybeNull] + public static IPublishedPropertyType GetModelPropertyType(IPublishedSnapshotAccessor publishedSnapshotAccessor, Expression> selector) + => PublishedModelUtility.GetModelPropertyType(GetModelContentType(publishedSnapshotAccessor), selector); +#pragma warning restore 0109 + + private IPublishedValueFallback _publishedValueFallback; + + // ctor + public ParentType(IPublishedContent content, IPublishedValueFallback publishedValueFallback) + : base(content, publishedValueFallback) + { + _publishedValueFallback = publishedValueFallback; + } + + // properties + + /// + /// prop1Name + /// + [global::System.CodeDom.Compiler.GeneratedCodeAttribute(""Umbraco.ModelsBuilder.Embedded"", """ + version + @""")] + [global::System.Diagnostics.CodeAnalysis.MaybeNull] + [ImplementPropertyType(""prop1"")] + public virtual string Prop1 => this.Value(_publishedValueFallback, ""prop1""); + } +} +"; + Console.WriteLine(genParent); + Assert.AreEqual(expectedParent.ClearLf(), genParent); + + var sb2 = new StringBuilder(); + builder.Generate(sb2, builder.GetModelsToGenerate().Skip(1).First()); + var genChild = sb2.ToString(); + + var expectedChild = @"//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// +// Umbraco.ModelsBuilder.Embedded v" + version + @" +// +// Changes to this file will be lost if the code is regenerated. +// +//------------------------------------------------------------------------------ + +using System; +using System.Linq.Expressions; +using Umbraco.Cms.Core.Models.PublishedContent; +using Umbraco.Cms.Core.PublishedCache; +using Umbraco.Cms.Infrastructure.ModelsBuilder; +using Umbraco.Cms.Core; +using Umbraco.Extensions; + +namespace Umbraco.Cms.Web.Common.PublishedModels +{ + /// childTypeName + [PublishedModel(""childType"")] + public partial class ChildType : ParentType + { + // helpers +#pragma warning disable 0109 // new is redundant + [global::System.CodeDom.Compiler.GeneratedCodeAttribute(""Umbraco.ModelsBuilder.Embedded"", """ + version + @""")] + public new const string ModelTypeAlias = ""childType""; + [global::System.CodeDom.Compiler.GeneratedCodeAttribute(""Umbraco.ModelsBuilder.Embedded"", """ + version + @""")] + public new const PublishedItemType ModelItemType = PublishedItemType.Content; + [global::System.CodeDom.Compiler.GeneratedCodeAttribute(""Umbraco.ModelsBuilder.Embedded"", """ + version + @""")] + [return: global::System.Diagnostics.CodeAnalysis.MaybeNull] + public new static IPublishedContentType GetModelContentType(IPublishedSnapshotAccessor publishedSnapshotAccessor) + => PublishedModelUtility.GetModelContentType(publishedSnapshotAccessor, ModelItemType, ModelTypeAlias); + [global::System.CodeDom.Compiler.GeneratedCodeAttribute(""Umbraco.ModelsBuilder.Embedded"", """ + version + @""")] + [return: global::System.Diagnostics.CodeAnalysis.MaybeNull] + public static IPublishedPropertyType GetModelPropertyType(IPublishedSnapshotAccessor publishedSnapshotAccessor, Expression> selector) + => PublishedModelUtility.GetModelPropertyType(GetModelContentType(publishedSnapshotAccessor), selector); +#pragma warning restore 0109 + + private IPublishedValueFallback _publishedValueFallback; + + // ctor + public ChildType(IPublishedContent content, IPublishedValueFallback publishedValueFallback) + : base(content, publishedValueFallback) + { + _publishedValueFallback = publishedValueFallback; + } + + // properties + } +} +"; + + Console.WriteLine(genChild); + Assert.AreEqual(expectedChild.ClearLf(), genChild); + + } + + [Test] + public void GenerateComposedType() + { + // Umbraco returns nice, pascal-cased names. + var composition1 = new TypeModel + { + Id = 2, + Alias = "composition1", + ClrName = "Composition1", + Name = "composition1Name", + ParentId = 0, + BaseType = null, + ItemType = TypeModel.ItemTypes.Content, + IsMixin = true, + }; + composition1.Properties.Add(new PropertyModel + { + Alias = "compositionProp", + ClrName = "CompositionProp", + Name = "compositionPropName", + ModelClrType = typeof(string), + ClrTypeName = typeof(string).FullName + }); + + var type1 = new TypeModel + { + Id = 1, + Alias = "type1", + ClrName = "Type1", + Name = "type1Name", + ParentId = 0, + BaseType = null, + ItemType = TypeModel.ItemTypes.Content, + }; + type1.Properties.Add(new PropertyModel + { + Alias = "prop1", + ClrName = "Prop1", + Name = "prop1Name", + ModelClrType = typeof(string), + }); + type1.MixinTypes.Add(composition1); + + TypeModel[] types = new[] { type1, composition1 }; + + var modelsBuilderConfig = new ModelsBuilderSettings(); + var builder = new TextBuilder(modelsBuilderConfig, types); + + SemVersion version = ApiVersion.Current.Version; + + var sb = new StringBuilder(); + builder.Generate(sb, builder.GetModelsToGenerate().First()); + var genComposed = sb.ToString(); + + var expectedComposed = @"//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// +// Umbraco.ModelsBuilder.Embedded v" + version + @" +// +// Changes to this file will be lost if the code is regenerated. +// +//------------------------------------------------------------------------------ + +using System; +using System.Linq.Expressions; +using Umbraco.Cms.Core.Models.PublishedContent; +using Umbraco.Cms.Core.PublishedCache; +using Umbraco.Cms.Infrastructure.ModelsBuilder; +using Umbraco.Cms.Core; +using Umbraco.Extensions; + +namespace Umbraco.Cms.Web.Common.PublishedModels +{ + /// type1Name + [PublishedModel(""type1"")] + public partial class Type1 : PublishedContentModel, IComposition1 + { + // helpers +#pragma warning disable 0109 // new is redundant + [global::System.CodeDom.Compiler.GeneratedCodeAttribute(""Umbraco.ModelsBuilder.Embedded"", """ + version + @""")] + public new const string ModelTypeAlias = ""type1""; + [global::System.CodeDom.Compiler.GeneratedCodeAttribute(""Umbraco.ModelsBuilder.Embedded"", """ + version + @""")] + public new const PublishedItemType ModelItemType = PublishedItemType.Content; + [global::System.CodeDom.Compiler.GeneratedCodeAttribute(""Umbraco.ModelsBuilder.Embedded"", """ + version + @""")] + [return: global::System.Diagnostics.CodeAnalysis.MaybeNull] + public new static IPublishedContentType GetModelContentType(IPublishedSnapshotAccessor publishedSnapshotAccessor) + => PublishedModelUtility.GetModelContentType(publishedSnapshotAccessor, ModelItemType, ModelTypeAlias); + [global::System.CodeDom.Compiler.GeneratedCodeAttribute(""Umbraco.ModelsBuilder.Embedded"", """ + version + @""")] + [return: global::System.Diagnostics.CodeAnalysis.MaybeNull] + public static IPublishedPropertyType GetModelPropertyType(IPublishedSnapshotAccessor publishedSnapshotAccessor, Expression> selector) + => PublishedModelUtility.GetModelPropertyType(GetModelContentType(publishedSnapshotAccessor), selector); +#pragma warning restore 0109 + + private IPublishedValueFallback _publishedValueFallback; + + // ctor + public Type1(IPublishedContent content, IPublishedValueFallback publishedValueFallback) + : base(content, publishedValueFallback) + { + _publishedValueFallback = publishedValueFallback; + } + + // properties + + /// + /// prop1Name + /// + [global::System.CodeDom.Compiler.GeneratedCodeAttribute(""Umbraco.ModelsBuilder.Embedded"", """ + version + @""")] + [global::System.Diagnostics.CodeAnalysis.MaybeNull] + [ImplementPropertyType(""prop1"")] + public virtual string Prop1 => this.Value(_publishedValueFallback, ""prop1""); + + /// + /// compositionPropName + /// + [global::System.CodeDom.Compiler.GeneratedCodeAttribute(""Umbraco.ModelsBuilder.Embedded"", """ + version + @""")] + [global::System.Diagnostics.CodeAnalysis.MaybeNull] + [ImplementPropertyType(""compositionProp"")] + public virtual string CompositionProp => global::Umbraco.Cms.Web.Common.PublishedModels.Composition1.GetCompositionProp(this, _publishedValueFallback); + } +} +"; + Console.WriteLine(genComposed); + Assert.AreEqual(expectedComposed.ClearLf(), genComposed); + + var sb2 = new StringBuilder(); + builder.Generate(sb2, builder.GetModelsToGenerate().Skip(1).First()); + var genComposition = sb2.ToString(); + + var expectedComposition = @"//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// +// Umbraco.ModelsBuilder.Embedded v" + version + @" +// +// Changes to this file will be lost if the code is regenerated. +// +//------------------------------------------------------------------------------ + +using System; +using System.Linq.Expressions; +using Umbraco.Cms.Core.Models.PublishedContent; +using Umbraco.Cms.Core.PublishedCache; +using Umbraco.Cms.Infrastructure.ModelsBuilder; +using Umbraco.Cms.Core; +using Umbraco.Extensions; + +namespace Umbraco.Cms.Web.Common.PublishedModels +{ + // Mixin Content Type with alias ""composition1"" + /// composition1Name + public partial interface IComposition1 : IPublishedContent + { + /// compositionPropName + [global::System.CodeDom.Compiler.GeneratedCodeAttribute(""Umbraco.ModelsBuilder.Embedded"", """ + version + @""")] + [global::System.Diagnostics.CodeAnalysis.MaybeNull] + string CompositionProp { get; } + } + + /// composition1Name + [PublishedModel(""composition1"")] + public partial class Composition1 : PublishedContentModel, IComposition1 + { + // helpers +#pragma warning disable 0109 // new is redundant + [global::System.CodeDom.Compiler.GeneratedCodeAttribute(""Umbraco.ModelsBuilder.Embedded"", """ + version + @""")] + public new const string ModelTypeAlias = ""composition1""; + [global::System.CodeDom.Compiler.GeneratedCodeAttribute(""Umbraco.ModelsBuilder.Embedded"", """ + version + @""")] + public new const PublishedItemType ModelItemType = PublishedItemType.Content; + [global::System.CodeDom.Compiler.GeneratedCodeAttribute(""Umbraco.ModelsBuilder.Embedded"", """ + version + @""")] + [return: global::System.Diagnostics.CodeAnalysis.MaybeNull] + public new static IPublishedContentType GetModelContentType(IPublishedSnapshotAccessor publishedSnapshotAccessor) + => PublishedModelUtility.GetModelContentType(publishedSnapshotAccessor, ModelItemType, ModelTypeAlias); + [global::System.CodeDom.Compiler.GeneratedCodeAttribute(""Umbraco.ModelsBuilder.Embedded"", """ + version + @""")] + [return: global::System.Diagnostics.CodeAnalysis.MaybeNull] + public static IPublishedPropertyType GetModelPropertyType(IPublishedSnapshotAccessor publishedSnapshotAccessor, Expression> selector) + => PublishedModelUtility.GetModelPropertyType(GetModelContentType(publishedSnapshotAccessor), selector); +#pragma warning restore 0109 + + private IPublishedValueFallback _publishedValueFallback; + + // ctor + public Composition1(IPublishedContent content, IPublishedValueFallback publishedValueFallback) + : base(content, publishedValueFallback) + { + _publishedValueFallback = publishedValueFallback; + } + + // properties + + /// + /// compositionPropName + /// + [global::System.CodeDom.Compiler.GeneratedCodeAttribute(""Umbraco.ModelsBuilder.Embedded"", """ + version + @""")] + [global::System.Diagnostics.CodeAnalysis.MaybeNull] + [ImplementPropertyType(""compositionProp"")] + public virtual string CompositionProp => GetCompositionProp(this, _publishedValueFallback); + + /// Static getter for compositionPropName + [global::System.CodeDom.Compiler.GeneratedCodeAttribute(""Umbraco.ModelsBuilder.Embedded"", """ + version + @""")] + [return: global::System.Diagnostics.CodeAnalysis.MaybeNull] + public static string GetCompositionProp(IComposition1 that, IPublishedValueFallback publishedValueFallback) => that.Value(publishedValueFallback, ""compositionProp""); + } +} +"; + + Console.WriteLine(genComposition); + Assert.AreEqual(expectedComposition.ClearLf(), genComposition); + } + [TestCase("int", typeof(int))] [TestCase("global::System.Collections.Generic.IEnumerable", typeof(IEnumerable))] [TestCase("global::Umbraco.Cms.Tests.UnitTests.Umbraco.ModelsBuilder.Embedded.BuilderTestsClass1", typeof(BuilderTestsClass1))] diff --git a/tests/Umbraco.Tests.UnitTests/Umbraco.Web.BackOffice/CollectionBuilders/TreeCollectionBuilderTests.cs b/tests/Umbraco.Tests.UnitTests/Umbraco.Web.BackOffice/CollectionBuilders/TreeCollectionBuilderTests.cs new file mode 100644 index 000000000000..5392d50ebd1f --- /dev/null +++ b/tests/Umbraco.Tests.UnitTests/Umbraco.Web.BackOffice/CollectionBuilders/TreeCollectionBuilderTests.cs @@ -0,0 +1,36 @@ +using System.Linq; +using NUnit.Framework; +using Umbraco.Cms.Core.Trees; +using Umbraco.Cms.Web.BackOffice.Trees; + +namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Web.BackOffice.CollectionBuilders +{ + public class TreeCollectionBuilderTests + { + [Test] + public void Adding_Tree_To_Collection_Builder() + { + var collectionBuilder = new TreeCollectionBuilder(); + var treeDefinition = new Tree(0, "test", "test", "test", "test", TreeUse.Main, typeof(LanguageTreeController), false); + + collectionBuilder.AddTree(treeDefinition); + var collection = collectionBuilder.CreateCollection(null); + + Assert.AreEqual(1, collection.Count); + Assert.AreEqual(treeDefinition, collection.FirstOrDefault()); + } + + [Test] + public void Remove_Tree_From_Collection_Builder() + { + var collectionBuilder = new TreeCollectionBuilder(); + var treeDefinition = new Tree(0, "test", "test", "test", "test", TreeUse.Main, typeof(LanguageTreeController), false); + + collectionBuilder.AddTree(treeDefinition); + collectionBuilder.RemoveTreeController(); + var collection = collectionBuilder.CreateCollection(null); + + Assert.AreEqual(0, collection.Count); + } + } +}