Created
April 16, 2012 13:52
-
-
Save joelpurra/2398969 to your computer and use it in GitHub Desktop.
MvcScriptHelper: Helps render multiple script blocks from multiple pages/layouts/partial views, in the expected order
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//----------------------------------------------------------------------- | |
// <copyright file="MvcScriptHelper.cs" company="The Swedish Post and Telecom Authority (PTS)"> | |
// Copyright (c) 2011, 2012 The Swedish Post and Telecom Authority (PTS) | |
// Developed for PTS by Joel Purra <http://joelpurra.se/> | |
// Released under the BSD license. | |
// </copyright> | |
//----------------------------------------------------------------------- | |
// https://gist.github.com/2398969 | |
namespace JoelPurra.Web.Helpers | |
{ | |
using System; | |
using System.Diagnostics.Contracts; | |
using System.Linq; | |
using System.Web; | |
using System.Web.Mvc; | |
using System.Web.WebPages; | |
/// <summary> | |
/// Helps renders multiple script blocks from multiple pages, layouts, partial views in the expected order. | |
/// </summary> | |
public static class MvcScriptHelper | |
{ | |
#region Constants and Fields | |
private static int counter; | |
#endregion | |
#region Public Methods | |
/// <summary> | |
/// Renders multiple script blocks from multiple partial views | |
/// </summary> | |
/// <remarks> | |
/// Inspiration from http://stackoverflow.com/questions/5433531/using-sections-in-editor-display-templates/5433722#5433722 | |
/// </remarks> | |
/// <param name="htmlHelper"> </param> | |
/// <returns> </returns> | |
public static IHtmlString RenderScripts(this HtmlHelper htmlHelper) | |
{ | |
Contract.Requires(htmlHelper != null); | |
// Order the collection by the key in order to output scripts in the order they were added on each "execution level". | |
// This is a hack due to the execution order of Razor pages | |
// See http://mvcdev.com/differences-between-asp-net-razor-and-web-forms-view-engines/ | |
IOrderedEnumerable<object> scriptKeys = | |
htmlHelper.ViewContext.HttpContext.Items.Keys.Cast<object>().Where( | |
key => key.GetType() == typeof(int[])).OrderBy(key => string.Join(", ", (int[])key)); | |
foreach (object key in scriptKeys) | |
{ | |
Func<object, HelperResult> template = | |
htmlHelper.ViewContext.HttpContext.Items[key] as Func<object, HelperResult>; | |
if (template != null) | |
{ | |
htmlHelper.ViewContext.Writer.Write(template(null)); | |
} | |
} | |
return MvcHtmlString.Empty; | |
} | |
/// <summary> | |
/// Adds script blocks to be executed in order called. | |
/// </summary> | |
/// <example> | |
/// <![CDATA[@Html.Script( | |
/// @<script> | |
/// //<![CDATA[ | |
/// alert("This is a script block!"); | |
/// //]]> | |
/// </script>) | |
/// ]]> | |
/// </example> | |
/// <remarks> | |
/// Inspiration from http://stackoverflow.com/questions/5433531/using-sections-in-editor-display-templates/5433722#5433722 | |
/// </remarks> | |
/// <param name="htmlHelper"> </param> | |
/// <param name="razorExecutionLevel"> </param> | |
/// <param name="template"> One or more script blocks. Surround multiple blocks with the <text> tag. </param> | |
/// <returns> </returns> | |
public static MvcHtmlString Script( | |
this HtmlHelper htmlHelper, RazorExecutionLevel razorExecutionLevel, Func<object, HelperResult> template) | |
{ | |
Contract.Requires(htmlHelper != null); | |
Contract.Requires(template != null); | |
int razorExecutionLevelInt = (int)razorExecutionLevel; | |
// TODO: Make a new ScriptKey class that is sortable | |
int[] key = new[] | |
{ | |
razorExecutionLevelInt, counter | |
}; | |
htmlHelper.ViewContext.HttpContext.Items.Add(key, template); | |
counter++; | |
return MvcHtmlString.Empty; | |
} | |
public static MvcHtmlString ScriptInLayout(this HtmlHelper htmlHelper, Func<object, HelperResult> template) | |
{ | |
Contract.Requires(htmlHelper != null); | |
Contract.Requires(template != null); | |
return htmlHelper.Script(RazorExecutionLevel.Layout, template); | |
} | |
public static MvcHtmlString ScriptInPage(this HtmlHelper htmlHelper, Func<object, HelperResult> template) | |
{ | |
Contract.Requires(htmlHelper != null); | |
Contract.Requires(template != null); | |
return htmlHelper.Script(RazorExecutionLevel.Page, template); | |
} | |
public static MvcHtmlString ScriptInPartialView(this HtmlHelper htmlHelper, Func<object, HelperResult> template) | |
{ | |
Contract.Requires(htmlHelper != null); | |
Contract.Requires(template != null); | |
return htmlHelper.Script(RazorExecutionLevel.PartialView, template); | |
} | |
#endregion | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//----------------------------------------------------------------------- | |
// <copyright file="RazorExecutionLevel.cs" company="The Swedish Post and Telecom Authority (PTS)"> | |
// Copyright (c) 2011, 2012 The Swedish Post and Telecom Authority (PTS) | |
// Developed for PTS by Joel Purra <http://joelpurra.se/> | |
// Released under the BSD license. | |
// </copyright> | |
//----------------------------------------------------------------------- | |
// https://gist.github.com/2398969 | |
namespace JoelPurra.Web.Helpers | |
{ | |
public enum RazorExecutionLevel | |
{ | |
Layout = 1, | |
Page = 2, | |
PartialView = 3 | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment