Created

Embed URL

HTTPS clone URL

SSH clone URL

You can clone with HTTPS or SSH.

Download Gist
View HtmlHelperExtensions.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124
public static class HtmlHelperExtensions
{
private static readonly char Separator = '/';
private static readonly string TemplateFolder = HttpContext.Current.Server.MapPath("~/App/templates");
private static readonly IViewEngine ViewEngine = new HandlebarsRazorViewEngine();
 
public static MvcHtmlString RenderEmber(this HtmlHelper helper, string path = "", bool noTemplateName = false)
{
if (HttpRuntime.Cache[path] == null)
{
var builder = new StringBuilder();
 
string absolutePath;
string templateName = "";
if (string.IsNullOrEmpty(path))
{
absolutePath = TemplateFolder;
}
else
{
templateName = path.Replace("\\", Separator.ToString());
absolutePath = Path.Combine(TemplateFolder, path);
}
 
if (File.Exists(absolutePath))
{
int fileExtensionPosition = templateName.LastIndexOf('.');
if (fileExtensionPosition > 0)
{
templateName = templateName.Substring(0, fileExtensionPosition);
}
 
AppendFileTemplate(builder, helper, templateName, null, null, new FileInfo(absolutePath), noTemplateName);
 
HttpRuntime.Cache.Insert(path, new MvcHtmlString(builder.ToString()), new CacheDependency(absolutePath));
}
else
{
if (Directory.Exists(absolutePath))
{
if (templateName.Length > 0 && templateName[templateName.Length - 1] != Separator)
{
templateName += Separator;
}
List<string> dependencyList = new List<string>();
 
AppendDirectoryTemplates(builder, helper, templateName, "", new DirectoryInfo(absolutePath), dependencyList);
 
var result = new MvcHtmlString(builder.ToString());
HttpRuntime.Cache.Insert(path, result, new CacheDependency(dependencyList.ToArray()));
}
else
{
return new MvcHtmlString(""); //nothing is found, return empty string and do not cache
}
}
}
 
return HttpRuntime.Cache[path] as MvcHtmlString;
}
 
private static void AppendDirectoryTemplates(StringBuilder builder, HtmlHelper helper, string templateName, string relativeDirName, DirectoryInfo rootDirectory, List<string> dependencyList)
{
dependencyList.Add(rootDirectory.FullName);
 
var newSubRelativeDirName = relativeDirName;
if (!string.IsNullOrEmpty(newSubRelativeDirName))
{
newSubRelativeDirName = newSubRelativeDirName + Separator;
}
 
foreach (DirectoryInfo subDir in rootDirectory.GetDirectories())
{
AppendDirectoryTemplates(builder, helper, templateName, newSubRelativeDirName + subDir.Name, subDir, dependencyList);
}
 
foreach (FileInfo templateFile in rootDirectory.GetFiles("*.hbs"))
{
string subtemplateName = templateFile.Name;
int fileExtensionPosition = subtemplateName.LastIndexOf('.');
if (fileExtensionPosition > 0)
{
subtemplateName = subtemplateName.Substring(0, fileExtensionPosition);
}
if (relativeDirName.Length > 0 && relativeDirName[relativeDirName.Length - 1] != Separator)
{
relativeDirName += Separator;
}
AppendFileTemplate(builder, helper, templateName, relativeDirName, subtemplateName, templateFile);
}
}
 
private static void AppendFileTemplate(StringBuilder builder, HtmlHelper helper, string templateName, string relativeDirName, string subtemplateName, FileInfo templateFile, bool noTemplateName = false)
{
if (templateFile.Extension.ToLowerInvariant().StartsWith(".htm"))
{
//for .html/.htm* files, we'll simply append the content
var content = File.ReadAllText(Path.Combine(Path.Combine(templateName, relativeDirName), subtemplateName));
builder.Append(content);
return;
}
var fullTemplateName = templateName + relativeDirName + subtemplateName;
 
//for other template files, we treate them as x-handlebars script type
if (noTemplateName)
{
builder.AppendLine("<script type=\"text/x-handlebars\">");
}
else
{
builder.AppendLine("<script type=\"text/x-handlebars\" data-template-name=\"" + fullTemplateName + "\">");
}
 
var controllerContext = new ControllerContext(helper.ViewContext.HttpContext, new RouteData(), helper.ViewContext.Controller);
controllerContext.RouteData.Values["controller"] = string.IsNullOrEmpty(relativeDirName) ? "Home" : Path.GetDirectoryName(relativeDirName);
var result = ViewEngine.FindView(controllerContext, subtemplateName, null, false);
var stringWriter = new StringWriter(builder);
var viewContext = new ViewContext(controllerContext, result.View, new ViewDataDictionary(), new TempDataDictionary(), stringWriter);
result.View.Render(viewContext, stringWriter);
 
builder.AppendLine("</script>");
}
 
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.