views:

40

answers:

2

Hi. I want to be able to register scripts and stylesheets. These items would then be added to the head section of the current page. For example, I have a partial view called ImageViewer that renders a few images and relies on a script. Instead of adding this script in the view using the ImageViewer, I'd like to be able to register this script in the partial view action method.

Is there any standard way of doing this?

If there is not, how could I do it myself? The lifecycle of an MVC application does not seem to make this easy. The way I have tried to implement it is to iterate through a collection of scripts/stylesheets in the TempData collection, and then creating methods RegisterScript and RegisterStyleSheet to add information.

However, since I want to add this data to the head section of my page, and the partial view method is executed after the head section is rendered, it does not seem possible.

How would you go about to implement such behaviour?

+1  A: 

Ive done this by using a ViewMasterPage with a ContentPlaceholder in the head section, allowing my partial views to define the scripts/stylesheets/whatever to be included.

Jamiec
+1  A: 

The common approach (as pointed out by Jamiec) is to include a ContentPlaceHolder in the head section of your master template.

If however, you want your controller to decide what CSS to render (perhaps for theming or something similar) you could also create a HTML helper to do this. A quick and dirty implementation to illustrate:

Master page:

<head runat="server">
    <%= Html.IncludeStyles() %>
</head>

Action method:

public ActionResult SomeAction()
{
    ViewData["StyleSheets"] = new[] { "StylesheetA", "StylesheetB" };
    return View();
}

HTML Helper:

public static class HtmlHelperExtensions
{
    public static string IncludeStyles(this HtmlHelper helper)
    {
        var styles = helper.ViewData["StyleSheets"] as IEnumerable<string>;
        var sb = new StringBuilder();

        if (styles != null)
        {
            foreach (var style in styles)
            {
                sb.AppendFormat("<link rel=\"stylesheet\" href=\"/content/" + style + ".css\" />\n");
            }
        }

        return sb.ToString();
    }
}
richeym
Hi. Yes, this is pretty much what I have done, however, in my case SomeAction is an partial view that is executed after the head section is rendered. Which means that I can't add scripts or styles there. I can't think of any solution that doesn't force me to have my main view know of the scripts that all my partial views use. Do you have any solution to that problem?
Max Malmgren
@richeym Linking to your username so you get notified of my previous comment.
Max Malmgren