Skip to content

Instantly share code, notes, and snippets.

@alberto
Created October 16, 2009 15:54
Show Gist options
  • Save alberto/211873 to your computer and use it in GitHub Desktop.
Save alberto/211873 to your computer and use it in GitHub Desktop.
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Web.Mvc;
using System.Web.Routing;
/*
* TODO:
* auto_discovery_link_tag
* cache_asset_timestamps
* cache_asset_timestamps=
* register_javascript_expansion
* register_javascript_include_default
* register_stylesheet_expansion
*/
namespace MvcApplication1 {
public static class HtmlExtensions {
public static string ASSETS_DIR = "~/Content";
public static string JAVASCRIPTS_DIR = ASSETS_DIR + "/js";
public static string STYLESHEETS_DIR = ASSETS_DIR + "/css";
public static string IMAGES_DIR = ASSETS_DIR + "/img";
public static string[] JAVASCRIPT_DEFAULT_SOURCES = new [] { "jquery" };
public static string[] STYLESHEET_DEFAULT_SOURCES = new [] { "" };
public static string ScriptPath(this HtmlHelper html, string src) {
return html.AssetPath(src, JAVASCRIPTS_DIR, "js");
}
public static string Script(this HtmlHelper html) {
return MultipleAssets(html.Script, MergeList(JAVASCRIPT_DEFAULT_SOURCES, "application"));
}
public static string Script(this HtmlHelper html, params string[] sources) {
return MultipleAssets(html.Script, sources);
}
public static string Script(this HtmlHelper html, string src) {
if(string.IsNullOrEmpty(src)) return string.Empty;
var tag = new TagBuilder("script");
tag.MergeAttribute("type", "text/javascript");
tag.MergeAttribute("src", html.ScriptPath(src));
return tag.ToString(TagRenderMode.Normal);
}
public static string StylePath(this HtmlHelper html, string href) {
return html.AssetPath(href, STYLESHEETS_DIR, "css");
}
public static string Style(this HtmlHelper html) {
return MultipleAssets(html.Style, MergeList(STYLESHEET_DEFAULT_SOURCES, "application"));
}
public static string Style(this HtmlHelper html, params string[] styles) {
return MultipleAssets(html.Style, styles);
}
public static string Style(this HtmlHelper html, string href) {
if(string.IsNullOrEmpty(href)) return string.Empty;
var tag = new TagBuilder("link");
tag.MergeAttribute("rel", "stylesheet");
tag.MergeAttribute("type", "text/css");
tag.MergeAttribute("href", html.StylePath(href));
return tag.ToString(TagRenderMode.SelfClosing);
}
public static string ImagePath(this HtmlHelper html, string src) {
return html.AssetPath(src, IMAGES_DIR, "png");
}
public static string Image(this HtmlHelper html, string src) {
return html.Image(src, null);
}
public static string Image(this HtmlHelper html, string src, object htmlAttributes) {
if(string.IsNullOrEmpty(src)) return string.Empty;
var tag = new TagBuilder("img");
tag.MergeAttributes(new RouteValueDictionary(htmlAttributes));
tag.MergeAttribute("src", html.ImagePath(src));
return tag.ToString(TagRenderMode.SelfClosing);
}
private static string Timestamp(this HtmlHelper html, string path) {
var local = html.ViewContext.HttpContext.Server.MapPath(path);
return File.Exists(local) ? File.GetLastWriteTimeUtc(local).ToString("yyyyMMddhhmmssfff") : string.Empty;
}
private static string CombinePath(params string[] paths) {
return paths.Aggregate(Path.Combine).Replace(@"\", "/");
}
private static string AssetPath(this HtmlHelper html, string path, string dir, string ext) {
if(string.IsNullOrEmpty(path)) return string.Empty;
var url = path;
if(string.IsNullOrEmpty(Path.GetExtension(path))) url += "." + ext;
Uri uri;
if(Uri.TryCreate(url, UriKind.Absolute, out uri) && uri.Scheme != "file") return url;
if(!url.StartsWith("~") && !url.StartsWith("/")) url = CombinePath(dir, url);
url += "?" + html.Timestamp(url);
var root = html.ViewContext.HttpContext.Request.ApplicationPath;
if(url.StartsWith("~")) url = CombinePath(root, url.Substring(2));
return url;
}
private static string MultipleAssets(Func<string, string> func, params string[] sources) {
return string.Join("\n", sources.Select(func).ToArray());
}
private static T[] MergeList<T>(IEnumerable<T> first, params T[] others) {
return new List<T>(first).Concat(others).ToArray();
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment