While building out the MVC Storefront, I find that I’m creating quite a large “Helper” library for doing common things, like registering script tags and CSS sheets. I decided to tighten this up a bit and created a helper I kind of like.
The Need
I want to try and reduce repetition as much as possible throughout the application, and to that end I put as much logic as I can into “Helpers” so I can reduce the <%…%> as much as possible on the page. ANY logic whatsoever makes the ViewPage harder to read, and my general rule of thumb is that if I see an “If” anywhere, it’s ripe for a Helper. I know this rule doesn’t always apply… but it’s a good place to start.
The same logic applied to most UI elements – things like style sheets (if you have more than one), common images (like Product images), and script tags.
The Setup
I keep all my script tags in a directory called “scripts”. Right now there are only 3 files in there:
- MicrosoftAjax.debug.js
- MicrosoftAjax.js
- MicrosoftAjaxMVC.js (this is a file I created)
Normally I would just make a simple function to return the script tags – something like:
public static string RegisterJS(this System.Web.Mvc.HtmlHelper helper, string scriptLib) { //get the directory where the scripts are string scriptRoot = VirtualPathUtility.ToAbsolute("~/Scripts"); string scriptFormat="<script src=\"{0}/{1}\" type=\"text/javascript\"></script>\r\n"; return string.Format(scriptFormat,scriptRoot,scriptLib); }
That’s helpful, but I can do better
. I don’t like “magic strings” and even though it’s the name of a file – I’d rather use something else here. Also, if I have to use “Html.RegisterJS…” every line – I haven’t really saved much.
The Code
To start, I’m going to create an Enum that I know will grow (you can put this anywhere – I use a file called “Enums” and am putting it in the Helpers folder), and I’ll reference the names of my script libraries:
/// <summary> /// Enums which describe script libraries /// </summary> public enum ScriptLibrary { All, Default, MicrosoftAjax, MicrosoftAjaxMVC, }
Next, I buff out the RegisterJS function a bit…
/// <summary> /// A helper for registering script tags on an MVC View page. /// </summary> public static string RegisterJS(this System.Web.Mvc.HtmlHelper helper, ScriptLibrary scriptLib) { //get the directory where the scripts are string scriptRoot = VirtualPathUtility.ToAbsolute("~/Scripts"); string scriptFormat="<script src=\"{0}/{1}\" type=\"text/javascript\"></script>\r\n"; string scriptLibFile=""; string result = ""; System.Text.StringBuilder sb = new System.Text.StringBuilder(); //all of the script tags if (scriptLib == ScriptLibrary.All) { string[] scripts = Enum.GetNames(typeof(ScriptLibrary)); foreach (string script in scripts) { scriptLibFile = script + ".js"; sb.AppendFormat(scriptFormat, scriptRoot,scriptLibFile); } result = sb.ToString(); //just the defaults please } else if (scriptLib == ScriptLibrary.Default) { sb.AppendFormat(scriptFormat, scriptRoot,"MicrosoftAjax.js"); sb.AppendFormat(scriptFormat, scriptRoot,"MicrosoftAjaxMVC.js"); result = sb.ToString(); } else { //just the ones asked for scriptLibFile=Enum.GetName(typeof(ScriptLibrary),scriptLib)+".js"; result = string.Format(scriptFormat, scriptRoot,scriptLibFile); } return result; }
And there you are. Now I can reference my script libraries with one line, and I don’t have to have a bulk of <script> tags everywhere:
<%=Html.RegisterJS(ScriptLibrary.Default) %>
I know the code above can be tightened some
and I’d love to hear your ideas. I’m not sure how usable the “All” selection is – but I wanted to include so you could get the idea here… sort of a “thematic” way to register your scripts.
