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