Home » Bundling
Category Archives: Bundling
Bundle CSS and JavaScript Files in Sitecore MVC
The other day I was poking around Sitecore.Forms.Mvc.dll — this assembly ships with Web Forms for Marketers (WFFM), and is used when WFFM is running on Sitecore MVC — and noticed WFFM does some bundling of JavaScript and CSS files:
WFFM uses the above class as an <initialize> pipeline processor. You can see this defined in Sitecore.Forms.Mvc.config:
This got me thinking: why not build my own class to serve as an <initialize> pipeline processor to bundle my CSS and JavaScript files?
As an experiment I whipped up the following class to do just that:
using System.Collections.Generic;
using System.Linq;
using System.Web.Optimization;
using Sitecore.Pipelines;
namespace Sitecore.Sandbox.Forms.Mvc.Pipelines
{
public class RegisterAdditionalFormBundles
{
public RegisterAdditionalFormBundles()
{
CssFiles = new List<string>();
JavaScriptFiles = new List<string>();
}
public void Process(PipelineArgs args)
{
BundleCollection bundles = GetBundleCollection();
if (bundles == null)
{
return;
}
AddBundle(bundles, CreateCssBundle());
AddBundle(bundles, CreateJavaScriptBundle());
}
protected virtual BundleCollection GetBundleCollection()
{
return BundleTable.Bundles;
}
protected virtual Bundle CreateCssBundle()
{
if (!CanBundleAssets(CssVirtualPath, CssFiles))
{
return null;
}
return new StyleBundle(CssVirtualPath).Include(CssFiles.ToArray());
}
protected virtual Bundle CreateJavaScriptBundle()
{
if (!CanBundleAssets(JavaScriptVirtualPath, JavaScriptFiles))
{
return null;
}
return new ScriptBundle(JavaScriptVirtualPath).Include(JavaScriptFiles.ToArray());
}
protected virtual bool CanBundleAssets(string virtualPath, IEnumerable<string> filePaths)
{
return !string.IsNullOrWhiteSpace(virtualPath)
&& filePaths != null
&& filePaths.Any();
}
private static void AddBundle(BundleCollection bundles, Bundle bundle)
{
if(bundle == null)
{
return;
}
bundles.Add(bundle);
}
private string CssVirtualPath { get; set; }
private List<string> CssFiles { get; set; }
private string JavaScriptVirtualPath { get; set; }
private List<string> JavaScriptFiles { get; set; }
}
}
The class above basically takes in a collection of CSS and JavaScript file paths as well as their virtual bundled paths — these are magically populated by Sitecore’s Configuration Factory using values provided by the configuration file shown below — iterates over both collections, and adds them to the BundleTable — the BundleTable is defined in System.Web.Optimization.dll.
I then glued everything together using a patch configuration file:
<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/">
<sitecore>
<pipelines>
<initialize>
<processor patch:after="processor[@type='Sitecore.Forms.Mvc.Pipelines.RegisterFormBundles, Sitecore.Forms.Mvc']"
type="Sitecore.Sandbox.Forms.Mvc.Pipelines.RegisterAdditionalFormBundles, Sitecore.Sandbox">
<CssVirtualPath>~/wffm-bundles/styles.css</CssVirtualPath>
<CssFiles hint="list">
<CssFile>~/css/uniform.aristo.css</CssFile>
</CssFiles>
<JavaScriptVirtualPath>~/wffm-bundles/scripts.js</JavaScriptVirtualPath>
<JavaScriptFiles hint="list">
<JavaScriptFile>~/js/jquery.min.js</JavaScriptFile>
<JavaScriptFile>~/js/jquery.uniform.min.js</JavaScriptFile>
<JavaScriptFile>~/js/bind.uniform.js</JavaScriptFile>
</JavaScriptFiles>
</processor>
</initialize>
</pipelines>
</sitecore>
</configuration>
I’m adding the <initialize> pipeline processor shown above after WFFM’s though theoretically you could add it anywhere within the <initialize> pipeline.
The CSS and JavaScript files defined in the configuration file above are from the Uniform project — this project includes CSS, JavaScript and images to make forms look nice, though I am in no way endorsing this project. I only needed some CSS and JavaScript files to spin up something quickly for testing.
For testing, I built the following View — it uses some helpers to render the <link> and <script> tags for the bundles — and tied it to my Layout in Sitecore:
@using System.Web.Optimization
@using Sitecore.Mvc
@using Sitecore.Mvc.Presentation
<!DOCTYPE html>
<html>
<head>
<title></title>
@Styles.Render("~/wffm-bundles/styles.css")
@Scripts.Render("~/wffm-bundles/scripts.js")
</head>
<body>
@Html.Sitecore().Placeholder("page content")
</body>
</html>
I then built a “Feedback” form in WFFM; mapped it to the “page content” placeholder defined in the View above; published it; and pulled it up in my browser. As you can see the code from the Uniform project styled the form:
For comparison, this is what the form looks like without the <initialize> pipeline processor above:
If you have any thoughts on this, or have alternative ways of bundling CSS and JavaScript files in your Sitecore MVC solutions, please share in a comment.



