Yesterday, I introduced Zippy. Today, I gave Zippy some serious wings. After taking a look at Justin Etheredge’s Project Formerly Named Bundler (i.e. PFNB), I was inspired to add some Bundler-like functionality to Zippy. As I said in my last post, Zippy is definitely not a full-fledged, complete, fly-off-the-shelf bundling framework like PFNB, but it’s definitely a tool that could be used by anyone who might need a little more control over their, uh, bundling. Truly.
You can download the updated Zippy here, and start fiddling.
Let me show you how you can use Zippy. Like in my last post, add the Fat.Zippy.MVC dll to your project. Add the Fat.Mvc.Zippy.Helpers.Html namespace to your web.config file. Once you’ve done that, create a controller, ZipController that inherits from the abstract class, ZippyController. Now you’ve harnessed the powers of the Zippy birdy.
Here’s an example implementation:
using System;
using System.IO;
using System.Web;
using System.Web.Mvc;
using Fat.Mvc.Zippy;
namespace Fat.MVC.ZippyWeb.Controllers
{
public class ZipController : ZippyController
{
protected override string CreateCssPathFromKey(string key)
{
//I can override this method to place my mashed, minified
//css files in an appropriate project folder.
//The "key" here is an MD5 key generated to specify a unique set of files.
//So, assuming the following directory exists, I could create my path like so:
string path = Path.Combine(@"/Public/Styles/ZStore/", key + ".css");
return Server.MapPath(path);
}
protected override string CreateJsPathFromKey(string key)
{
//I can override this method to place my mashed, minified
//js files in an appropriate project folder.
//The "key" here is an MD5 key generated to specify a unique set of files.
//So, assuming the following directory exists, I could create my path like so:
string path = Path.Combine(@"/Public/Scripts/ZStore/", key + ".js");
return Server.MapPath(path);
}
protected override string MinifyCss(string path, string css)
{
//The default minifier is the YUI Compressor
//But you can override it with your own here.
return base.MinifyCss(path, css);
}
protected override string MinifyJs(string path, string js)
{
//The default minifier is the YUI Compressor
//But you can override it with your own here.
return base.MinifyJs(path, js);
}
protected override void SetupDefaultOutputCaching()
{
//Setup output cache, e.g.:
Response.Cache.AppendCacheExtension("must-revalidate, proxy-revalidate");
base.SetupDefaultOutputCaching();
}
protected override void ValidatePath(string path)
{
//validate the path.
//throw an error if something fishy happens...
if (path.Contains(".config")) throw new Exception("Whoa there...");
base.ValidatePath(path);
}
protected override void ValidateCssPath(string path)
{
//validate the css path
//same as validate path, but applies only to css files
//passed to the Style() method
base.ValidateCssPath(path);
}
protected override void ValidateJsPath(string path)
{
//validate the js path
//same as validate path, but applies only to js files
//passed to the Javascript() method
base.ValidateJsPath(path);
}
}
}
With this Controller in our project, we can start having fun.
For one, we can mash/minify some scripts or stylesheets we specifiy in our Master Page with scripts or stylesheets that we specify in our ViewPage. For example,
in your MasterPage, you could write:
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title><asp:ContentPlaceHolder ID="ContentPlaceHolder1" runat="server" /></title>
<% Html.Style("/Content/Site.css"); %>
<% Html.Style("/Content/Siteddd.less"); %>
<% Html.Script("/Scripts/jquery-1.3.2.min.js"); %>
<!-- Conditionally add a script-->
<% if(conditionalToTest) Html.Script("/Scripts/jquery.validate.min.js"); %>
<asp:ContentPlaceHolder ID="HeadContent" runat="server" />
<%= Html.CompressCss(Url) %>
<%= Html.CompressJs(Url) %>
</head>
<body>
<asp:ContentPlaceHolder ID="MainContent" runat="server" />
</body>
</html>
And in your ViewPage:
<asp:Content ID="indexTitle" ContentPlaceHolderID="TitleContent" runat="server">
.title...
</asp:Content>
<asp:Content ID="headContent" ContentPlaceHolderID="HeadContent" runat="server">
<% Html.Style("/Public/Styles/PageStyle.css"); %>
<% Html.Script("/Scripts/MicrosoftAjax.js"); %>
</asp:Content>
<asp:Content ID="indexContent" ContentPlaceHolderID="MainContent" runat="server">
...page content...
</asp:Content>
And your page renders a single cached, mashed, minified stylesheet file and a single cached, mashed, minified javascript file. Here are the YSlow results:
Both of these files are cached on the server. Also, the following files are created in the folders you specified in your ZipController:
Like bundler, if you make any changes to the files that the mashed file is dependent upon, the mashed file is automatically updated on the next retrieval attempt.
That’s enough Zippiness for me. Hope you have fun with it; I sure did.
Read More
You can leave a response, or trackback from your own site.
9 Responses to “More “Ugh” Zippy Cache/Mash MVC Controller”
Leave a Reply





Have you tried the website using IE8?
I am having a “weird” (pun intended) issue with a web page that uses jQuery UI tabs, jqGrid (on two seperate tabs), and the jQuery ThemeSwitcher. I made all the changes necessary to compress the images and stylesheets, which works perfect in FireFox, but fails to render the output via IE8. It is running via ASP.NET MVC from within a VS2010 Ult. I have attempted to debug IE8 with the developer tools, but have come up with nadda. There are no scripting errors, etc..
Thanks for your coding insight!
sinnerFA
Update, everything renders properly when using “compatibility view” in IE8…
Hey sinner, I’m not sure what you mean by “fails to render the output via IE8.” Are the images not showing up? Are the styles not being applied? I’d love to help; just need a little more detail from ya.
Cheers,
E
Yep, it appears that everything, the CSS’s, Images, and JScripts fail to “load” when using your code, that is unless I turn on “compatibility view” in IE8. I was just inquiring whether you have seen this before. It appears as though IE8 is unable to render the output strings for the compressed items.
-sinnerFA
Damn it all to hell, maybe? It works in IE8 for me, in compat or non-compat mode…? My scripts, images, and stylesheets all play nicely.
I’d love to get to the bottom of this, but I can’t replicate the issue. Any way we can talk over e-mail (I sent you an e-mail earlier this morning), and you can help me sort this madness out?
C,e
[...] a nice T4 template for mashing and minifying DotLess, Css, and Js files. Today, in the spirit of my Zippy Series, I’ve enhanced (or deprecated [on?]) Wayne’s creation with a couple of new features, [...]
[...] post is another “milestone” in the arduous journey of the Zippy bird. It’s an ugly bird, but the process of “making fluff out of feathers” has always [...]
Hi,
obviously the controller won’t work wih mvc areas, does it?
I always receve 404 for the combines js and/or vss file.
Thanks
Hey Sinner,
Check out the Html.Style and Html.Script methods in the source. You should be able to tweak them for use with mvc areas.
Cheers,
Evan