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