We have had multiple requests for a possible option to minify the generated "on the fly" layout_transformations.css file.
Fulfilling this task requires several steps, which I will describe bellow.
First, it is needed to change the default handler once the Bootstrapper completes the initialization in Global.asax file as follows:
public class Global : System.Web.HttpApplication { protected void Application_Start(object sender, EventArgs e) { Bootstrapper.Initialized += Bootstrapper_Initialized; } void Bootstrapper_Initialized(object sender, Telerik.Sitefinity.Data.ExecutedEventArgs e) { var routesCollection = System.Web.Routing.RouteTable.Routes; var path = "Sitefinity/Public/ResponsiveDesign/layout_transformations.css"; var route = routesCollection .Where(r => r.GetType() == typeof(System.Web.Routing.Route) && (r as System.Web.Routing.Route).Url == path) .FirstOrDefault(); if (route != null) { var index = routesCollection.IndexOf(route); if (index > -1) { var currentRoute = routesCollection[index] as System.Web.Routing.Route; var routeNew = new ResponsiveDesignTransformationRouteHandlerExtended(); currentRoute.RouteHandler = routeNew; } } }By using the above approach we are switching the default ResponsiveDesignTransformationRouteHandler with a custom one:
using System;using System.Linq;using System.Web;using System.Web.Routing;namespace SitefinityWebApp.ExtendResponsiveDesign{ /// <summary> /// Route handler which returns the css styles for the responsive design transformations. /// </summary> public class ResponsiveDesignTransformationRouteHandlerExtended : IRouteHandler { /// <summary>Provides the object that processes the request.</summary> /// <returns>An object that processes the request.</returns> /// <param name="requestContext"> /// An object that encapsulates information about the request. /// </param> public IHttpHandler GetHttpHandler(RequestContext requestContext) { return new ResponsiveDesignTransformationHttpHandlerExtended(); } }}Last, we need to implement the new ResponsiveDesignTransformationHttpHandlerExtended:
using System;using System.Globalization;using System.IO;using System.Linq;using System.Web;using Telerik.Sitefinity.Modules.Pages;using Telerik.Sitefinity.Modules.ResponsiveDesign.Web;namespace SitefinityWebApp.ExtendResponsiveDesign{ public class ResponsiveDesignTransformationHttpHandlerExtended : IHttpHandler { public void ProcessRequest(HttpContext context) { var oldHandler = new ResponsiveDesignTransformationHttpHandler(); var stringWriter = new StringWriter(); var mockContext = new HttpContext( context.Request, new HttpResponse(stringWriter)); oldHandler.ProcessRequest(mockContext); context.Response.Clear(); context.Response.Cache.SetCacheability(HttpCacheability.Public); context.Response.Cache.SetExpires(DateTime.Now.AddHours(1)); context.Response.ContentType = "text/css"; Guid pageDataId = Guid.Empty; CultureInfo culture = null; if (context.Request.QueryString["culture"] != null) { culture = CultureInfo.GetCultureInfo(context.Request.QueryString["culture"]); } if (context.Request.QueryString["pageDataId"] != null) { pageDataId = Guid.Parse(context.Request.QueryString["pageDataId"]); } else if (context.Request.QueryString["pageId"] != null) { Guid pageNodeId = Guid.Parse(context.Request.QueryString["pageId"]); var pageNode = PageManager.GetManager().GetPageNodes().SingleOrDefault(pn => pn.Id == pageNodeId); if (pageNode != null) pageDataId = pageNode.GetPageData(culture).Id; } var css = stringWriter.ToString(); Microsoft.Ajax.Utilities.Minifier myMinifier = new Microsoft.Ajax.Utilities.Minifier(); var minifiedCSS = myMinifier.MinifyStyleSheet(css); context.Response.Write(minifiedCSS); } public bool IsReusable { get { return true; } } }}
In HttpHandlerResponsiveDesignTransformationHttpHandlerExtended is needed to mock the HttpContext and pass it as a parameter to default ResponsiveDesignTransformationHttpHandler and by doing this, we let the default handler to generate the non-minified css for us.
Microsoft Ajax Minifier is a simple JavaScript and CSS minification Library, which can be easily installed in a Visual Studio project, trough Package Manager Console. By passing the non-minified css string as a parameter to MinifyStyleSheet(), we get the minified css, which is now ready to be recorded in the HttpContext response:
var css = stringWriter.ToString(); Microsoft.Ajax.Utilities.Minifier myMinifier = new Microsoft.Ajax.Utilities.Minifier(); var minifiedCSS = myMinifier.MinifyStyleSheet(css); context.Response.Write(minifiedCSS);I will be happy to receive any feedback for a possible optimization of the code provided!