Merge branch 'netcore/task/9727-published-request' into netcore/task/9733-routabledocumentfilter
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Microsoft.Extensions.Options;
|
||||
@@ -112,10 +112,10 @@ namespace Umbraco.Web.Routing
|
||||
// if the property varies, get the variant value, URL is "<domain>/<variant-alias>"
|
||||
|
||||
// but! only if the culture is published, else ignore
|
||||
if (varies && !node.HasCulture(domainUri.Culture.Name)) continue;
|
||||
if (varies && !node.HasCulture(domainUri.Culture)) continue;
|
||||
|
||||
var umbracoUrlName = varies
|
||||
? node.Value<string>(_publishedValueFallback,Constants.Conventions.Content.UrlAlias, culture: domainUri.Culture.Name)
|
||||
? node.Value<string>(_publishedValueFallback,Constants.Conventions.Content.UrlAlias, culture: domainUri.Culture)
|
||||
: node.Value<string>(_publishedValueFallback, Constants.Conventions.Content.UrlAlias);
|
||||
|
||||
var aliases = umbracoUrlName?.Split(new [] {','}, StringSplitOptions.RemoveEmptyEntries);
|
||||
@@ -127,7 +127,7 @@ namespace Umbraco.Web.Routing
|
||||
{
|
||||
var path = "/" + alias;
|
||||
var uri = new Uri(CombinePaths(domainUri.Uri.GetLeftPart(UriPartial.Path), path));
|
||||
yield return UrlInfo.Url(_uriUtility.UriFromUmbraco(uri, _requestConfig).ToString(), domainUri.Culture.Name);
|
||||
yield return UrlInfo.Url(_uriUtility.UriFromUmbraco(uri, _requestConfig).ToString(), domainUri.Culture);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -77,7 +77,7 @@ namespace Umbraco.Web.Routing
|
||||
if (!string.IsNullOrEmpty(cultureFromQuerystring))
|
||||
{
|
||||
// we're assuming it will match a culture, if an invalid one is passed in, an exception will throw (there is no TryGetCultureInfo method), i think this is ok though
|
||||
frequest.SetCulture(CultureInfo.GetCultureInfo(cultureFromQuerystring));
|
||||
frequest.SetCulture(cultureFromQuerystring);
|
||||
}
|
||||
|
||||
frequest.SetPublishedContent(node);
|
||||
|
||||
@@ -54,7 +54,7 @@ namespace Umbraco.Web.Routing
|
||||
? frequest.Domain.ContentId + DomainUtilities.PathRelativeToDomain(frequest.Domain.Uri, frequest.Uri.GetAbsolutePathDecoded())
|
||||
: frequest.Uri.GetAbsolutePathDecoded();
|
||||
|
||||
IRedirectUrl redirectUrl = _redirectUrlService.GetMostRecentRedirectUrl(route, frequest.Culture.Name);
|
||||
IRedirectUrl redirectUrl = _redirectUrlService.GetMostRecentRedirectUrl(route, frequest.Culture);
|
||||
|
||||
if (redirectUrl == null)
|
||||
{
|
||||
|
||||
@@ -74,7 +74,7 @@ namespace Umbraco.Web.Routing
|
||||
|
||||
_logger.LogDebug("Test route {Route}", route);
|
||||
|
||||
IPublishedContent node = umbCtx.Content.GetByRoute(umbCtx.InPreviewMode, route, culture: docreq.Culture?.Name);
|
||||
IPublishedContent node = umbCtx.Content.GetByRoute(umbCtx.InPreviewMode, route, culture: docreq.Culture);
|
||||
if (node != null)
|
||||
{
|
||||
docreq.SetPublishedContent(node);
|
||||
|
||||
@@ -59,7 +59,7 @@ namespace Umbraco.Web.Routing
|
||||
node = FindContentByAlias(
|
||||
umbCtx.Content,
|
||||
frequest.Domain != null ? frequest.Domain.ContentId : 0,
|
||||
frequest.Culture.Name,
|
||||
frequest.Culture,
|
||||
frequest.Uri.GetAbsolutePathDecoded());
|
||||
|
||||
if (node != null)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.Extensions.Options;
|
||||
using Microsoft.Extensions.Logging;
|
||||
@@ -83,7 +83,9 @@ namespace Umbraco.Web.Routing
|
||||
var umbracoContext = _umbracoContextAccessor.UmbracoContext;
|
||||
var node = umbracoContext.Content.GetById(id);
|
||||
if (node == null)
|
||||
{
|
||||
yield break;
|
||||
}
|
||||
|
||||
// look for domains, walking up the tree
|
||||
var n = node;
|
||||
@@ -96,17 +98,19 @@ namespace Umbraco.Web.Routing
|
||||
|
||||
// no domains = exit
|
||||
if (domainUris ==null)
|
||||
{
|
||||
yield break;
|
||||
}
|
||||
|
||||
foreach (var d in domainUris)
|
||||
{
|
||||
var culture = d?.Culture?.Name;
|
||||
var culture = d?.Culture;
|
||||
|
||||
//although we are passing in culture here, if any node in this path is invariant, it ignores the culture anyways so this is ok
|
||||
// although we are passing in culture here, if any node in this path is invariant, it ignores the culture anyways so this is ok
|
||||
var route = umbracoContext.Content.GetRouteById(id, culture);
|
||||
if (route == null) continue;
|
||||
|
||||
//need to strip off the leading ID for the route if it exists (occurs if the route is for a node with a domain assigned)
|
||||
// need to strip off the leading ID for the route if it exists (occurs if the route is for a node with a domain assigned)
|
||||
var pos = route.IndexOf('/');
|
||||
var path = pos == 0 ? route : route.Substring(pos);
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using System.Globalization;
|
||||
using System.Globalization;
|
||||
|
||||
namespace Umbraco.Web.Routing
|
||||
{
|
||||
@@ -15,7 +15,7 @@ namespace Umbraco.Web.Routing
|
||||
/// <param name="contentId">The identifier of the content which supports the domain.</param>
|
||||
/// <param name="culture">The culture of the domain.</param>
|
||||
/// <param name="isWildcard">A value indicating whether the domain is a wildcard domain.</param>
|
||||
public Domain(int id, string name, int contentId, CultureInfo culture, bool isWildcard)
|
||||
public Domain(int id, string name, int contentId, string culture, bool isWildcard)
|
||||
{
|
||||
Id = id;
|
||||
Name = name;
|
||||
@@ -55,7 +55,7 @@ namespace Umbraco.Web.Routing
|
||||
/// <summary>
|
||||
/// Gets the culture of the domain.
|
||||
/// </summary>
|
||||
public CultureInfo Culture { get; }
|
||||
public string Culture { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether the domain is a wildcard domain.
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Umbraco.Core;
|
||||
@@ -51,8 +51,8 @@ namespace Umbraco.Web.Routing
|
||||
var rootContentId = domain?.ContentId ?? -1;
|
||||
var wcDomain = FindWildcardDomainInPath(umbracoContext.Domains.GetAll(true), contentPath, rootContentId);
|
||||
|
||||
if (wcDomain != null) return wcDomain.Culture.Name;
|
||||
if (domain != null) return domain.Culture.Name;
|
||||
if (wcDomain != null) return wcDomain.Culture;
|
||||
if (domain != null) return domain.Culture;
|
||||
return umbracoContext.Domains.DefaultCulture;
|
||||
}
|
||||
|
||||
@@ -233,13 +233,13 @@ namespace Umbraco.Web.Routing
|
||||
|
||||
if (culture != null) // try the supplied culture
|
||||
{
|
||||
var cultureDomains = domainsAndUris.Where(x => x.Culture.Name.InvariantEquals(culture)).ToList();
|
||||
var cultureDomains = domainsAndUris.Where(x => x.Culture.InvariantEquals(culture)).ToList();
|
||||
if (cultureDomains.Count > 0) return cultureDomains;
|
||||
}
|
||||
|
||||
if (defaultCulture != null) // try the defaultCulture culture
|
||||
{
|
||||
var cultureDomains = domainsAndUris.Where(x => x.Culture.Name.InvariantEquals(defaultCulture)).ToList();
|
||||
var cultureDomains = domainsAndUris.Where(x => x.Culture.InvariantEquals(defaultCulture)).ToList();
|
||||
if (cultureDomains.Count > 0) return cultureDomains;
|
||||
}
|
||||
|
||||
@@ -254,13 +254,13 @@ namespace Umbraco.Web.Routing
|
||||
|
||||
if (culture != null) // try the supplied culture
|
||||
{
|
||||
domainAndUri = domainsAndUris.FirstOrDefault(x => x.Culture.Name.InvariantEquals(culture));
|
||||
domainAndUri = domainsAndUris.FirstOrDefault(x => x.Culture.InvariantEquals(culture));
|
||||
if (domainAndUri != null) return domainAndUri;
|
||||
}
|
||||
|
||||
if (defaultCulture != null) // try the defaultCulture culture
|
||||
{
|
||||
domainAndUri = domainsAndUris.FirstOrDefault(x => x.Culture.Name.InvariantEquals(defaultCulture));
|
||||
domainAndUri = domainsAndUris.FirstOrDefault(x => x.Culture.InvariantEquals(defaultCulture));
|
||||
if (domainAndUri != null) return domainAndUri;
|
||||
}
|
||||
|
||||
|
||||
@@ -45,7 +45,11 @@ namespace Umbraco.Web.Routing
|
||||
/// <summary>
|
||||
/// Gets the content request's culture.
|
||||
/// </summary>
|
||||
CultureInfo Culture { get; }
|
||||
/// <remarks>
|
||||
/// This will get mapped to a CultureInfo eventually but CultureInfo are expensive to create so we want to leave that up to the
|
||||
/// localization middleware to do. See https://github.com/dotnet/aspnetcore/blob/b795ac3546eb3e2f47a01a64feb3020794ca33bb/src/Middleware/Localization/src/RequestLocalizationMiddleware.cs#L165.
|
||||
/// </remarks>
|
||||
string Culture { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the url to redirect to, when the content request triggers a redirect.
|
||||
|
||||
@@ -26,7 +26,7 @@ namespace Umbraco.Web.Routing
|
||||
/// <summary>
|
||||
/// Gets the <see cref="CultureInfo"/> assigned (if any)
|
||||
/// </summary>
|
||||
CultureInfo Culture { get; }
|
||||
string Culture { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether the current published content has been obtained
|
||||
@@ -64,7 +64,7 @@ namespace Umbraco.Web.Routing
|
||||
/// <summary>
|
||||
/// Sets the culture for the request
|
||||
/// </summary>
|
||||
IPublishedRequestBuilder SetCulture(CultureInfo culture);
|
||||
IPublishedRequestBuilder SetCulture(string culture);
|
||||
|
||||
/// <summary>
|
||||
/// Sets the found <see cref="IPublishedContent"/> for the request
|
||||
|
||||
@@ -13,7 +13,7 @@ namespace Umbraco.Web.Routing
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="PublishedRequest"/> class.
|
||||
/// </summary>
|
||||
public PublishedRequest(Uri uri, IPublishedContent publishedContent, bool isInternalRedirect, ITemplate template, DomainAndUri domain, CultureInfo culture, string redirectUrl, int? responseStatusCode, IReadOnlyList<string> cacheExtensions, IReadOnlyDictionary<string, string> headers, bool cacheabilityNoCache, bool ignorePublishedContentCollisions)
|
||||
public PublishedRequest(Uri uri, IPublishedContent publishedContent, bool isInternalRedirect, ITemplate template, DomainAndUri domain, string culture, string redirectUrl, int? responseStatusCode, IReadOnlyList<string> cacheExtensions, IReadOnlyDictionary<string, string> headers, bool setNoCacheHeader, bool ignorePublishedContentCollisions)
|
||||
{
|
||||
Uri = uri ?? throw new ArgumentNullException(nameof(uri));
|
||||
PublishedContent = publishedContent;
|
||||
@@ -25,7 +25,7 @@ namespace Umbraco.Web.Routing
|
||||
ResponseStatusCode = responseStatusCode;
|
||||
CacheExtensions = cacheExtensions;
|
||||
Headers = headers;
|
||||
SetNoCacheHeader = cacheabilityNoCache;
|
||||
SetNoCacheHeader = setNoCacheHeader;
|
||||
IgnorePublishedContentCollisions = ignorePublishedContentCollisions;
|
||||
}
|
||||
|
||||
@@ -48,7 +48,7 @@ namespace Umbraco.Web.Routing
|
||||
public DomainAndUri Domain { get; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public CultureInfo Culture { get; }
|
||||
public string Culture { get; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string RedirectUrl { get; }
|
||||
|
||||
@@ -36,7 +36,7 @@ namespace Umbraco.Web.Routing
|
||||
public DomainAndUri Domain { get; private set; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public CultureInfo Culture { get; private set; }
|
||||
public string Culture { get; private set; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public ITemplate Template { get; private set; }
|
||||
@@ -89,7 +89,7 @@ namespace Umbraco.Web.Routing
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public IPublishedRequestBuilder SetCulture(CultureInfo culture)
|
||||
public IPublishedRequestBuilder SetCulture(string culture)
|
||||
{
|
||||
Culture = culture;
|
||||
return this;
|
||||
|
||||
@@ -121,15 +121,15 @@ namespace Umbraco.Web.Routing
|
||||
return request.Build();
|
||||
}
|
||||
|
||||
private void SetVariationContext(CultureInfo culture)
|
||||
private void SetVariationContext(string culture)
|
||||
{
|
||||
VariationContext variationContext = _variationContextAccessor.VariationContext;
|
||||
if (variationContext != null && variationContext.Culture == culture?.Name)
|
||||
if (variationContext != null && variationContext.Culture == culture)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_variationContextAccessor.VariationContext = new VariationContext(culture?.Name);
|
||||
_variationContextAccessor.VariationContext = new VariationContext(culture);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
@@ -272,7 +272,7 @@ namespace Umbraco.Web.Routing
|
||||
}
|
||||
|
||||
// variant, ensure that the culture corresponding to the domain's language is published
|
||||
return domainDocument.Cultures.ContainsKey(domain.Culture.Name);
|
||||
return domainDocument.Cultures.ContainsKey(domain.Culture);
|
||||
}
|
||||
|
||||
domains = domains.Where(IsPublishedContentDomain).ToList();
|
||||
@@ -302,10 +302,10 @@ namespace Umbraco.Web.Routing
|
||||
// not matching any existing domain
|
||||
_logger.LogDebug("{TracePrefix}Matches no domain", tracePrefix);
|
||||
|
||||
request.SetCulture(defaultCulture == null ? CultureInfo.CurrentUICulture : new CultureInfo(defaultCulture));
|
||||
request.SetCulture(defaultCulture ?? CultureInfo.CurrentUICulture.Name);
|
||||
}
|
||||
|
||||
_logger.LogDebug("{TracePrefix}Culture={CultureName}", tracePrefix, request.Culture.Name);
|
||||
_logger.LogDebug("{TracePrefix}Culture={CultureName}", tracePrefix, request.Culture);
|
||||
|
||||
return request.Domain != null;
|
||||
}
|
||||
@@ -331,7 +331,7 @@ namespace Umbraco.Web.Routing
|
||||
if (domain != null)
|
||||
{
|
||||
request.SetCulture(domain.Culture);
|
||||
_logger.LogDebug("{TracePrefix}Got domain on node {DomainContentId}, set culture to {CultureName}", tracePrefix, domain.ContentId, request.Culture.Name);
|
||||
_logger.LogDebug("{TracePrefix}Got domain on node {DomainContentId}, set culture to {CultureName}", tracePrefix, domain.ContentId, request.Culture);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -665,7 +665,14 @@ namespace Umbraco.Web.Routing
|
||||
var templateId = request.PublishedContent.TemplateId;
|
||||
ITemplate template = GetTemplate(templateId);
|
||||
request.SetTemplate(template);
|
||||
_logger.LogDebug("FindTemplate: Running with template id={TemplateId} alias={TemplateAlias}", template.Id, template.Alias);
|
||||
if (template != null)
|
||||
{
|
||||
_logger.LogDebug("FindTemplate: Running with template id={TemplateId} alias={TemplateAlias}", template.Id, template.Alias);
|
||||
}
|
||||
else
|
||||
{
|
||||
_logger.LogWarning("FindTemplate: Could not find template with id {TemplateId}", templateId);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
@@ -284,9 +284,11 @@ namespace Umbraco.Web.Routing
|
||||
// we do our best, but can't do the impossible
|
||||
// get the "default" domain ie the first one for the culture, else the first one (exists, length > 0)
|
||||
if (qualifiedSites == null)
|
||||
return domainAndUris.FirstOrDefault(x => x.Culture.Name.InvariantEquals(culture)) ??
|
||||
domainAndUris.FirstOrDefault(x => x.Culture.Name.InvariantEquals(defaultCulture)) ??
|
||||
domainAndUris.First();
|
||||
{
|
||||
return domainAndUris.FirstOrDefault(x => x.Culture.InvariantEquals(culture))
|
||||
?? domainAndUris.FirstOrDefault(x => x.Culture.InvariantEquals(defaultCulture))
|
||||
?? domainAndUris.First();
|
||||
}
|
||||
|
||||
// find a site that contains the current authority
|
||||
var currentSite = qualifiedSites.FirstOrDefault(site => site.Value.Contains(currentAuthority));
|
||||
@@ -308,7 +310,7 @@ namespace Umbraco.Web.Routing
|
||||
.FirstOrDefault(domainAndUri => domainAndUri != null);
|
||||
|
||||
// random, really
|
||||
ret = ret ?? domainAndUris.FirstOrDefault(x => x.Culture.Name.InvariantEquals(culture)) ?? domainAndUris.First();
|
||||
ret = ret ?? domainAndUris.FirstOrDefault(x => x.Culture.InvariantEquals(culture)) ?? domainAndUris.First();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -1,9 +1,5 @@
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Security.Principal;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
|
||||
namespace Umbraco.Core.Security
|
||||
@@ -13,7 +9,6 @@ namespace Umbraco.Core.Security
|
||||
/// <summary>
|
||||
/// Ensures that the thread culture is set based on the back office user's culture
|
||||
/// </summary>
|
||||
/// <param name="identity"></param>
|
||||
public static void EnsureCulture(this IIdentity identity)
|
||||
{
|
||||
var culture = GetCulture(identity);
|
||||
@@ -27,16 +22,10 @@ namespace Umbraco.Core.Security
|
||||
{
|
||||
if (identity is UmbracoBackOfficeIdentity umbIdentity && umbIdentity.IsAuthenticated)
|
||||
{
|
||||
return UserCultures.GetOrAdd(umbIdentity.Culture, s => new CultureInfo(s));
|
||||
return CultureInfo.GetCultureInfo(umbIdentity.Culture);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Used so that we aren't creating a new CultureInfo object for every single request
|
||||
/// </summary>
|
||||
private static readonly ConcurrentDictionary<string, CultureInfo> UserCultures = new ConcurrentDictionary<string, CultureInfo>();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using Umbraco.Core.Models.PublishedContent;
|
||||
using Umbraco.Core.Strings;
|
||||
|
||||
@@ -12,35 +13,31 @@ namespace Umbraco.Core.Templates
|
||||
/// <summary>
|
||||
/// Renders the template for the specified pageId and an optional altTemplateId
|
||||
/// </summary>
|
||||
/// <param name="contentId"></param>
|
||||
/// <param name="contentId">The content id</param>
|
||||
/// <param name="altTemplateId">If not specified, will use the template assigned to the node</param>
|
||||
/// <returns></returns>
|
||||
IHtmlEncodedString RenderTemplate(int contentId, int? altTemplateId = null);
|
||||
Task<IHtmlEncodedString> RenderTemplateAsync(int contentId, int? altTemplateId = null);
|
||||
|
||||
/// <summary>
|
||||
/// Renders the macro with the specified alias.
|
||||
/// </summary>
|
||||
/// <param name="contentId"></param>
|
||||
/// <param name="contentId">The content id</param>
|
||||
/// <param name="alias">The alias.</param>
|
||||
/// <returns></returns>
|
||||
IHtmlEncodedString RenderMacro(int contentId, string alias);
|
||||
|
||||
/// <summary>
|
||||
/// Renders the macro with the specified alias, passing in the specified parameters.
|
||||
/// </summary>
|
||||
/// <param name="contentId"></param>
|
||||
/// <param name="contentId">The content id</param>
|
||||
/// <param name="alias">The alias.</param>
|
||||
/// <param name="parameters">The parameters.</param>
|
||||
/// <returns></returns>
|
||||
IHtmlEncodedString RenderMacro(int contentId, string alias, object parameters);
|
||||
|
||||
/// <summary>
|
||||
/// Renders the macro with the specified alias, passing in the specified parameters.
|
||||
/// </summary>
|
||||
/// <param name="contentId"></param>
|
||||
/// <param name="contentId">The content id</param>
|
||||
/// <param name="alias">The alias.</param>
|
||||
/// <param name="parameters">The parameters.</param>
|
||||
/// <returns></returns>
|
||||
IHtmlEncodedString RenderMacro(int contentId, string alias, IDictionary<string, object> parameters);
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using System;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.IO;
|
||||
using Umbraco.Web.Templates;
|
||||
@@ -8,6 +8,7 @@ using Umbraco.Core.Models.PublishedContent;
|
||||
using Umbraco.Core.Strings;
|
||||
using Umbraco.Web;
|
||||
using Umbraco.Web.Macros;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Umbraco.Core.Templates
|
||||
{
|
||||
@@ -24,6 +25,9 @@ namespace Umbraco.Core.Templates
|
||||
private readonly IMacroRenderer _macroRenderer;
|
||||
private readonly ITemplateRenderer _templateRenderer;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="UmbracoComponentRenderer"/> class.
|
||||
/// </summary>
|
||||
public UmbracoComponentRenderer(IUmbracoContextAccessor umbracoContextAccessor, IMacroRenderer macroRenderer, ITemplateRenderer templateRenderer)
|
||||
{
|
||||
_umbracoContextAccessor = umbracoContextAccessor;
|
||||
@@ -31,76 +35,55 @@ namespace Umbraco.Core.Templates
|
||||
_templateRenderer = templateRenderer ?? throw new ArgumentNullException(nameof(templateRenderer));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Renders the template for the specified pageId and an optional altTemplateId
|
||||
/// </summary>
|
||||
/// <param name="contentId"></param>
|
||||
/// <param name="altTemplateId">If not specified, will use the template assigned to the node</param>
|
||||
/// <returns></returns>
|
||||
public IHtmlEncodedString RenderTemplate(int contentId, int? altTemplateId = null)
|
||||
/// <inheritdoc/>
|
||||
public async Task<IHtmlEncodedString> RenderTemplateAsync(int contentId, int? altTemplateId = null)
|
||||
{
|
||||
using (var sw = new StringWriter())
|
||||
{
|
||||
try
|
||||
{
|
||||
_templateRenderer.RenderAsync(contentId, altTemplateId, sw);
|
||||
await _templateRenderer.RenderAsync(contentId, altTemplateId, sw);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
sw.Write("<!-- Error rendering template with id {0}: '{1}' -->", contentId, ex);
|
||||
}
|
||||
|
||||
return new HtmlEncodedString(sw.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Renders the macro with the specified alias.
|
||||
/// </summary>
|
||||
/// <param name="contentId"></param>
|
||||
/// <param name="alias">The alias.</param>
|
||||
/// <returns></returns>
|
||||
public IHtmlEncodedString RenderMacro(int contentId, string alias)
|
||||
{
|
||||
return RenderMacro(contentId, alias, new { });
|
||||
}
|
||||
/// <inheritdoc/>
|
||||
public IHtmlEncodedString RenderMacro(int contentId, string alias) => RenderMacro(contentId, alias, new { });
|
||||
|
||||
/// <summary>
|
||||
/// Renders the macro with the specified alias, passing in the specified parameters.
|
||||
/// </summary>
|
||||
/// <param name="contentId"></param>
|
||||
/// <param name="alias">The alias.</param>
|
||||
/// <param name="parameters">The parameters.</param>
|
||||
/// <returns></returns>
|
||||
public IHtmlEncodedString RenderMacro(int contentId, string alias, object parameters)
|
||||
{
|
||||
return RenderMacro(contentId, alias, parameters?.ToDictionary<object>());
|
||||
}
|
||||
/// <inheritdoc/>
|
||||
public IHtmlEncodedString RenderMacro(int contentId, string alias, object parameters) => RenderMacro(contentId, alias, parameters?.ToDictionary<object>());
|
||||
|
||||
/// <summary>
|
||||
/// Renders the macro with the specified alias, passing in the specified parameters.
|
||||
/// </summary>
|
||||
/// <param name="contentId"></param>
|
||||
/// <param name="alias">The alias.</param>
|
||||
/// <param name="parameters">The parameters.</param>
|
||||
/// <returns></returns>
|
||||
/// <inheritdoc/>
|
||||
public IHtmlEncodedString RenderMacro(int contentId, string alias, IDictionary<string, object> parameters)
|
||||
{
|
||||
if (contentId == default)
|
||||
{
|
||||
throw new ArgumentException("Invalid content id " + contentId);
|
||||
}
|
||||
|
||||
var content = _umbracoContextAccessor.UmbracoContext.Content?.GetById(contentId);
|
||||
|
||||
if (content == null)
|
||||
{
|
||||
throw new InvalidOperationException("Cannot render a macro, no content found by id " + contentId);
|
||||
}
|
||||
|
||||
return RenderMacro(content, alias, parameters);
|
||||
}
|
||||
|
||||
|
||||
/// <inheritdoc/>
|
||||
public IHtmlEncodedString RenderMacroForContent(IPublishedContent content, string alias, IDictionary<string, object> parameters)
|
||||
{
|
||||
if(content == null)
|
||||
{
|
||||
throw new InvalidOperationException("Cannot render a macro, IPublishedContent is null");
|
||||
}
|
||||
|
||||
return RenderMacro(content, alias, parameters);
|
||||
}
|
||||
@@ -108,16 +91,15 @@ namespace Umbraco.Core.Templates
|
||||
/// <summary>
|
||||
/// Renders the macro with the specified alias, passing in the specified parameters.
|
||||
/// </summary>
|
||||
/// <param name="alias">The macro alias.</param>
|
||||
/// <param name="parameters">The parameters.</param>
|
||||
/// <param name="content">The content used for macro rendering</param>
|
||||
/// <returns></returns>
|
||||
private IHtmlEncodedString RenderMacro(IPublishedContent content, string alias, IDictionary<string, object> parameters)
|
||||
{
|
||||
if (content == null) throw new ArgumentNullException(nameof(content));
|
||||
if (content == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(content));
|
||||
}
|
||||
|
||||
// TODO: We are doing at ToLower here because for some insane reason the UpdateMacroModel method looks for a lower case match. the whole macro concept needs to be rewritten.
|
||||
//NOTE: the value could have HTML encoded values, so we need to deal with that
|
||||
// NOTE: the value could have HTML encoded values, so we need to deal with that
|
||||
var macroProps = parameters?.ToDictionary(
|
||||
x => x.Key.ToLowerInvariant(),
|
||||
i => (i.Value is string) ? WebUtility.HtmlDecode(i.Value.ToString()) : i.Value);
|
||||
|
||||
@@ -54,7 +54,7 @@ namespace Umbraco.Web.Routing
|
||||
_logger.LogDebug("Looking for a page to handle 404.");
|
||||
|
||||
// try to find a culture as best as we can
|
||||
CultureInfo errorCulture = CultureInfo.CurrentUICulture;
|
||||
string errorCulture = CultureInfo.CurrentUICulture.Name;
|
||||
if (frequest.Domain != null)
|
||||
{
|
||||
errorCulture = frequest.Domain.Culture;
|
||||
@@ -67,7 +67,7 @@ namespace Umbraco.Web.Routing
|
||||
while (pos > 1)
|
||||
{
|
||||
route = route.Substring(0, pos);
|
||||
node = umbCtx.Content.GetByRoute(route, culture: frequest?.Culture?.Name);
|
||||
node = umbCtx.Content.GetByRoute(route, culture: frequest?.Culture);
|
||||
if (node != null)
|
||||
{
|
||||
break;
|
||||
|
||||
@@ -21,12 +21,12 @@ namespace Umbraco.Web.Routing
|
||||
ContentErrorPage[] error404Collection,
|
||||
IEntityService entityService,
|
||||
IPublishedContentQuery publishedContentQuery,
|
||||
CultureInfo errorCulture)
|
||||
string errorCulture)
|
||||
{
|
||||
if (error404Collection.Length > 1)
|
||||
{
|
||||
// test if a 404 page exists with current culture thread
|
||||
ContentErrorPage cultureErr = error404Collection.FirstOrDefault(x => x.Culture == errorCulture.Name)
|
||||
ContentErrorPage cultureErr = error404Collection.FirstOrDefault(x => x.Culture.InvariantEquals(errorCulture))
|
||||
?? error404Collection.FirstOrDefault(x => x.Culture == "default"); // there should be a default one!
|
||||
|
||||
if (cultureErr != null)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
@@ -86,7 +86,6 @@ namespace Umbraco.Core.Services.Implement
|
||||
/// <summary>
|
||||
/// Returns all key/values in storage for the given culture
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public IDictionary<string, string> GetAllStoredValues(CultureInfo culture)
|
||||
{
|
||||
if (culture == null) throw new ArgumentNullException("culture");
|
||||
@@ -108,16 +107,18 @@ namespace Umbraco.Core.Services.Implement
|
||||
return result;
|
||||
}
|
||||
|
||||
//convert all areas + keys to a single key with a '/'
|
||||
// convert all areas + keys to a single key with a '/'
|
||||
result = GetStoredTranslations(xmlSource, culture);
|
||||
|
||||
//merge with the English file in case there's keys in there that don't exist in the local file
|
||||
var englishCulture = new CultureInfo("en-US");
|
||||
// merge with the English file in case there's keys in there that don't exist in the local file
|
||||
var englishCulture = CultureInfo.GetCultureInfo("en-US");
|
||||
if (culture.Equals(englishCulture) == false)
|
||||
{
|
||||
var englishResults = GetStoredTranslations(xmlSource, englishCulture);
|
||||
foreach (var englishResult in englishResults.Where(englishResult => result.ContainsKey(englishResult.Key) == false))
|
||||
{
|
||||
result.Add(englishResult.Key, englishResult.Value);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -128,13 +129,13 @@ namespace Umbraco.Core.Services.Implement
|
||||
return result;
|
||||
}
|
||||
|
||||
//convert all areas + keys to a single key with a '/'
|
||||
// convert all areas + keys to a single key with a '/'
|
||||
foreach (var area in _dictionarySource[culture])
|
||||
{
|
||||
foreach (var key in area.Value)
|
||||
{
|
||||
var dictionaryKey = string.Format("{0}/{1}", area.Key, key.Key);
|
||||
//i don't think it's possible to have duplicates because we're dealing with a dictionary in the first place, but we'll double check here just in case.
|
||||
// i don't think it's possible to have duplicates because we're dealing with a dictionary in the first place, but we'll double check here just in case.
|
||||
if (result.ContainsKey(dictionaryKey) == false)
|
||||
{
|
||||
result.Add(dictionaryKey, key.Value);
|
||||
|
||||
@@ -461,7 +461,7 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
var domains = _serviceContext.DomainService.GetAll(true);
|
||||
foreach (var domain in domains
|
||||
.Where(x => x.RootContentId.HasValue && x.LanguageIsoCode.IsNullOrWhiteSpace() == false)
|
||||
.Select(x => new Domain(x.Id, x.DomainName, x.RootContentId.Value, CultureInfo.GetCultureInfo(x.LanguageIsoCode), x.IsWildcard)))
|
||||
.Select(x => new Domain(x.Id, x.DomainName, x.RootContentId.Value, x.LanguageIsoCode, x.IsWildcard)))
|
||||
{
|
||||
_domainStore.SetLocked(domain.Id, domain);
|
||||
}
|
||||
@@ -865,7 +865,7 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
if (domain == null) continue;
|
||||
if (domain.RootContentId.HasValue == false) continue; // anomaly
|
||||
if (domain.LanguageIsoCode.IsNullOrWhiteSpace()) continue; // anomaly
|
||||
var culture = CultureInfo.GetCultureInfo(domain.LanguageIsoCode);
|
||||
var culture = domain.LanguageIsoCode;
|
||||
_domainStore.SetLocked(domain.Id, new Domain(domain.Id, domain.DomainName, domain.RootContentId.Value, culture, domain.IsWildcard));
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@ namespace Umbraco.Tests.UnitTests.Umbraco.Core.CoreThings
|
||||
public void TestSetup()
|
||||
{
|
||||
_savedCulture = Thread.CurrentThread.CurrentCulture;
|
||||
Thread.CurrentThread.CurrentCulture = new CultureInfo("en-GB"); // make sure the dates parse correctly
|
||||
Thread.CurrentThread.CurrentCulture = CultureInfo.GetCultureInfo("en-GB"); // make sure the dates parse correctly
|
||||
}
|
||||
|
||||
[TearDown]
|
||||
|
||||
@@ -19,8 +19,8 @@ namespace Umbraco.Tests.UnitTests.Umbraco.Core.Routing
|
||||
[TearDown]
|
||||
public void TearDown() => SiteDomainHelper.Clear(); // assuming this works!
|
||||
|
||||
private static readonly CultureInfo s_cultureFr = CultureInfo.GetCultureInfo("fr-fr");
|
||||
private static readonly CultureInfo s_cultureGb = CultureInfo.GetCultureInfo("en-gb");
|
||||
private static readonly string s_cultureFr = "fr-fr";
|
||||
private static readonly string s_cultureGb = "en-gb";
|
||||
|
||||
[Test]
|
||||
public void AddSites()
|
||||
@@ -185,7 +185,7 @@ namespace Umbraco.Tests.UnitTests.Umbraco.Core.Routing
|
||||
new Domain(1, "domain1.com", -1, s_cultureGb, false),
|
||||
};
|
||||
DomainAndUri[] domainAndUris = DomainAndUris(current, domains);
|
||||
string output = helper.MapDomain(domainAndUris, current, s_cultureFr.Name, s_cultureFr.Name).Uri.ToString();
|
||||
string output = helper.MapDomain(domainAndUris, current, s_cultureFr, s_cultureFr).Uri.ToString();
|
||||
Assert.AreEqual("https://domain1.com/", output);
|
||||
|
||||
// will pick it all right
|
||||
@@ -196,7 +196,7 @@ namespace Umbraco.Tests.UnitTests.Umbraco.Core.Routing
|
||||
new Domain(1, "https://domain2.com", -1, s_cultureGb, false)
|
||||
};
|
||||
domainAndUris = DomainAndUris(current, domains);
|
||||
output = helper.MapDomain(domainAndUris, current, s_cultureFr.Name, s_cultureFr.Name).Uri.ToString();
|
||||
output = helper.MapDomain(domainAndUris, current, s_cultureFr, s_cultureFr).Uri.ToString();
|
||||
Assert.AreEqual("https://domain1.com/", output);
|
||||
|
||||
current = new Uri("https://domain1.com/foo/bar");
|
||||
@@ -206,7 +206,7 @@ namespace Umbraco.Tests.UnitTests.Umbraco.Core.Routing
|
||||
new Domain(1, "https://domain4.com", -1, s_cultureGb, false)
|
||||
};
|
||||
domainAndUris = DomainAndUris(current, domains);
|
||||
output = helper.MapDomain(domainAndUris, current, s_cultureFr.Name, s_cultureFr.Name).Uri.ToString();
|
||||
output = helper.MapDomain(domainAndUris, current, s_cultureFr, s_cultureFr).Uri.ToString();
|
||||
Assert.AreEqual("https://domain1.com/", output);
|
||||
|
||||
current = new Uri("https://domain4.com/foo/bar");
|
||||
@@ -216,7 +216,7 @@ namespace Umbraco.Tests.UnitTests.Umbraco.Core.Routing
|
||||
new Domain(1, "https://domain4.com", -1, s_cultureGb, false)
|
||||
};
|
||||
domainAndUris = DomainAndUris(current, domains);
|
||||
output = helper.MapDomain(domainAndUris, current, s_cultureFr.Name, s_cultureFr.Name).Uri.ToString();
|
||||
output = helper.MapDomain(domainAndUris, current, s_cultureFr, s_cultureFr).Uri.ToString();
|
||||
Assert.AreEqual("https://domain4.com/", output);
|
||||
}
|
||||
|
||||
@@ -240,8 +240,8 @@ namespace Umbraco.Tests.UnitTests.Umbraco.Core.Routing
|
||||
new DomainAndUri(new Domain(1, "domain1.com", -1, s_cultureFr, false), current),
|
||||
new DomainAndUri(new Domain(1, "domain2.com", -1, s_cultureGb, false), current),
|
||||
}, current,
|
||||
s_cultureFr.Name,
|
||||
s_cultureFr.Name).Uri.ToString();
|
||||
s_cultureFr,
|
||||
s_cultureFr).Uri.ToString();
|
||||
Assert.AreEqual("http://domain1.com/", output);
|
||||
|
||||
// current is a site1 uri, domains do not contain current
|
||||
@@ -253,8 +253,8 @@ namespace Umbraco.Tests.UnitTests.Umbraco.Core.Routing
|
||||
new DomainAndUri(new Domain(1, "domain1.net", -1, s_cultureFr, false), current),
|
||||
new DomainAndUri(new Domain(1, "domain2.net", -1, s_cultureGb, false), current)
|
||||
}, current,
|
||||
s_cultureFr.Name,
|
||||
s_cultureFr.Name).Uri.ToString();
|
||||
s_cultureFr,
|
||||
s_cultureFr).Uri.ToString();
|
||||
Assert.AreEqual("http://domain1.net/", output);
|
||||
|
||||
// current is a site1 uri, domains do not contain current
|
||||
@@ -267,8 +267,8 @@ namespace Umbraco.Tests.UnitTests.Umbraco.Core.Routing
|
||||
new DomainAndUri(new Domain(1, "domain2.net", -1, s_cultureFr, false), current),
|
||||
new DomainAndUri(new Domain(1, "domain1.net", -1, s_cultureGb, false), current)
|
||||
}, current,
|
||||
s_cultureFr.Name,
|
||||
s_cultureFr.Name).Uri.ToString();
|
||||
s_cultureFr,
|
||||
s_cultureFr).Uri.ToString();
|
||||
Assert.AreEqual("http://domain1.net/", output);
|
||||
}
|
||||
|
||||
@@ -301,8 +301,8 @@ namespace Umbraco.Tests.UnitTests.Umbraco.Core.Routing
|
||||
},
|
||||
current,
|
||||
true,
|
||||
s_cultureFr.Name,
|
||||
s_cultureFr.Name).ToArray();
|
||||
s_cultureFr,
|
||||
s_cultureFr).ToArray();
|
||||
|
||||
Assert.AreEqual(1, output.Count());
|
||||
Assert.Contains("http://domain1.org/", output.Select(d => d.Uri.ToString()).ToArray());
|
||||
@@ -320,8 +320,8 @@ namespace Umbraco.Tests.UnitTests.Umbraco.Core.Routing
|
||||
},
|
||||
current,
|
||||
true,
|
||||
s_cultureFr.Name,
|
||||
s_cultureFr.Name).ToArray();
|
||||
s_cultureFr,
|
||||
s_cultureFr).ToArray();
|
||||
|
||||
Assert.AreEqual(1, output.Count());
|
||||
Assert.Contains("http://domain1.org/", output.Select(d => d.Uri.ToString()).ToArray());
|
||||
@@ -343,8 +343,8 @@ namespace Umbraco.Tests.UnitTests.Umbraco.Core.Routing
|
||||
},
|
||||
current,
|
||||
true,
|
||||
s_cultureFr.Name,
|
||||
s_cultureFr.Name).ToArray();
|
||||
s_cultureFr,
|
||||
s_cultureFr).ToArray();
|
||||
|
||||
Assert.AreEqual(3, output.Count());
|
||||
Assert.Contains("http://domain1.org/", output.Select(d => d.Uri.ToString()).ToArray());
|
||||
@@ -364,8 +364,8 @@ namespace Umbraco.Tests.UnitTests.Umbraco.Core.Routing
|
||||
new DomainAndUri(new Domain(1, "domain1.org", -1, s_cultureGb, false), current), // yes: same site (though bogus setup)
|
||||
}, current,
|
||||
true,
|
||||
s_cultureFr.Name,
|
||||
s_cultureFr.Name).ToArray();
|
||||
s_cultureFr,
|
||||
s_cultureFr).ToArray();
|
||||
|
||||
Assert.AreEqual(3, output.Count());
|
||||
Assert.Contains("http://domain1.org/", output.Select(d => d.Uri.ToString()).ToArray());
|
||||
|
||||
@@ -48,7 +48,7 @@ namespace Umbraco.Tests.UnitTests.Umbraco.Core.Web.Routing
|
||||
|
||||
sut.SetDomain(
|
||||
new DomainAndUri(
|
||||
new Domain(1, "test", 2, CultureInfo.GetCultureInfo("en-AU"), false), new Uri("https://example.com/en-au")));
|
||||
new Domain(1, "test", 2, "en-AU", false), new Uri("https://example.com/en-au")));
|
||||
|
||||
Assert.IsNotNull(sut.Domain);
|
||||
Assert.IsNotNull(sut.Culture);
|
||||
@@ -62,8 +62,8 @@ namespace Umbraco.Tests.UnitTests.Umbraco.Core.Web.Routing
|
||||
IPublishedContent content = Mock.Of<IPublishedContent>(x => x.Id == 1);
|
||||
ITemplate template = Mock.Of<ITemplate>(x => x.Id == 1);
|
||||
string[] cacheExt = new[] { "must-revalidate" };
|
||||
var auCulture = CultureInfo.GetCultureInfo("en-AU");
|
||||
var usCulture = CultureInfo.GetCultureInfo("en-US");
|
||||
var auCulture = "en-AU";
|
||||
var usCulture = "en-US";
|
||||
var domain = new DomainAndUri(
|
||||
new Domain(1, "test", 2, auCulture, false), new Uri("https://example.com/en-au"));
|
||||
IReadOnlyDictionary<string, string> headers = new Dictionary<string, string> { ["Hello"] = "world" };
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using Umbraco.Core;
|
||||
@@ -19,20 +19,14 @@ namespace Umbraco.Tests.LegacyXmlPublishedCache
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public IEnumerable<Domain> GetAll(bool includeWildcards)
|
||||
{
|
||||
return _domainService.GetAll(includeWildcards)
|
||||
public IEnumerable<Domain> GetAll(bool includeWildcards) => _domainService.GetAll(includeWildcards)
|
||||
.Where(x => x.RootContentId.HasValue && x.LanguageIsoCode.IsNullOrWhiteSpace() == false)
|
||||
.Select(x => new Domain(x.Id, x.DomainName, x.RootContentId.Value, CultureInfo.GetCultureInfo(x.LanguageIsoCode), x.IsWildcard));
|
||||
}
|
||||
.Select(x => new Domain(x.Id, x.DomainName, x.RootContentId.Value, x.LanguageIsoCode, x.IsWildcard));
|
||||
|
||||
/// <inheritdoc />
|
||||
public IEnumerable<Domain> GetAssigned(int documentId, bool includeWildcards = false)
|
||||
{
|
||||
return _domainService.GetAssignedDomains(documentId, includeWildcards)
|
||||
public IEnumerable<Domain> GetAssigned(int documentId, bool includeWildcards = false) => _domainService.GetAssignedDomains(documentId, includeWildcards)
|
||||
.Where(x => x.RootContentId.HasValue && x.LanguageIsoCode.IsNullOrWhiteSpace() == false)
|
||||
.Select(x => new Domain(x.Id, x.DomainName, x.RootContentId.Value, CultureInfo.GetCultureInfo(x.LanguageIsoCode), x.IsWildcard));
|
||||
}
|
||||
.Select(x => new Domain(x.Id, x.DomainName, x.RootContentId.Value, x.LanguageIsoCode, x.IsWildcard));
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool HasAssigned(int documentId, bool includeWildcards = false)
|
||||
|
||||
@@ -35,7 +35,7 @@ namespace Umbraco.Tests.PublishedContent
|
||||
var request = await publishedRouter.CreateRequestAsync(umbracoContext.CleanedUmbracoUrl);
|
||||
var content = GetPublishedContentMock();
|
||||
request.SetPublishedContent(content.Object);
|
||||
request.SetCulture(new CultureInfo("en-AU"));
|
||||
request.SetCulture("en-AU");
|
||||
request.SetRedirect("/hello");
|
||||
var result = publishedRouter.BuildRequest(request);
|
||||
|
||||
|
||||
@@ -64,7 +64,9 @@ namespace Umbraco.Tests.Routing
|
||||
publishedRouter.FindDomain(request);
|
||||
|
||||
if (expectedNode > 0)
|
||||
Assert.AreEqual(expectedCulture, request.Culture.Name);
|
||||
{
|
||||
Assert.AreEqual(expectedCulture, request.Culture);
|
||||
}
|
||||
|
||||
var finder = new ContentFinderByUrlAlias(LoggerFactory.CreateLogger<ContentFinderByUrlAlias>(), Mock.Of<IPublishedValueFallback>(), VariationContextAccessor, GetUmbracoContextAccessor(umbracoContext));
|
||||
var result = finder.TryFindContent(request);
|
||||
|
||||
@@ -49,8 +49,9 @@ namespace Umbraco.Tests.Routing
|
||||
|
||||
Assert.IsTrue(result);
|
||||
Assert.IsNotNull(frequest.PublishedContent);
|
||||
Assert.IsNotNull(frequest.GetTemplateAlias());
|
||||
Assert.AreEqual("blah".ToUpperInvariant(), frequest.GetTemplateAlias().ToUpperInvariant());
|
||||
var templateAlias = frequest.GetTemplateAlias();
|
||||
Assert.IsNotNull(templateAlias );
|
||||
Assert.AreEqual("blah".ToUpperInvariant(), templateAlias.ToUpperInvariant());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,7 +34,7 @@ namespace Umbraco.Tests.Routing
|
||||
var snapshotService = CreatePublishedSnapshotService(globalSettings);
|
||||
var umbracoContext = GetUmbracoContext(urlString, globalSettings:globalSettings, snapshotService: snapshotService);
|
||||
var publishedRouter = CreatePublishedRouter(GetUmbracoContextAccessor(umbracoContext));
|
||||
var frequest = await publishedRouter .CreateRequestAsync(umbracoContext.CleanedUmbracoUrl);
|
||||
var frequest = await publishedRouter.CreateRequestAsync(umbracoContext.CleanedUmbracoUrl);
|
||||
var lookup = new ContentFinderByUrl(LoggerFactory.CreateLogger<ContentFinderByUrl>(), GetUmbracoContextAccessor(umbracoContext));
|
||||
|
||||
Assert.IsTrue(globalSettings.HideTopLevelNodeFromPath);
|
||||
@@ -119,7 +119,7 @@ namespace Umbraco.Tests.Routing
|
||||
var umbracoContext = GetUmbracoContext(urlString, globalSettings:globalSettings);
|
||||
var publishedRouter = CreatePublishedRouter(GetUmbracoContextAccessor(umbracoContext));
|
||||
var frequest = await publishedRouter .CreateRequestAsync(umbracoContext.CleanedUmbracoUrl);
|
||||
frequest.SetDomain(new DomainAndUri(new Domain(1, "mysite", -1, CultureInfo.CurrentCulture, false), new Uri("http://mysite/")));
|
||||
frequest.SetDomain(new DomainAndUri(new Domain(1, "mysite", -1, "en-US", false), new Uri("http://mysite/")));
|
||||
var lookup = new ContentFinderByUrl(LoggerFactory.CreateLogger<ContentFinderByUrl>(), GetUmbracoContextAccessor(umbracoContext));
|
||||
|
||||
var result = lookup.TryFindContent(frequest);
|
||||
@@ -147,7 +147,7 @@ namespace Umbraco.Tests.Routing
|
||||
var umbracoContext = GetUmbracoContext(urlString, globalSettings:globalSettings);
|
||||
var publishedRouter = CreatePublishedRouter(GetUmbracoContextAccessor(umbracoContext));
|
||||
var frequest = await publishedRouter .CreateRequestAsync(umbracoContext.CleanedUmbracoUrl);
|
||||
frequest.SetDomain(new DomainAndUri(new Domain(1, "mysite/æøå", -1, CultureInfo.CurrentCulture, false), new Uri("http://mysite/æøå")));
|
||||
frequest.SetDomain(new DomainAndUri(new Domain(1, "mysite/æøå", -1, "en-US", false), new Uri("http://mysite/æøå")));
|
||||
var lookup = new ContentFinderByUrl(LoggerFactory.CreateLogger<ContentFinderByUrl>(), GetUmbracoContextAccessor(umbracoContext));
|
||||
|
||||
var result = lookup.TryFindContent(frequest);
|
||||
|
||||
@@ -180,7 +180,7 @@ namespace Umbraco.Tests.Routing
|
||||
|
||||
// must lookup domain else lookup by URL fails
|
||||
publishedRouter.FindDomain(frequest);
|
||||
Assert.AreEqual(expectedCulture, frequest.Culture.Name);
|
||||
Assert.AreEqual(expectedCulture, frequest.Culture);
|
||||
|
||||
var lookup = new ContentFinderByUrl(LoggerFactory.CreateLogger<ContentFinderByUrl>(), GetUmbracoContextAccessor(umbracoContext));
|
||||
var result = lookup.TryFindContent(frequest);
|
||||
|
||||
@@ -275,7 +275,7 @@ namespace Umbraco.Tests.Routing
|
||||
// lookup domain
|
||||
publishedRouter.FindDomain(frequest);
|
||||
|
||||
Assert.AreEqual(expectedCulture, frequest.Culture.Name);
|
||||
Assert.AreEqual(expectedCulture, frequest.Culture);
|
||||
|
||||
var finder = new ContentFinderByUrl(LoggerFactory.CreateLogger<ContentFinderByUrl>(), GetUmbracoContextAccessor(umbracoContext));
|
||||
var result = finder.TryFindContent(frequest);
|
||||
@@ -331,7 +331,7 @@ namespace Umbraco.Tests.Routing
|
||||
publishedRouter.HandleWildcardDomains(frequest);
|
||||
|
||||
Assert.IsTrue(result);
|
||||
Assert.AreEqual(expectedCulture, frequest.Culture.Name);
|
||||
Assert.AreEqual(expectedCulture, frequest.Culture);
|
||||
Assert.AreEqual(frequest.PublishedContent.Id, expectedNode);
|
||||
}
|
||||
// domains such as "/en" are natively supported, and when instanciating
|
||||
@@ -377,7 +377,7 @@ namespace Umbraco.Tests.Routing
|
||||
publishedRouter.FindDomain(frequest);
|
||||
Assert.IsNotNull(frequest.Domain);
|
||||
|
||||
Assert.AreEqual(expectedCulture, frequest.Culture.Name);
|
||||
Assert.AreEqual(expectedCulture, frequest.Culture);
|
||||
|
||||
var finder = new ContentFinderByUrl(LoggerFactory.CreateLogger<ContentFinderByUrl>(), GetUmbracoContextAccessor(umbracoContext));
|
||||
var result = finder.TryFindContent(frequest);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
@@ -186,8 +186,8 @@ namespace Umbraco.Tests.Routing
|
||||
if (contentId != 9876) return Enumerable.Empty<Domain>();
|
||||
return new[]
|
||||
{
|
||||
new Domain(2, "example.us", 9876, CultureInfo.GetCultureInfo("en-US"), false), //default
|
||||
new Domain(3, "example.fr", 9876, CultureInfo.GetCultureInfo("fr-FR"), false)
|
||||
new Domain(2, "example.us", 9876, "en-US", false), //default
|
||||
new Domain(3, "example.fr", 9876, "fr-FR", false)
|
||||
};
|
||||
});
|
||||
domainCache.Setup(x => x.DefaultCulture).Returns(CultureInfo.GetCultureInfo("en-US").Name);
|
||||
@@ -240,8 +240,8 @@ namespace Umbraco.Tests.Routing
|
||||
if (contentId != 9876) return Enumerable.Empty<Domain>();
|
||||
return new[]
|
||||
{
|
||||
new Domain(2, "example.us", 9876, CultureInfo.GetCultureInfo("en-US"), false), //default
|
||||
new Domain(3, "example.fr", 9876, CultureInfo.GetCultureInfo("fr-FR"), false)
|
||||
new Domain(2, "example.us", 9876, "en-US", false), //default
|
||||
new Domain(3, "example.fr", 9876, "fr-FR", false)
|
||||
};
|
||||
});
|
||||
domainCache.Setup(x => x.DefaultCulture).Returns(CultureInfo.GetCultureInfo("en-US").Name);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
@@ -50,6 +50,7 @@ namespace Umbraco.Web.BackOffice.Controllers
|
||||
// get cultures - new-ing instances to get proper display name,
|
||||
// in the current culture, and not the cached one
|
||||
// (see notes in Language class about culture info names)
|
||||
// TODO: Fix this requirement, see https://github.com/umbraco/Umbraco-CMS/issues/3623
|
||||
return CultureInfo.GetCultures(CultureTypes.AllCultures)
|
||||
.Where(x => !x.Name.IsNullOrWhiteSpace())
|
||||
.Select(x => new CultureInfo(x.Name)) // important!
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Mvc.Controllers;
|
||||
using Microsoft.AspNetCore.Mvc.Infrastructure;
|
||||
using Umbraco.Core;
|
||||
@@ -49,7 +50,7 @@ namespace Umbraco.Web.BackOffice.Controllers
|
||||
_actionDescriptorCollectionProvider = actionDescriptorCollectionProvider;
|
||||
}
|
||||
|
||||
public IEnumerable<Section> GetSections()
|
||||
public async Task<IEnumerable<Section>> GetSections()
|
||||
{
|
||||
var sections = _sectionService.GetAllowedSections(_backofficeSecurityAccessor.BackOfficeSecurity.GetUserId().ResultOr(0));
|
||||
|
||||
@@ -74,7 +75,7 @@ namespace Umbraco.Web.BackOffice.Controllers
|
||||
if (hasDashboards) continue;
|
||||
|
||||
// get the first tree in the section and get its root node route path
|
||||
var sectionRoot = appTreeController.GetApplicationTrees(section.Alias, null, null).Result;
|
||||
var sectionRoot = await appTreeController.GetApplicationTrees(section.Alias, null, null);
|
||||
section.RoutePath = GetRoutePathForFirstTree(sectionRoot);
|
||||
}
|
||||
|
||||
|
||||
@@ -212,7 +212,9 @@ namespace Umbraco.Web.BackOffice.Mapping
|
||||
|
||||
// NOTE: unfortunately we're not async, we'll use .Result and hope this won't cause a deadlock anywhere for now
|
||||
var urls = source.GetContentUrlsAsync(_publishedRouter, umbracoContext, _localizationService, _localizedTextService, _contentService, _variationContextAccessor, _loggerFactory.CreateLogger<IContent>(), _uriUtility, _publishedUrlProvider)
|
||||
.Result
|
||||
.ConfigureAwait(false)
|
||||
.GetAwaiter()
|
||||
.GetResult()
|
||||
.ToArray();
|
||||
|
||||
return urls;
|
||||
|
||||
@@ -52,7 +52,7 @@ namespace Umbraco.Web.Common.ActionsResults
|
||||
await response.WriteAsync("<p>" + _message + "</p>");
|
||||
}
|
||||
|
||||
await response.WriteAsync("<p>This page can be replaced with a custom 404. Check the documentation for \"custom 404\".</p>");
|
||||
await response.WriteAsync("<p>This page can be replaced with a custom 404. Check the <a target='_blank' href='https://our.umbraco.com/documentation/tutorials/Custom-Error-Pages/'>documentation for \"custom 404\"</a>.</p>");
|
||||
await response.WriteAsync("<p style=\"border-top: 1px solid #ccc; padding-top: 10px\"><small>This page is intentionally left ugly ;-)</small></p>");
|
||||
await response.WriteAsync("</body></html>");
|
||||
}
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
using System.Globalization;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Localization;
|
||||
using Microsoft.Extensions.Options;
|
||||
using Umbraco.Core.Security;
|
||||
|
||||
namespace Umbraco.Web.Common.Localization
|
||||
@@ -12,6 +14,13 @@ namespace Umbraco.Web.Common.Localization
|
||||
/// </summary>
|
||||
public class UmbracoBackOfficeIdentityCultureProvider : RequestCultureProvider
|
||||
{
|
||||
private readonly RequestLocalizationOptions _localizationOptions;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="UmbracoBackOfficeIdentityCultureProvider"/> class.
|
||||
/// </summary>
|
||||
public UmbracoBackOfficeIdentityCultureProvider(RequestLocalizationOptions localizationOptions) => _localizationOptions = localizationOptions;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override Task<ProviderCultureResult> DetermineProviderCultureResult(HttpContext httpContext)
|
||||
{
|
||||
@@ -22,6 +31,17 @@ namespace Umbraco.Web.Common.Localization
|
||||
return NullProviderCultureResult;
|
||||
}
|
||||
|
||||
// We need to dynamically change the supported cultures since we won't ever know what languages are used since
|
||||
// they are dynamic within Umbraco.
|
||||
var cultureExists = _localizationOptions.SupportedCultures.Contains(culture);
|
||||
|
||||
if (!cultureExists)
|
||||
{
|
||||
// add this as a supporting culture
|
||||
_localizationOptions.SupportedCultures.Add(culture);
|
||||
_localizationOptions.SupportedUICultures.Add(culture);
|
||||
}
|
||||
|
||||
return Task.FromResult(new ProviderCultureResult(culture.Name));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,13 @@
|
||||
using System.Globalization;
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Localization;
|
||||
using Microsoft.AspNetCore.Routing;
|
||||
using Microsoft.Extensions.Options;
|
||||
using Microsoft.Extensions.Primitives;
|
||||
using Umbraco.Web.Common.Routing;
|
||||
using Umbraco.Web.Routing;
|
||||
|
||||
@@ -13,19 +18,42 @@ namespace Umbraco.Web.Common.Localization
|
||||
/// </summary>
|
||||
public class UmbracoPublishedContentCultureProvider : RequestCultureProvider
|
||||
{
|
||||
private readonly RequestLocalizationOptions _localizationOptions;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="UmbracoPublishedContentCultureProvider"/> class.
|
||||
/// </summary>
|
||||
public UmbracoPublishedContentCultureProvider(RequestLocalizationOptions localizationOptions) => _localizationOptions = localizationOptions;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override Task<ProviderCultureResult> DetermineProviderCultureResult(HttpContext httpContext)
|
||||
{
|
||||
if (httpContext.GetRouteValue(Core.Constants.Web.UmbracoRouteDefinitionDataToken) is UmbracoRouteValues routeValues)
|
||||
{
|
||||
CultureInfo culture = routeValues.PublishedRequest?.Culture;
|
||||
string culture = routeValues.PublishedRequest?.Culture;
|
||||
if (culture != null)
|
||||
{
|
||||
return Task.FromResult(new ProviderCultureResult(culture.Name));
|
||||
// We need to dynamically change the supported cultures since we won't ever know what languages are used since
|
||||
// they are dynamic within Umbraco.
|
||||
// This code to check existence is borrowed from aspnetcore to avoid creating a CultureInfo
|
||||
// https://github.com/dotnet/aspnetcore/blob/b795ac3546eb3e2f47a01a64feb3020794ca33bb/src/Middleware/Localization/src/RequestLocalizationMiddleware.cs#L165
|
||||
CultureInfo existingCulture = _localizationOptions.SupportedCultures.FirstOrDefault(supportedCulture =>
|
||||
StringSegment.Equals(supportedCulture.Name, culture, StringComparison.OrdinalIgnoreCase));
|
||||
|
||||
if (existingCulture == null)
|
||||
{
|
||||
// add this as a supporting culture
|
||||
var ci = CultureInfo.GetCultureInfo(culture);
|
||||
_localizationOptions.SupportedCultures.Add(ci);
|
||||
_localizationOptions.SupportedUICultures.Add(ci);
|
||||
}
|
||||
|
||||
return Task.FromResult(new ProviderCultureResult(culture));
|
||||
}
|
||||
}
|
||||
|
||||
return NullProviderCultureResult;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,8 +30,8 @@ namespace Umbraco.Web.Common.Localization
|
||||
options.RequestCultureProviders = new List<IRequestCultureProvider>();
|
||||
}
|
||||
|
||||
options.RequestCultureProviders.Insert(0, new UmbracoBackOfficeIdentityCultureProvider());
|
||||
options.RequestCultureProviders.Insert(1, new UmbracoPublishedContentCultureProvider());
|
||||
options.RequestCultureProviders.Insert(0, new UmbracoBackOfficeIdentityCultureProvider(options));
|
||||
options.RequestCultureProviders.Insert(1, new UmbracoPublishedContentCultureProvider(options));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -87,8 +87,8 @@ namespace Umbraco.Web.Common.Templates
|
||||
var defaultLanguage = _languageService.GetAllLanguages().FirstOrDefault();
|
||||
|
||||
requestBuilder.SetCulture(defaultLanguage == null
|
||||
? CultureInfo.CurrentUICulture
|
||||
: defaultLanguage.CultureInfo);
|
||||
? CultureInfo.CurrentUICulture.Name
|
||||
: defaultLanguage.CultureInfo.Name);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Xml.XPath;
|
||||
using Umbraco.Core;
|
||||
@@ -7,6 +7,7 @@ using Umbraco.Core.Models.PublishedContent;
|
||||
using Umbraco.Core.Templates;
|
||||
using Umbraco.Core.Strings;
|
||||
using Umbraco.Core.Xml;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Umbraco.Web.Website
|
||||
{
|
||||
@@ -95,13 +96,10 @@ namespace Umbraco.Web.Website
|
||||
/// <summary>
|
||||
/// Renders the template for the specified pageId and an optional altTemplateId
|
||||
/// </summary>
|
||||
/// <param name="contentId"></param>
|
||||
/// <param name="contentId">The content id</param>
|
||||
/// <param name="altTemplateId">If not specified, will use the template assigned to the node</param>
|
||||
/// <returns></returns>
|
||||
public IHtmlEncodedString RenderTemplate(int contentId, int? altTemplateId = null)
|
||||
{
|
||||
return _componentRenderer.RenderTemplate(contentId, altTemplateId);
|
||||
}
|
||||
public async Task<IHtmlEncodedString> RenderTemplateAsync(int contentId, int? altTemplateId = null)
|
||||
=> await _componentRenderer.RenderTemplateAsync(contentId, altTemplateId);
|
||||
|
||||
#region RenderMacro
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Web;
|
||||
@@ -12,6 +12,7 @@ using Umbraco.Core.Xml;
|
||||
using Umbraco.Web.Mvc;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Umbraco.Web.Security;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Umbraco.Web
|
||||
{
|
||||
@@ -104,13 +105,10 @@ namespace Umbraco.Web
|
||||
/// <summary>
|
||||
/// Renders the template for the specified pageId and an optional altTemplateId
|
||||
/// </summary>
|
||||
/// <param name="contentId"></param>
|
||||
/// <param name="contentId">The content id</param>
|
||||
/// <param name="altTemplateId">If not specified, will use the template assigned to the node</param>
|
||||
/// <returns></returns>
|
||||
public IHtmlEncodedString RenderTemplate(int contentId, int? altTemplateId = null)
|
||||
{
|
||||
return _componentRenderer.RenderTemplate(contentId, altTemplateId);
|
||||
}
|
||||
public async Task<IHtmlEncodedString> RenderTemplateAsync(int contentId, int? altTemplateId = null)
|
||||
=> await _componentRenderer.RenderTemplateAsync(contentId, altTemplateId);
|
||||
|
||||
#region RenderMacro
|
||||
|
||||
|
||||
Reference in New Issue
Block a user