views:

326

answers:

2

Hi,

how would you guys create a dynamic layout in ASP.NET MVC 2 where admins could select widgets to display, arrange them, disable, move them etc.? I mean a flexible layout that can be changed via the admin panel without having to touch the code. Here I thought about defining and storing layout widgets paths in a db. Later I could associate these widgets with routes (in db). For each request (controller, action) I would fetch the layout among with associated widgets and output them recursively. Probably I could user RenderAction and PartialViews for that.

Is my direction correct or should I focus on some other technique?

Thanks, Jakub

A: 

If you want interactive drag-and-drop of widgets, use jQuery or ExtJS. ExtJS has a complete portal example.

If you don't want to use javascript, you would need to roll a custom solution in which areas are defined and filled with dynamically-loaded partial views.

Dave Swersky
Thanks Dave, I don't want to use JQuery. I wil take the second solution.
Cosmo
+2  A: 

Rob Conery did a similar thing with his Kona rewrite. He was able to make regions in the page, and then associate widgets to those regions.

There are two approaches that come to mind:

1.) The first is you load all your widgets in the controller action and the content they hold. Then send all this information of widgets (in a model) up to your view and do your filtering there. This preserves your separation between the view and the controller. You'll probably want to create a helper method:

<% Html.RenderWidgets("Main", Model.Widgets) %>

<% Html.RenderWidgets("SideBar", Model.Widgets) %>

One note on the first approach. You'll probably want some kind of naming convention for your widgets, so you can find their partial view more easily.

2.) Another approach is to use RenderAction and call a "RegionController" that you can pass a region name to. Passing the region name will trigger a query for all widgets that fall within that specific region.

 <% Html.RenderAction<RegionController>(x=>x.Widgets("Main")) %>

 <% Html.RenderAction<RegionController>(x=>x.Widgets("SideBar")) %>

I personally would do the first approach, but I don't see a problem with the second approach other than the cries from the purists.

Khalid Abuhakmeh
Assuming that Widgets is an Ordered List I think the first example is the easiest.
Nissan Fan
Yeah the Widgets would most likely be an IEnumerable<Widgets> or ICollection<Widgets> with a widget having some kind of distinguishable property on it like widget.Region == "Main"
Khalid Abuhakmeh
Thanks Khalid! These were my first thoughts. I guess the first solution should be faster since each widget doesn't have to run the routing pipeline.
Cosmo