diff --git a/Lombiq.HelpfulLibraries.OrchardCore/Contents/CommonStereotypes.cs b/Lombiq.HelpfulLibraries.OrchardCore/Contents/CommonStereotypes.cs index 56f0f6d3..3d1c3074 100644 --- a/Lombiq.HelpfulLibraries.OrchardCore/Contents/CommonStereotypes.cs +++ b/Lombiq.HelpfulLibraries.OrchardCore/Contents/CommonStereotypes.cs @@ -8,4 +8,5 @@ public static class CommonStereotypes public const string Content = nameof(Content); public const string MenuItem = nameof(MenuItem); public const string Widget = nameof(Widget); + public const string CustomSettings = nameof(CustomSettings); } diff --git a/Lombiq.HelpfulLibraries.OrchardCore/Contents/ContentOrchardHelperExtensions.cs b/Lombiq.HelpfulLibraries.OrchardCore/Contents/ContentOrchardHelperExtensions.cs index e0ded58f..cfe0057e 100644 --- a/Lombiq.HelpfulLibraries.OrchardCore/Contents/ContentOrchardHelperExtensions.cs +++ b/Lombiq.HelpfulLibraries.OrchardCore/Contents/ContentOrchardHelperExtensions.cs @@ -87,11 +87,15 @@ public static string Action( where TController : ControllerBase => orchardHelper.HttpContext.Action(taskActionExpression.StripResult(), additionalArguments); - private static IUrlHelper GetUrlHelper(this IOrchardHelper orchardHelper) + /// + /// Constructs a new instance using the current . + /// + public static IUrlHelper GetUrlHelper(this IOrchardHelper orchardHelper) { var serviceProvider = orchardHelper.HttpContext.RequestServices; var urlHelperFactory = serviceProvider.GetService(); - var actionContext = serviceProvider.GetService()?.ActionContext; + var actionContext = serviceProvider.GetService()?.ActionContext ?? + throw new InvalidOperationException("Couldn't access the action context."); return urlHelperFactory.GetUrlHelper(actionContext); } diff --git a/Lombiq.HelpfulLibraries.OrchardCore/Contents/ContentTypeDefinitionBuilderExtensions.cs b/Lombiq.HelpfulLibraries.OrchardCore/Contents/ContentTypeDefinitionBuilderExtensions.cs index 94e70c0e..512def58 100644 --- a/Lombiq.HelpfulLibraries.OrchardCore/Contents/ContentTypeDefinitionBuilderExtensions.cs +++ b/Lombiq.HelpfulLibraries.OrchardCore/Contents/ContentTypeDefinitionBuilderExtensions.cs @@ -1,3 +1,4 @@ +using Lombiq.HelpfulLibraries.OrchardCore.Contents; using OrchardCore.Autoroute.Models; using OrchardCore.ContentManagement.Metadata.Settings; using OrchardCore.Title.Models; @@ -66,4 +67,18 @@ public static ContentTypeDefinitionBuilder WithContentTypeAutoroute( AllowUpdatePath = true, ManageContainedItemRoutes = true, })); + + /// + /// Sets the type's to . + /// accordingly. + /// + public static ContentTypeDefinitionBuilder AsWidget(this ContentTypeDefinitionBuilder builder) => + builder.Stereotype(CommonStereotypes.Widget); + + /// + /// Sets the type's to . + /// accordingly. + /// + public static ContentTypeDefinitionBuilder AsCustomSettings(this ContentTypeDefinitionBuilder builder) => + builder.Stereotype(CommonStereotypes.CustomSettings); } diff --git a/Lombiq.HelpfulLibraries.OrchardCore/Middlewares/CookieCultureScopeMiddleware.cs b/Lombiq.HelpfulLibraries.OrchardCore/Middlewares/CookieCultureScopeMiddleware.cs new file mode 100644 index 00000000..8a8c1878 --- /dev/null +++ b/Lombiq.HelpfulLibraries.OrchardCore/Middlewares/CookieCultureScopeMiddleware.cs @@ -0,0 +1,61 @@ +using Microsoft.AspNetCore.Http; +using Microsoft.Extensions.DependencyInjection; +using OrchardCore.Localization; +using System.Globalization; +using System.Threading.Tasks; + +namespace Lombiq.HelpfulLibraries.OrchardCore.Middlewares; + +/// +/// A middleware that looks for the "culture" query string argument or cookie and uses it to initialize a . +/// +public class CookieCultureScopeMiddleware +{ + public const string CultureKeyName = "culture"; + + private readonly RequestDelegate _next; + + public CookieCultureScopeMiddleware(RequestDelegate next) => _next = next; + + public async Task InvokeAsync(HttpContext context) + { + if (!TryGetCultureInfo(context, out var culture)) + { + culture = await context + .RequestServices + .GetRequiredService() + .GetDefaultCultureAsync() ?? "en-US"; + } + + using var scope = CultureScope.Create(culture, culture, ignoreSystemSettings: true); + context.SetCookieForever(CultureKeyName, culture); + + await _next(context); + } + + private static bool TryGetCultureInfo(HttpContext context, out string culture) + { + if (context.Request.Query.TryGetValue(CultureKeyName, out var queryCulture)) + { + culture = queryCulture[0]; + } + else + { + context.Request.Cookies.TryGetValue(CultureKeyName, out culture); + } + + if (string.IsNullOrWhiteSpace(culture)) return false; + + try + { + culture = new CultureInfo(culture).Name; + return true; + } + catch + { + culture = null; + return false; + } + } +}