Skip to main content

Devops

Bundling with Sitecore MVC

Bundling@1x.jpg
Sitecore

Sitecore

Sitecore’s MVC support is (as of Sitecore 6.6 update 5) based on the MVC3 implementation by Microsoft.

One really nice feature of Microsoft’s MVC4 implementation is the concept of bundling. Bundling allows a developer to aggregate a collection of either CSS files or Javascript files into a single “item” that can be easily manipulated and used within a Razor view.

It includes some excellent enhancements:

 

 

  1. Reduces the number of Http requests made by the browser by aggregating the CSS or JS files into a single “virtual” file
  2. Automatic minimization of CSS and JS files
  3. Virtual Pathing (allows you to change the path used to access the aggregated group of files)
  4. Simplified syntax to include possibly several files from within a Razor view
  5. for more information on bundling, please see MVC4 Bundling and Minification

You can use these features within Sitecore’s MVC implementation as well. The following instructions assume you have a Sitecore 6.6 update 2 (or later) installation that you are working with, and that MVC has already been enabled.

Step 1 – Installing the needed assemblies

In order to use Bundling, you must install the necessary assemblies provided by Microsoft.  There are actually 2 components that are required – Microsoft.System.Optimization and WebGrease.  Both of these can be installed via nuget – the package name is Microsoft ASP.NET Web Optimization Framework

nuget installation screenshot

Make sure you select the correct item from nuget

Once you have installed them, the references to System.Web.Optimization and WebGrease will be included as references in your solution.

Step 2 – Creating Bundles in the Sitecore Pipeline

Normally, bundling makes use of the Global.asax / Application_Start method provided by ASP.NET.  In Sitecore, it’s best to avoid using this – especially if you are working on a Multi-site instance of Sitecore that could be shared with several other projects.

Instead of using Global.asax, you can inject a simple pipeline method into the <Initialize> pipeline.

using System.Web.Optimization;
using Sitecore;
using Sitecore.Pipelines;

namespace MyProject.Web.Pipelines
{
public class RegisterPlatformBundles
{
[UsedImplicitly]
public virtual void Process(PipelineArgs args)
{
RegisterBundles( BundleTable.Bundles );
}

private void RegisterBundles(BundleCollection bundles)
{
bundles.Add(new ScriptBundle(&quot;~/bundles/jquery&quot;).Include(
&quot;~/assets/Platform/Scripts/jquery-{version}.js&quot;));

bundles.Add(new ScriptBundle(&quot;~/bundles/jqueryui&quot;).Include(
&quot;~/assets/Platform/Scripts/jquery-ui-{version}.js&quot;));

bundles.Add(new ScriptBundle(&quot;~/bundles/jqueryval&quot;).Include(
&quot;~/assets/Platform/Scripts/jquery.unobtrusive<em>&quot;,
&quot;~/assets/Platform/Scripts/jquery.validate</em>&quot;));

// Use the development version of Modernizr to develop with and learn from. Then, when you're
// ready for production, use the build tool at http://modernizr.com to pick only the tests you need.
bundles.Add(new ScriptBundle(&quot;~/bundles/modernizr&quot;).Include(
&quot;~/assets/Platform/Scripts/modernizr-*&quot;));
}

}
}

With the above class added to your project, you can inject this processor into the initialize pipeline by adding the following Sitecore configuration patch file into your App_Config/Include folder. Make sure to change the class and assembly name below from MyProject.Pipelines.RegisterMyBundles, MyProject to the actual name of your class and assembly.


&amp;lt;configuration xmlns:patch="http://www.sitecore.net/xmlconfig/"&amp;gt;
&amp;lt;sitecore&amp;gt;
&amp;lt;pipelines&amp;gt;
&amp;lt;initialize&amp;gt;
&amp;lt;processor patch:before="processor[@type='Sitecore.Mvc.Pipelines.Loader.InitializeGlobalFilters, Sitecore.Mvc']"
type="MyProject.Web.Pipelines.RegisterPlatformBundles, MyProject" /&amp;gt;
&amp;lt;/initialize&amp;gt;
&amp;lt;/pipelines&amp;gt;
&amp;lt;/sitecore&amp;gt;
&amp;lt;/configuration&amp;gt;

Step 3 – Using the Bundle in a Razor View

