Using sections in Editor/Display templates
Solution 1:
You could proceed with a conjunction of two helpers:
public static class HtmlExtensions
{
public static MvcHtmlString Script(this HtmlHelper htmlHelper, Func<object, HelperResult> template)
{
htmlHelper.ViewContext.HttpContext.Items["_script_" + Guid.NewGuid()] = template;
return MvcHtmlString.Empty;
}
public static IHtmlString RenderScripts(this HtmlHelper htmlHelper)
{
foreach (object key in htmlHelper.ViewContext.HttpContext.Items.Keys)
{
if (key.ToString().StartsWith("_script_"))
{
var template = htmlHelper.ViewContext.HttpContext.Items[key] as Func<object, HelperResult>;
if (template != null)
{
htmlHelper.ViewContext.Writer.Write(template(null));
}
}
}
return MvcHtmlString.Empty;
}
}
and then in your _Layout.cshtml
:
<body>
...
@Html.RenderScripts()
</body>
and somewhere in some template:
@Html.Script(
@<script src="@Url.Content("~/Scripts/jquery-1.4.4.min.js")" type="text/javascript"></script>
)
Solution 2:
Modified version of Darin's answer to ensure ordering. Also works with CSS:
public static IHtmlString Resource(this HtmlHelper HtmlHelper, Func<object, HelperResult> Template, string Type)
{
if (HtmlHelper.ViewContext.HttpContext.Items[Type] != null) ((List<Func<object, HelperResult>>)HtmlHelper.ViewContext.HttpContext.Items[Type]).Add(Template);
else HtmlHelper.ViewContext.HttpContext.Items[Type] = new List<Func<object, HelperResult>>() { Template };
return new HtmlString(String.Empty);
}
public static IHtmlString RenderResources(this HtmlHelper HtmlHelper, string Type)
{
if (HtmlHelper.ViewContext.HttpContext.Items[Type] != null)
{
List<Func<object, HelperResult>> Resources = (List<Func<object, HelperResult>>)HtmlHelper.ViewContext.HttpContext.Items[Type];
foreach (var Resource in Resources)
{
if (Resource != null) HtmlHelper.ViewContext.Writer.Write(Resource(null));
}
}
return new HtmlString(String.Empty);
}
You can add JS and CSS resources like this:
@Html.Resource(@<script src="@Url.Content("~/Scripts/jquery-1.4.4.min.js")" type="text/javascript"></script>, "js")
@Html.Resource(@<link rel="stylesheet" href="@Url.Content("~/CSS/style.css")" />, "css")
And render JS and CSS resources like this:
@Html.RenderResources("js")
@Html.RenderResources("css")
You could do a string check to see if it starts with script/link so you don't have to explicitly define what each resource is.