diff --git a/src/Umbraco.Infrastructure/DependencyInjection/UmbracoBuilder.Services.cs b/src/Umbraco.Infrastructure/DependencyInjection/UmbracoBuilder.Services.cs index 915b815033..187b3f0e31 100644 --- a/src/Umbraco.Infrastructure/DependencyInjection/UmbracoBuilder.Services.cs +++ b/src/Umbraco.Infrastructure/DependencyInjection/UmbracoBuilder.Services.cs @@ -116,31 +116,13 @@ namespace Umbraco.Cms.Infrastructure.DependencyInjection private static LocalizedTextServiceFileSources SourcesFactory(IServiceProvider container) { var hostingEnvironment = container.GetRequiredService(); - var globalSettings = container.GetRequiredService>().Value; var mainLangFolder = new DirectoryInfo(hostingEnvironment.MapPathContentRoot(WebPath.Combine(Constants.SystemDirectories.Umbraco, "config", "lang"))); - var appPlugins = new DirectoryInfo(hostingEnvironment.MapPathContentRoot(Constants.SystemDirectories.AppPlugins)); - var configLangFolder = new DirectoryInfo(hostingEnvironment.MapPathContentRoot(WebPath.Combine(Constants.SystemDirectories.Config, "lang"))); - - var pluginLangFolders = appPlugins.Exists == false - ? Enumerable.Empty() - : appPlugins.GetDirectories() - // Check for both Lang & lang to support case sensitive file systems. - .SelectMany(x => x.GetDirectories("?ang", SearchOption.AllDirectories).Where(x => x.Name.InvariantEquals("lang"))) - .SelectMany(x => x.GetFiles("*.xml", SearchOption.TopDirectoryOnly)) - .Select(x => new LocalizedTextServiceSupplementaryFileSource(x, false)); - - // user defined langs that overwrite the default, these should not be used by plugin creators - var userLangFolders = configLangFolder.Exists == false - ? Enumerable.Empty() - : configLangFolder - .GetFiles("*.user.xml", SearchOption.TopDirectoryOnly) - .Select(x => new LocalizedTextServiceSupplementaryFileSource(x, true)); return new LocalizedTextServiceFileSources( container.GetRequiredService>(), container.GetRequiredService(), mainLangFolder, - pluginLangFolders.Concat(userLangFolders)); + container.GetServices()); } } } diff --git a/src/Umbraco.Web.BackOffice/DependencyInjection/UmbracoBuilder.LocalizedText.cs b/src/Umbraco.Web.BackOffice/DependencyInjection/UmbracoBuilder.LocalizedText.cs new file mode 100644 index 0000000000..5deccd14f0 --- /dev/null +++ b/src/Umbraco.Web.BackOffice/DependencyInjection/UmbracoBuilder.LocalizedText.cs @@ -0,0 +1,94 @@ +using System.Collections.Generic; +using System.IO; +using System.Linq; + +using Microsoft.AspNetCore.Hosting; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.FileProviders; + +using Umbraco.Cms.Core.DependencyInjection; +using Umbraco.Cms.Core.Routing; +using Umbraco.Cms.Core.Services.Implement; + +using IHostingEnvironment = Umbraco.Cms.Core.Hosting.IHostingEnvironment; + +namespace Umbraco.Extensions +{ + /// + /// Extension methods for for the Umbraco back office + /// + public static partial class UmbracoBuilderExtensions + { + /// + /// Add the SupplementaryLocalizedTextFilesSources + /// + /// + /// + private static IUmbracoBuilder AddSupplemenataryLocalizedTextFileSources(this IUmbracoBuilder builder) + { + builder.Services.AddTransient(sp => + { + return GetSupplementaryFileSources( + sp.GetRequiredService(), + sp.GetRequiredService()); + }); + + return builder; + } + + + /// + /// Loads the suplimentary localization files from plugins and user config + /// + private static IEnumerable GetSupplementaryFileSources( + IHostingEnvironment hostingEnvironment, + IWebHostEnvironment webHostEnvironment) + { + var webFileProvider = webHostEnvironment.WebRootFileProvider; + var contentFileProvider = webHostEnvironment.ContentRootFileProvider; + + // plugins in /app_plugins + var pluginLangFolders = GetPluginLanguageFileSources(contentFileProvider, Cms.Core.Constants.SystemDirectories.AppPlugins, false); + + // files in /wwwroot/app_plugins (or any virtual location that maps to this) + var razorPluginFolders = GetPluginLanguageFileSources(webFileProvider, Cms.Core.Constants.SystemDirectories.AppPlugins, false); + + // user defined langs that overwrite the default, these should not be used by plugin creators + var configLangFolder = new DirectoryInfo(hostingEnvironment.MapPathContentRoot(WebPath.Combine(Cms.Core.Constants.SystemDirectories.Config, "lang"))); + + var userLangFolders = configLangFolder.Exists == false + ? Enumerable.Empty() + : configLangFolder + .GetFiles("*.user.xml", SearchOption.TopDirectoryOnly) + .Select(x => new LocalizedTextServiceSupplementaryFileSource(x, true)); + + // returned in order where userLangFolders takes precedence over plugins + return pluginLangFolders + .Concat(razorPluginFolders) + .Concat(userLangFolders); + } + + + /// + /// Loads the suplimentary localaization files via the file provider. + /// + /// + /// locates all *.xml files in the lang folder of any sub folder of the one provided. + /// e.g /app_plugins/plugin-name/lang/*.xml + /// + private static IEnumerable GetPluginLanguageFileSources( + IFileProvider fileProvider, string folder, bool overwriteCoreKeys) + { + // locate all the *.xml files inside Lang folders inside folders of the main folder + // e.g. /app_plugins/plugin-name/lang/*.xml + + return fileProvider.GetDirectoryContents(folder) + .Where(x => x.IsDirectory) + .SelectMany(x => fileProvider.GetDirectoryContents(WebPath.Combine(folder, x.Name))) + .Where(x => x.IsDirectory && x.Name.InvariantEquals("lang")) + .Select(x => new DirectoryInfo(x.PhysicalPath)) + .SelectMany(x => x.GetFiles("*.xml", SearchOption.TopDirectoryOnly)) + .Select(x => new LocalizedTextServiceSupplementaryFileSource(x, overwriteCoreKeys)); + } + } +} diff --git a/src/Umbraco.Web.BackOffice/DependencyInjection/UmbracoBuilderExtensions.cs b/src/Umbraco.Web.BackOffice/DependencyInjection/UmbracoBuilderExtensions.cs index 63027a3c9e..df09e9a9b2 100644 --- a/src/Umbraco.Web.BackOffice/DependencyInjection/UmbracoBuilderExtensions.cs +++ b/src/Umbraco.Web.BackOffice/DependencyInjection/UmbracoBuilderExtensions.cs @@ -56,7 +56,8 @@ namespace Umbraco.Extensions .AddLogViewer() .AddExamine() .AddExamineIndexes() - .AddControllersWithAmbiguousConstructors(); + .AddControllersWithAmbiguousConstructors() + .AddSupplemenataryLocalizedTextFileSources(); public static IUmbracoBuilder AddUnattendedInstallInstallCreateUser(this IUmbracoBuilder builder) {