Writing an unthemed view while still using Orchard shapes and helpers

Posted by Bertrand Le Roy on ASP.net Weblogs See other posts from ASP.net Weblogs or by Bertrand Le Roy
Published on Sat, 20 Oct 2012 21:16:00 GMT Indexed on 2012/10/20 23:02 UTC
Read the original article Hit count: 345

Filed under:
|
|

This quick tip will show how you can write a custom view for a custom controller action in Orchard that does not use the current theme, but that still retains the ability to use shapes, as well as zones, Script and Style helpers.

The controller action, first, needs to opt out of theming:

[Themed(false)]
public ActionResult Index() {}

Then, we still want to use a shape as the view model, because Clay is so awesome:

private readonly dynamic _shapeFactory;

public MyController(IShapeFactory shapeFactory) {
    _shapeFactory = shapeFactory;
}

[Themed(false)]
public ActionResult Index() {
    return View(_shapeFactory.MyShapeName(
        Foo: 42,
        Bar: "baz"
        ));
}

As you can see, we injected a shape factory, and that enables us to build our shape from our action and inject that into the view as the model.

Finally, in the view (that would in Views/MyController/Index.cshtml here), just use helpers as usual. The only gotcha is that you need to use “Layout” in order to declare zones, and that two of those zones, Head and Tail, are mandatory for the top and bottom scripts and stylesheets to be injected properly. Names are important here.

@{
    Style.Include("somestylesheet.css");
    Script.Require("jQuery");
    Script.Include("somescript.js");
    using(Script.Foot()) {
        <script type="text/javascript">
            $(function () {
                // Do stuff
            })
        </script>
    }
}
<!DOCTYPE html>
<html>
    <head>
        <title>My unthemed page</title>
        @Display(Layout.Head)
    </head>
    <body>
        <h1>My unthemed page</h1>
        <div>@Model.Foo is the answer.</div>
    </body>
    @Display(Layout.Tail)
</html>

Note that if you define your own zones using @Display(Layout.SomeZone) in your view, you can perfectly well send additional shapes to them from your controller action, if you injected an instance of IWorkContextAccessor:

_workContextAccessor.GetContext().Layout
    .SomeZone.Add(_shapeFactory.SomeOtherShape());

Of course, you’ll need to write a SomeOtherShape.cshtml template for that shape but I think this is pretty neat.

© ASP.net Weblogs or respective owner

Related posts about ASP.NET

Related posts about Clay