Somehow my intuition is always a little bit at odds with MVC (as found in current web frameworks). It feels more natural that the view would request the data it needs, especially if it is putting together a mosaic of different sources.
For example, I guess most web applications have some sort of layout view and include the content into it. But what if there are different kinds of things to include? For example there could be a list of logged in users to be displayed in the sidebar, or any number of widgets. It seems unnatural to have to gather the data for those in every controller call.
My experience is with Java frameworks, where usually the flow is through one controller - how does for example Rails deal with that sort of thing? For Java I guess the proposed solution is Portlets, but I haven't seen their wide adaption yet, and they seem to be another headache (those Java specs should be made shorter and more concise).
What is the best solution?
Also, imagine an application with a Web view displaying a data set returned from a controller. Now the client/user wants an OS-native version of the app. That's simple, just build a native (OS-specific) window view and call the same controller for the data set (model). Or maybe an API is needed for external consumption. In that case a web service "view" can be built to return the same data set from the same controller. We're just swapping views here--it's plug-and-play.
It's a clear separation of responsibilities. I believe that used to be called "modular" programming. ;)
MVC is an elegant design pattern, but I think an MVC framework must provide a simple way for components to include other components. Otherwise, I can see why you would find it frustrating that your main controller has to do all the work.
Aren't these things conceptually separate views, each having its own controller?
However, mentioning MVC and web applications gives me an excuse to engage in nostalgia and once more mourn the passing[1] of WebObjects. It was simple in WebObjects to make any reusable part of a page into its own component. Also, MVC has a much bigger payoff when you have development tools designed to support it. WOBuilder allowed you to graphically build interface components, then just drag connections between properties in your controller object and the widget you wanted to display them in. And not just top level properties, but you could drill down through the relationships of any object (e.g. user.shoppingCart.numberOfItems, Google "key value coding" if interested). (And yes, this is just like Cocoa and Interface Builder, came out of the same technology base originally.)
I have yet to see any web development tools[2] that come anywhere close to the productivity enabled by WebObjects. And I didn't even get into the Enterprise Objects Framework...
[1] WebObjects is still very much alive inside Apple (iTunes store, Apple Store, pretty much everything Apple does on the web) but for outside developers it is quite dead. The only life support is ant + Eclipse plugins, but that defeats the whole purpose as the development tools were the whole point of WebObjects. [2] Tools as distinct from programming languages. WebObjects was Java, so nothing special there, but real old timers still miss the Objective C version.
In Rails, you don't necessarily have to have a monolithic view. On more complex sites, you use fragments, called partials. Sidebars can be easily created by having a "shared" view directory full of partials. Further, there is a content_for helper in Rails views. Views render late; you can set an instance variable in the subviews that will affect what gets rendered in the layout. Trying to keep track of that can get hairy, so content_for abstracts that for you. Combined with the partials and the before_filter in the controllers, you can get a view to produce a number of things without having to resort to pulling DB info inside the views -- that reminds me too much of the bad old days of PHP.
In the logged-in users example, in what is normally in the sidebar, you use a render :partial => 'shared/users' if @users; then add a before_filter in the site-wide application layout to pull in the data if someone is logged in. A more complicated example is to render a "sidebar" partial, which renders more partials depending on some array of sidebars you want to display ... then use a before_filter to figure out what you want to populate the sidebars with. Any controller or actions can override or add to that sidebar array.
The main thing that sucks about this kind of organization is having the code scattered in a number of different files. This is where using an editor that knows the relationship between the files is important -- you can hit some key combination and jump between the different fragments without having to hunt them down in the file browser.
I was helping out on this one site built in PHP a while back where the code wasn't organized this way. It took me about a week to figure out where things were, which was a huge productivity drag for the other guys.
Caveat: My MVC experiences have been mostly with Java (Struts) and Python (Django) Then to get into your actual points:
1) The view CAN do the work of determining what will be shown. To quote the Django site: "In our interpretation of MVC, the "view" describes the data that gets presented to the user. It's not necessarily how the data looks, but which data is presented."
2) Anything that is a common widget should be abstracted and included on the page in some sort of "include". Either have some sort of base page that does the work, or on the individual pages do some method of "include". This really doesn't relate to MVC, other than your point about adding the data to your context/session, which should again be done generically and non per-page.
3) The general idea for any MVC system is to have the flow go through one controller. This controller may delegate to sub-controllers, but the idea is everything goes to one spot.
4) What is the best solution? There are many good solutions for writing a web app.
1) In Django the controller is called the view and the view is called the template, same principle but unless you want to get confused you should think of it as MTV == MVC (if you want to equate the two, Django seems to be perfectly happy making up its own interpretation of MVC for no apparent reason). Really the controller (in the MVC sense) is doing the work here.
The controller is doing the work to determine what will be shown, yes. I meant once the controller determines which view should be used, the view then can manage the specific data being shown.
Django does separate the view into a 'view' and a 'template'. One does your work, and the other does the displaying.
If you, as you suggest, have the view (essentially a glorified HTML template) request the data it needs (e.g. from multiple sources), then your data-selection and visual-presentation become tightly coupled. (The point of a view is that you can have multiple views of the same data). If the original view is handling things like data-selection and complex control flow, then when you want to create an alternate presentation of the same data, you'll end up copy-and-pasting code (c.f. "Don't Repeat Yourself").
So the best solution is to get a really good feel for separation of concerns, code-non-duplication, etc., and then organize your code accordingly. When using MVC, use every bit of it to keep your code simple and decoupled; if you just slap code into units called "models", "views", and "controllers" wherever you like, then you will receive NO BENEFIT (or negative benefit!) from using MVC. But, used properly, it can be a powerful tool.