diff --git a/src/Umbraco.Core/Configuration/IConfigManipulator.cs b/src/Umbraco.Core/Configuration/IConfigManipulator.cs index 83ab2c0631..1d9230be44 100644 --- a/src/Umbraco.Core/Configuration/IConfigManipulator.cs +++ b/src/Umbraco.Core/Configuration/IConfigManipulator.cs @@ -6,5 +6,6 @@ namespace Umbraco.Core.Configuration { void RemoveConnectionString(); void SaveConnectionString(string connectionString, string providerName); + void SaveConfigValue(string itemPath, object value); } } diff --git a/src/Umbraco.Core/Configuration/XmlConfigManipulator.cs b/src/Umbraco.Core/Configuration/XmlConfigManipulator.cs index 333f9dc6f9..64271ebff1 100644 --- a/src/Umbraco.Core/Configuration/XmlConfigManipulator.cs +++ b/src/Umbraco.Core/Configuration/XmlConfigManipulator.cs @@ -106,6 +106,11 @@ namespace Umbraco.Core.Configuration _logger.Info("Saved connection string to {ConfigFile}.", fileSource); } + public void SaveConfigValue(string itemPath, object value) + { + throw new NotImplementedException(); + } + private static void AddOrUpdateAttribute(XElement element, string name, string value) { var attribute = element.Attribute(name); diff --git a/src/Umbraco.Core/Constants-Configuration.cs b/src/Umbraco.Core/Constants-Configuration.cs index c45229d918..5124145a56 100644 --- a/src/Umbraco.Core/Constants-Configuration.cs +++ b/src/Umbraco.Core/Constants-Configuration.cs @@ -13,6 +13,8 @@ public const string ConfigPrefix = "Umbraco:CMS:"; public const string ConfigSecurityPrefix = ConfigPrefix+"Security:"; public const string ConfigModelsBuilderPrefix = ConfigPrefix+"ModelsBuilder:"; + public const string ConfigRuntimeMinification = ConfigPrefix+"RuntimeMinification"; + public const string ConfigRuntimeMinificationVersion = ConfigRuntimeMinification+":Version"; } } } diff --git a/src/Umbraco.Infrastructure/Configuration/JsonConfigManipulator.cs b/src/Umbraco.Infrastructure/Configuration/JsonConfigManipulator.cs index 3c78faea37..646df5124d 100644 --- a/src/Umbraco.Infrastructure/Configuration/JsonConfigManipulator.cs +++ b/src/Umbraco.Infrastructure/Configuration/JsonConfigManipulator.cs @@ -1,16 +1,10 @@ using System; -using System.Collections.Generic; using System.IO; -using System.Linq; -using System.Text.Json.Serialization; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Configuration.Json; using Microsoft.Extensions.FileProviders; using Newtonsoft.Json; using Newtonsoft.Json.Linq; -using Umbraco.Core.IO; -using Umbraco.Core.Serialization; - namespace Umbraco.Core.Configuration { public class JsonConfigManipulator : IConfigManipulator @@ -47,6 +41,29 @@ namespace Umbraco.Core.Configuration SaveJson(provider, json); } + public void SaveConfigValue(string key, object value) + { + var provider = GetJsonConfigurationProvider(); + + var json = GetJson(provider); + + JToken token = json; + foreach (var propertyName in key.Split(new[] { ':' })) + { + if (token is null) break; + token = CaseSelectPropertyValues(token, propertyName); + } + + if (token is null) return; + + var writer = new JTokenWriter(); + writer.WriteValue(value); + + token.Replace(writer.Token); + + SaveJson(provider, json); + + } private JToken GetConnectionItem(string connectionString, string providerName) { diff --git a/src/Umbraco.Web.BackOffice/AspNetCore/UmbracoCoreServiceCollectionExtensions.cs b/src/Umbraco.Web.BackOffice/AspNetCore/UmbracoCoreServiceCollectionExtensions.cs index c06af6f9f1..ad29e72707 100644 --- a/src/Umbraco.Web.BackOffice/AspNetCore/UmbracoCoreServiceCollectionExtensions.cs +++ b/src/Umbraco.Web.BackOffice/AspNetCore/UmbracoCoreServiceCollectionExtensions.cs @@ -10,6 +10,7 @@ using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Smidge; using Smidge.Nuglify; +using Smidge.Options; using Umbraco.Composing; using Umbraco.Configuration; using Umbraco.Core; @@ -166,7 +167,7 @@ namespace Umbraco.Web.BackOffice.AspNetCore public static IServiceCollection AddUmbracoRuntimeMinifier(this IServiceCollection services, IConfiguration configuration) { - services.AddSmidge(configuration.GetSection(Constants.Configuration.ConfigPrefix+"RuntimeMinification")); + services.AddSmidge(configuration.GetSection(Constants.Configuration.ConfigRuntimeMinification)); services.AddSmidgeNuglify(); return services; diff --git a/src/Umbraco.Web.BackOffice/Controllers/BackOfficeController.cs b/src/Umbraco.Web.BackOffice/Controllers/BackOfficeController.cs index 7045674d33..c8e0d71f80 100644 --- a/src/Umbraco.Web.BackOffice/Controllers/BackOfficeController.cs +++ b/src/Umbraco.Web.BackOffice/Controllers/BackOfficeController.cs @@ -31,6 +31,13 @@ namespace Umbraco.Web.BackOffice.Controllers return new JavaScriptResult(result); } + + public IActionResult Reset() + { + _runtimeMinifier.Reset(); + + return Content("OK"); + } } public class JavaScriptResult : ContentResult diff --git a/src/Umbraco.Web.BackOffice/Smidge/SmidgeRuntimeMinifier.cs b/src/Umbraco.Web.BackOffice/Smidge/SmidgeRuntimeMinifier.cs index 305caccd23..313143a01f 100644 --- a/src/Umbraco.Web.BackOffice/Smidge/SmidgeRuntimeMinifier.cs +++ b/src/Umbraco.Web.BackOffice/Smidge/SmidgeRuntimeMinifier.cs @@ -4,7 +4,6 @@ using System.Linq; using System.Threading.Tasks; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http.Extensions; -using Microsoft.Extensions.Configuration; using Smidge; using Smidge.CompositeFiles; using Smidge.FileProcessors; @@ -30,6 +29,7 @@ namespace Umbraco.Web.BackOffice.Smidge private readonly IIOHelper _ioHelper; private readonly IHostingEnvironment _hostingEnvironment; private readonly ISmidgeConfig _smidgeConfig; + private readonly IConfigManipulator _configManipulator; private readonly IManifestParser _manifestParser; private readonly PreProcessPipelineFactory _preProcessPipelineFactory; private readonly PropertyEditorCollection _propertyEditorCollection; @@ -47,7 +47,8 @@ namespace Umbraco.Web.BackOffice.Smidge IGlobalSettings globalSettings, IIOHelper ioHelper, IHostingEnvironment hostingEnvironment, - ISmidgeConfig smidgeConfig) + ISmidgeConfig smidgeConfig, + IConfigManipulator configManipulator) { _smidge = smidge; _preProcessPipelineFactory = preProcessPipelineFactory; @@ -58,6 +59,7 @@ namespace Umbraco.Web.BackOffice.Smidge _ioHelper = ioHelper; _hostingEnvironment = hostingEnvironment; _smidgeConfig = smidgeConfig; + _configManipulator = configManipulator; } private PreProcessPipeline JsPipeline => _jsPipeline ??= _preProcessPipelineFactory.Create(typeof(JsMinifier)); @@ -110,9 +112,18 @@ namespace Umbraco.Web.BackOffice.Smidge } } + + /// + /// + /// + /// + /// Smidge uses the version number as cache buster (configurable). + /// We therefore can reset, by updating the version number in config + /// public void Reset() { - // TODO: Need to figure out how to delete temp directories to make sure we get fresh caches + var version = DateTime.UtcNow.Ticks.ToString(); + _configManipulator.SaveConfigValue(Constants.Configuration.ConfigRuntimeMinificationVersion, version.ToString()); } public async Task GetScriptForBackOfficeAsync() diff --git a/src/Umbraco.Web.UI.NetCore/Startup.cs b/src/Umbraco.Web.UI.NetCore/Startup.cs index 7d5dd98351..2bf9e82a55 100644 --- a/src/Umbraco.Web.UI.NetCore/Startup.cs +++ b/src/Umbraco.Web.UI.NetCore/Startup.cs @@ -1,14 +1,10 @@ using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Http; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; -using Smidge; using Umbraco.Web.BackOffice.AspNetCore; using Umbraco.Web.Common.AspNetCore; using Umbraco.Web.Website.AspNetCore; diff --git a/src/Umbraco.Web.UI.NetCore/appsettings.json b/src/Umbraco.Web.UI.NetCore/appsettings.json index f20a0f4962..0219ae2f86 100644 --- a/src/Umbraco.Web.UI.NetCore/appsettings.json +++ b/src/Umbraco.Web.UI.NetCore/appsettings.json @@ -2,8 +2,7 @@ "ConnectionStrings": { "umbracoDbDSN": "" }, - - "Logging": { + "Logging": { "LogLevel": { "Default": "Trace", "Microsoft": "Trace", @@ -13,13 +12,13 @@ "AllowedHosts": "*", "Umbraco": { "CMS": { - "Hosting": { - "Debug" : false - }, - "RuntimeMinification": { - "dataFolder" : "App_Data/TEMP/Smidge", - "version" : "1" - }, + "Hosting": { + "Debug": false + }, + "RuntimeMinification": { + "dataFolder": "App_Data/TEMP/Smidge", + "version": "637212411755687059" + }, "Imaging": { "Resize": { "MaxWidth": 5000, @@ -80,18 +79,44 @@ "RequestHandler": { "AddTrailingSlash": true, "CharCollection": [ - {"Char": " ", "Replacement": "-"}, - {"Char": "\"", "Replacement": ""}, - {"Char": "'", "Replacement": ""}, - {"Char": "%", "Replacement": ""}, - {"Char": ".", "Replacement": ""}, - {"Char": ";", "Replacement": ""}, - {"Char": "/", "Replacement": ""}, - {"Char": "\\", "Replacement": ""}, - {"Char": ":", "Replacement": ""} - + { + "Char": " ", + "Replacement": "-" + }, + { + "Char": "\"", + "Replacement": "" + }, + { + "Char": "'", + "Replacement": "" + }, + { + "Char": "%", + "Replacement": "" + }, + { + "Char": ".", + "Replacement": "" + }, + { + "Char": ";", + "Replacement": "" + }, + { + "Char": "/", + "Replacement": "" + }, + { + "Char": "\\", + "Replacement": "" + }, + { + "Char": ":", + "Replacement": "" + } ] } } } -} +} \ No newline at end of file diff --git a/src/Umbraco.Web.UI/Umbraco/Views/Default.cshtml b/src/Umbraco.Web.UI/Umbraco/Views/Default.cshtml index a048569760..16999d6a18 100644 --- a/src/Umbraco.Web.UI/Umbraco/Views/Default.cshtml +++ b/src/Umbraco.Web.UI/Umbraco/Views/Default.cshtml @@ -18,12 +18,7 @@ } var runtimeMinifier = Current.RuntimeMinifier; - runtimeMinifier.RequiresCss("Umbraco", "assets/css/umbraco.css", "lib/bootstrap-social/bootstrap-social.css", "assets/css/umbraco.css", "lib/font-awesome/css/font-awesome.min.css"); - - // Html - // .RequiresCss("assets/css/umbraco.css", "Umbraco") - // .RequiresCss("lib/bootstrap-social/bootstrap-social.css", "Umbraco") - // .RequiresCss("lib/font-awesome/css/font-awesome.min.css", "Umbraco"); + runtimeMinifier.RequiresCss("Umbraco", "lib/bootstrap-social/bootstrap-social.css", "assets/css/umbraco.css", "lib/font-awesome/css/font-awesome.min.css"); }