Here is how you accomplish what I mention in my post above:
First define ordering types: (to make sure things are bundled in the order you add them!)
Then define your bundle transformer (this will ensure the relative paths in the CSS work right when bundled - your primary issue):
public class StyleRelativePathTransform : IBundleTransform
{
public StyleRelativePathTransform(){}
public void Process(BundleContext context, BundleResponse response)
{
response.Content = String.Empty;
Regex pattern = new Regex(@"url\s*\(\s*([""']?)([^:)]+)\1\s*\)", RegexOptions.IgnoreCase);
// open each of the files
foreach (FileInfo cssFileInfo in response.Files)
{
if (cssFileInfo.Exists)
{
// apply the RegEx to the file (to change relative paths)
string contents = File.ReadAllText(cssFileInfo.FullName);
MatchCollection matches = pattern.Matches(contents);
// Ignore the file if no match
if (matches.Count > 0)
{
string cssFilePath = cssFileInfo.DirectoryName;
string cssVirtualPath = cssFilePath.Replace(context.HttpContext.Request.ServerVariables["APPL_PHYSICAL_PATH"], String.Empty);
foreach (Match match in matches)
{
// this is a path that is relative to the CSS file
string relativeToCSS = match.Groups[2].Value;
// combine the relative path to the cssAbsolute
string absoluteToUrl = Path.GetFullPath(Path.Combine(cssFilePath, relativeToCSS));
// make this server relative
string serverRelativeUrl = "/" + absoluteToUrl.Replace(context.HttpContext.Request.ServerVariables["APPL_PHYSICAL_PATH"], String.Empty).Replace(@"\", "/");
string quote = match.Groups[1].Value;
string replace = String.Format("url({0}{1}{0})", quote, serverRelativeUrl);
contents = contents.Replace(match.Groups[0].Value, replace);
}
}
// copy the result into the response.
response.Content = String.Format("{0}\r\n{1}", response.Content, contents);
}
}
}
}
Then define a Bundle that uses this transform:
Now create the bundles using the new bundler and orderers:
public static void RegisterBundles(BundleCollection bundles)
{
bundles.Add(new StyleImagePathBundle("~/Content/themes/blueopal/css").Include(
"~/Content/site.css",
"~/Content/KendoMvc/kendo.common.min.css",
"~/Content/KendoMvc/kendo.blueopal.min.css",
"~/Content/Custom/BlueOpal/blueopal.custom.css"));
bundles.Add(new ScriptBundle("~/Scripts/js").Include(
"~/Scripts/KendoMvc/jquery.min.js",
"~/Scripts/KendoMvc/kendo.web.min.js",
"~/Scripts/KendoMvc/kendo.all.min.js",
"~/Scripts/jquery.validate.min.js",
"~/Scripts/jquery.unobtrusive-ajax.min.js",
"~/Scripts/jquery.validate.unobtrusive.min.js",
"~/Scripts/KendoMVC/cultures/kendo.culture.en-US.min.js",
"~/Scripts/Site.js"));
bundles.GetBundleFor("~/Content/themes/blueopal/css").Orderer = new AppCssOrderer();
bundles.GetBundleFor("~/Scripts/js").Orderer = new AppJsOrderer();
BundleTable.EnableOptimizations = true;
}
Thats it. I have shown Kendo CSS and your own custom CSS working in default nuget locations with Bundling! caution: don't mix absolute and relative paths in your custom CSS files versus Kendo . css files. Always use relative CSS image paths. The bundle transformer takes care of the rest.
Happy Coding
-JJ