Where does (active) sidebar content fin in MVC?

I’m experimenting with redesigning a site to follow the MVC structure as an exercise. I’m loosely basing it on an article I’ve read somewhere, but from what I can tell it’s a fairly standard MVC setup. So far everything is going OK, but I’m struggling a bit with finding the appropriate place where I should place certain things belonging to general layout/sidebar etc. related stuff especially where that stuff also requires data from the model level. e.g. top lists etc.

So here’s a grossly simplified summary of my current setup:

  • Everything’s processed through index.php
  • The index page analyses the request parameters and identifies the required controller and the requested action
  • It then instanciates the appropriate controller class and calls a public method corresponding to the requested action
  • The controller obtains the necessary data from the model layer and selects the view to be rendered
  • The controller is also supposed to be able to select one of the pre-defined layouts that wrap the view belonging to the selected action

The folder structure is roughly as follows:

  • framework
  • models
  • models/modelname.php
  • controllers
  • controllers/controllername.php
  • views
  • views/controllername/actionname.php
  • views/shared/layouts
  • views/shared/layouts/layoutname.php

Now my problem is the following:

Let’s assume that the current request is to display an article. The system above would select the ArticleController and the display() action. The controller will retrieve the requested article and select the appropriate template to be rendered (“views/articles/display.php”). However in addition it will also select the “default” layout to be used. This in turn will select the “views/shared/layouts/default.php” to be used as a wrapper for the main content (“views/articles/display.php”). So far so good…

Now let’s assume further the the default layout contains a sidebar which may include such modules as “recommended articles”, “top read articles” or “online users” etc. All of these modules require data from the model layer (but not necessarily from the ArticleController)… The question is who would be responsible for retrieving the necessary data? And where to put it? etc…

Within my systems I work on there are ways to execute modules as nested modules from either the template or module. So specific to the architecture I work on the sidebar would be its its own module and it would executed from within the master template. I would then create a module to that lists the recommended articles and top read articles in a separate module that would give me either based on supplied arguments.

Again this is very specific to how the systems I work on but you can imagine seeing the below code within the master template so that each of these operations are reusable throughout the entire system.


/*
* Execute sidebar module
*/
$this->app->executeModule('Site.*.Module.Sidebar');

/*
* Execute widget/module to show recommended articles
*/
$this->app->executeModule('Site.*.Module.Widget',array('articl','recommended'));

/*
* Execute widget/module to show top read articles
*/
$this->app->executeModule('Site.*.Module.Widget',array('article','top-read'));

Ignoring the * these calls would execute the current sites requested modules from within the template or modules. You can think of it as a sub/nested request minus the master template. Being able to execute modules or controllers like this makes the code highly reusable and eliminates repetition that would otherwise be needed to accomplish a similar functionality. The array following the modules path are the arguments that will be supplied to that module as if the module itself was being executed as the true requested module.

Hmm… This is an interesting thought! Why did I not think of that :slight_smile:

So to see if I understand this correctly:

You would make the main dispatch into a generic “execute()” function which can be called (recursively) at any time not just when processing the requested URL. That way the output produced by the “view” for a given controller/action pair can be injected into the complete response at any stage, and the only difference between processing the “whole page” and a module would be that modules are rendered using a blank “layout”… This way “TopList” could just be an action in the ArticleController and its template could be located in the proper “views/articles” folder… I think I like that idea! Thanks!

Yep, you got it.