6

I have javascript blocks that are small. I would like to have these same blocks appear inline in my code but don't want to repeat them in each file. Is there a way that I can "include" code into the Razor file that doesn't involve

<script src="@Url.Content("~/Scripts/small_script_block1.js")" type="text/javascript"></script>

Thanks

JudyJ
  • 597
  • 5
  • 7
  • 14

3 Answers3

7

Another possibility that will take me a few more minutes to write up:

Create an extension method for HtmlHelper. In your cshtml file it would look like this:

@Html.InlineScriptBlock("~/scripts/small_script_block1.js")

If you want I can send you the implementation but that idea might be all you need. If not, add a comment and I'll write it up.

EDIT CODE Below (not pretty and no warranty implied or given :)

public static class HtmlHelperExtensions
{
    public static MvcHtmlString InlineScriptBlock<TModel>(this HtmlHelper<TModel> htmlHelper, string path)
    {
        var builder = new TagBuilder("script");
        builder.Attributes.Add("type", "text/javascript");

        var physicalPath = htmlHelper.ViewContext.RequestContext.HttpContext.Server.MapPath(path);
        if (File.Exists(physicalPath))
        {
            builder.InnerHtml = File.ReadAllText(physicalPath);
        }

        return MvcHtmlString.Create(builder.ToString());
    }
}

Keep in mind that if you drop this into your project you will need to make the namespace visible to the views. Unlike ASP.NET WebForms where you could provide markup at the top, Razor requires you to do this in the Web.config file in the Views folder.

<pages pageBaseType="System.Web.Mvc.WebViewPage">
  <namespaces>
    <add namespace="System.Web.Mvc" />
    <add namespace="System.Web.Mvc.Ajax" />
    <add namespace="System.Web.Mvc.Html" />
    <add namespace="System.Web.Routing" />
    <add namespace="Your.Namespace.Here.Extensions" />
  </namespaces>
</pages>
CodeMonkeyKing
  • 4,556
  • 1
  • 32
  • 34
  • Thanks CodeMonkeyKing. Your inlineScriptBlock looks good. Any chance u could post the code so I could see it. BTW I thought I saw an implementation using @Html.Partial to render the js from an external file. Now I don't see it on this page. Do you think this would be a good way to do it. Lee – JudyJ May 08 '11 at 05:24
  • I 'deleted' that suggestion as I thought that the InlineScriptBlock might be a better idea since you could include a 'raw' Javascript file. I'm working on the implementation now and will EDIT this answer when it is functional. – CodeMonkeyKing May 08 '11 at 05:27
  • Thank you very much for taking the time to help me. Lee – JudyJ May 08 '11 at 05:31
  • Thank you CodeMonkeyKing. I have used extension methods before and this one looks good. Also might be good for me to use and modify for other needs later on. If you have time can you tell me if this would be very different from using the different RenderPage, @Html.Partial or @Html.RenderPartial options – JudyJ May 08 '11 at 05:50
  • Lee - take a look at the comments on the other answer, I tried to explain the difference between Html.Partial and RenderPartial. When contrasting @RenderPage vs @Html.InlineScriptBlock above, the @RenderPage() would not know to insert the tags around your raw JavaScript files. You would then what to have your "script" block contained inside of a short .cshtml partial view. It would include the . I think the extension method is a little more helpful in the long run. Can you accept this answer :) – CodeMonkeyKing May 08 '11 at 06:00
  • BTW - here's an article on the difference between the various @RenderXxxx() methods in Razor.http://www.dotnetcurry.com/ShowArticle.aspx?ID=636 – CodeMonkeyKing May 08 '11 at 06:02
  • 1
    You can use @using in your Razor views to import a namespace if you don't want to touch web.config. (Though if you're repeating the @using, it's probably a good idea to use web.config anyway.) – Jim D'Angelo May 08 '11 at 06:08
  • Oh great to know! Thanks jdangelo. – CodeMonkeyKing May 08 '11 at 06:30
  • @CodemonkeyKing, no worries! =D – Jim D'Angelo May 09 '11 at 04:15
  • The only concern I see with this approach is the performance hit of reading the file from disk on each request, partial views (used in other answers below) are cached in memory an reloaded only when file changes. – Benja Feb 06 '13 at 19:11
5

You can use the @RenderSection syntax.

<head>
    @RenderSection( "JavaScript", optional : true)
</head>

somewhere in the body, add ..

@section JavaScript
{
    <script src="/Scripts/script.js" type="text/javascript"></script>
}

EDIT: Or if you prefer inline, then as follows:

@section JavaScript
{
    <script type="text/javascript">
    function doSomething() {
    }
    </script>
}
Jonathan Nixon
  • 4,940
  • 5
  • 39
  • 53
Leons
  • 2,679
  • 1
  • 21
  • 25
  • 1
    I think this doing the opposite of what Lee asked. However, it's an important design consideration for using Layouts (aka Master Pages in for those more familiar with WebForms) – CodeMonkeyKing May 08 '11 at 05:04
  • Thanks but I would like to have the javascript inline. You are just moving a call to an external file from a layout the the body. – JudyJ May 08 '11 at 05:05
  • @codemonkeyking - I considered that, but focused on the part of the question that talk about blocks of code, so the RenderSection seemed a good solution. The RenderPage, as you suggested, will also be a very good solution. – Leons May 08 '11 at 05:10
  • I updated the example to show how you can insert inline code with RenderSection. – Leons May 08 '11 at 05:12
  • Thanks Leons but your solution just moves code from the layout to the razor pages. I need to completely move it out of the razor pages. I think some other solutions here may meet my needs. Lee – JudyJ May 08 '11 at 05:19
  • I think I fully understand your question now and codemonkeyking has the right idea. – Leons May 08 '11 at 05:25
3
@RenderPage("_IncludeYourScriptsHere.cshtml")

Create a partial view and paste in your tag.

CodeMonkeyKing
  • 4,556
  • 1
  • 32
  • 34
  • Thanks CodeMonkey. Should I use RenderPage, @Html.Partial or @Html.RenderPartial. I'm getting rather confused with all the different choices. What I would like is for my page to be included pre-compilation. Do all these options include the js before the page is compiled? Thanks, Lee – JudyJ May 08 '11 at 05:30
  • Take a look at my other answer. To avoid confusion I can delete this page if you prefer the answer. @RenderPage is the Razor equivalent of an @Html.RenderPartial I believe. In MVC2 @Html.Partial is used to render a partial view (you can still use this w/ MVC3 and Razor). @Html.RenderPartial writes the response to the output stream and so your MVC2 version of this would have you use the <% Html.RenderPartial() %> vs. <%= Html.Partial() %>. This paraphrased from "Profession ASP.NET MVC 2" WROX - http://bit.ly/aJmn6p – CodeMonkeyKing May 08 '11 at 05:52