ModelViewController

Model-View-Controller (MVC) is a well known software architecture pattern, used in many web applications. I thought it would be interesting to try and describe the Foswiki core in terms of the MVC pattern, as it may help some folks understand how Foswiki "works".

First off, it has to be understood that that Foswiki started life as a suite of disconnected perl CGI scripts, and was developed for a number of years before any proper architecture plan emerged. As a result there is a lot of code in there that is still there because..... well, because it works, and there hasn't been a strong reason to change it to fit "the pattern". So in some cases, model and view and controller are mixed up together in the same module (the same is true of other systems that were designed from the ground up using MVC pattern, so we're in good company. So read the following with a large pinch of salt, and if something doesn't quite fit the pattern, c'est la vie.

OK, so here we go:

Model

The model manages the behavior and data of the application domain, responds to requests for information about its state (usually from the view), and responds to instructions to change state (usually from the controller). (Wikipedia)

The Model part of the Foswiki core is the area which has received the most refactoring attention in recent years. The outcome of this work has been to create abstract interfaces in the core to different parts of the model, and these interfaces now provide a reasonable degree of separation which lets us identify the component parts of the model. These are:
  • Foswiki::Meta - is how the model is presented to the rest of the core code (the views and controllers)
    • Foswiki::Store (and everything under lib/Foswiki/Store) is a second abstraction layer within the model, used exclusively by Foswiki::Meta
    • The Foswiki::Meta class implements what has been referred to elsewhere as the TopicObjectModel in Foswiki. A Meta object is an interface to a web or a topic that is held in the store. The interface is fairly clean, though is polluted by a number of methods (marked with SMELL in the source code) that belong in the view.
  • Foswiki::Prefs and lib/Foswiki/Prefs implement the internal model of preference settings
  • Foswiki::Form and lib/Foswiki/Form) provides a model of a data form attached to a topic. Unfortunately there is quite a lot of view code mixed in there too.

View

The view renders the model into a form suitable for interaction, typically a user interface element. Multiple views can exist for a single model for different purposes. (Wikipedia)
  • Foswiki::Search and lib/Foswiki/Search implement the presentation of search results
  • Foswiki::Macros deals with the expansion of Foswiki %MACROS%. These are not pure view code - the result from a macro expansion is fed direct into a view, but they are not really pure view either, as they implement much of the hard work of a controller. This is especially true when you factor in Plugins, which often implement major blocks of controller functionality in macro expansions.
  • Foswiki::Attach deals with presentation of attachments
  • Foswiki::Templates deals with the expansion of templates
  • lib/Foswiki/UI modules handle incoming requests. Unfortunately the views are tangled up with much controller code.
  • templates/* and locale/* are the partials used in building the actual views

Controller

The controller receives input and initiates a response by making calls on model objects. A controller accepts input from the user and instructs the model and viewport to perform actions based on that input. (Wikipedia)
  • bin contains all the CGI scripts that are the controller "entry points"
  • Foswiki::Macros deals with the expansion of Foswiki %MACROS%. These are not pure controller code - the result from a macro expansion is fed direct into a view - but they are not really pure view either, as they implement much of the hard work of a controller
  • Foswiki::Merge implements the merge functionality
  • lib/Foswiki/UI modules handle incoming requests. Unfortunately the controllers are tangled up with much view code.
  • Foswiki::Engine and Foswiki::UI.pm implement the incoming request dispatcher
  • Foswiki::Request and Foswiki::Response implement the request/response parts of web MVC.
  • Foswiki::Users and lib/Foswiki/Users implement session and user management

-- CrawfordCurrie - 09 Nov 2010
Topic revision: r2 - 09 Nov 2010, CrawfordCurrie
The copyright of the content on this website is held by the contributing authors, except where stated elsewhere. See Copyright Statement. Creative Commons License    Legal Imprint    Privacy Policy