The above code creates a bundle at the virtual path ~/assets/Platform/bundles/jquery – in order to add that bundle to a Razor view there are 2 steps.  First, add the namspace System.Web.Optimization to the Web.config file located in your Views folder (or whatever you call the folder that contains your Razor views).


&amp;lt;system.web.webPages.razor&amp;gt;
&amp;lt;host factoryType="System.Web.Mvc.MvcWebRazorHostFactory, System.Web.Mvc, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" /&amp;gt;
&amp;lt;pages pageBaseType="System.Web.Mvc.WebViewPage"&amp;gt;
&amp;lt;namespaces&amp;gt;
&amp;lt;add namespace="System.Web.Mvc" /&amp;gt;
&amp;lt;add namespace="System.Web.Mvc.Ajax" /&amp;gt;
&amp;lt;add namespace="System.Web.Mvc.Html" /&amp;gt;
&amp;lt;add namespace="System.Web.Routing" /&amp;gt;
&amp;lt;add namespace="System.Web.Optimization" /&amp;gt;
&amp;lt;/namespaces&amp;gt;
&amp;lt;/pages&amp;gt;
&amp;lt;/system.web.webPages.razor&amp;gt;

This will allow you to use the HtmlHelpers located within the assembly within your .cshtml files.

Within your .cshtml layout file, you can now add blocks such as


@using Sitecore.Mvc
@{
Layout = null;
}

&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html&amp;gt;
&amp;lt;head&amp;gt;
&amp;lt;title&amp;gt;test page&amp;lt;/title&amp;gt;
@Scripts.Render("~//bundles/modernizr")
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
&amp;lt;div&amp;gt;
@Html.Sitecore().Placeholder("content body")
&amp;lt;/div&amp;gt;
@Scripts.Render("~/bundles/jquery")
@Scripts.Render("~//bundles/jqueryui")
&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;

Next, you need to add this to your web.config – there’s a lot of chatter around this because it shouldn’t be needed, but

&amp;lt;system.webServer&amp;gt;
&amp;lt;modules runAllManagedModulesForAllRequests="false"&amp;gt;
&amp;lt;remove name="BundleModule"/&amp;gt; &amp;lt;add type="System.Web.Optimization.BundleModule" name="BundleModule"/&amp;gt;
...

Finally, I patched the IgnoreUrlPrefixes setting in sitecore to add the /bundles path

&amp;lt;configuration xmlns:patch="http://www.sitecore.net/xmlconfig/"&amp;gt;
&amp;lt;sitecore&amp;gt;
&amp;lt;settings&amp;gt;
&amp;lt;setting name="IgnoreUrlPrefixes" value="(all other sitecore paths here)|/bundles"/&amp;gt;
&amp;lt;/settings&amp;gt;
&amp;lt;/sitecore&amp;gt;
&amp;lt;/configuration&amp;gt;

Thoughts on “Bundling with Sitecore MVC”

  1. Thanks for this post Brian – it worked like a charm. For those using Sitecore 7.2, you can skip the web.config modifications.

  2. Pingback: Bundling with sitecore MVC - dex page

  3. We have a website running on Sitecore 7.1 (rev. 140324), implementing sitecore MVC 4.Bundling and minification is used as there are many css and less files. But sometimes website lose all the styling on pages and there appears nothing in the bundling parameter (?v=), issue appearing intermittently.
    There is no exception logged in the log files when this issue appears. The issue goes off when we recycle the app pool or restart the website.
    Can someone please let us know why the bundling is not working?
    It was first thought that this was due to performance, however on one occasion this occurred with very little load on the server.
    The link to the CSS bundle in the page source when working correctly looks like this:

    When the error happens, the link looks like this (no value for the “v” parameter).

    If anyone have an idea what can cause the issue please share. Thanks for your time!

  4. We don’t typically add items into the media library that would be bundled.
    I have seen many implementations that include items like .css or .js files into the media library, but we typically feel that items under the governance of the development team should not be managed as content.

  5. Pingback: Bundling with Sitecore 6.5 to 8.2 + versions of Sitecore | Balaji Blog

  6. I was momentarily confused on step 3 where you mention adding “this” to the web.config. It wasn’t immediately clear that I needed to figure out modules needed its closing mark up. Perhaps this can be include in the example instead of the “…”?

    Kind Regards

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Brian Beckham

As a Sitecore MVP, Brian spends most of his time consulting and architecting software solutions for enterprise-level Sitecore projects.

More from this Author

Categories
Follow Us