downloads documentation getting help mailing lists screenshots installation instructions template reference framework overview api documentation

Overview of the METAjour application framework

Data structure

Datatypes
The primary element that the METAjour application framework is based upon, is the datatype. Datatypes are definitions of objects - collections of different field types, relations to other datatypes and special behavior that overrides parent datatypes. They are implemented as ordinary classes in PHP.
The basic abstract datatype is called basic. It is defined by the class named basic in the basicclass.php file located in the core directory below the main METAjour directory. The basic datatype is abstract, hence no objects of that datatype exist. All other datatypes descend from basic and have their own class named <datatype> placed in the <datatype>class.php file in the core directory.
All datatypes, except the special type called system datatypes, have at least one table (the datatype table) that holds the data for the objects of that datatype. The datatype table is by default named <datatype>, but this can be defined in the datatype definition. The datatype table holds at least two columns: objectid and name. objectid is the unique object identifier in METAjour, and binds the row in the datatype table with the object properties stored in the object table. name is the visual representation of the object, for instance the name of a document in an object listing of document objects. In most datatypes the name can be anything, even empty or duplicated, but in some datatypes it has to be unique and non-empty. Some datatypes consist only of an objectid and a name, i.e. the category and folder datatype. The objectid is predefined, and is not a part of the datatype definition, but the name column is. This is because the name column doesn't neccessarily have to be a certain field type - it can be anything: a string, an integer, a floating point number etc. This is to the datatype to decide - the name column just have to be defined.

Extensions
METAjour is distributed as open source, so any part of the application can of course be modified and extended to suit your needs. To assist you in this, and to make it easier to distribute your enhancements to other users of METAjour, we have designed appropriate interfaces to extend METAjour.

We have 2 different types of extensions in METAjour. We have datatype extensions, and we have functional extensions. As you will see later, they aren't always separate.

Datatype extensions
The datatype extensions are ordinary datatypes, just as the core datatypes. They can be acompanied by views and models to extend the functionality of the basic views and models that applies to any datatype. Datatype extensions are made with classes named <datatype> in files named <datatype>.datatype.php placed in the directory named <datatype> in the extension directory below the main METAjour directory. Views and models that are either overriding existing views and models with datatype specific views and models, or are just plain new ones, are also placed in this directory. There is no functional difference between datatypes placed in an extension directory and datatypes placed in the core directory. But we encourage you to use extension directories because of the ability to store models, views, language files and other accompanying files in the same directory structure as the datatype definition file. Besides that, datatypes in extension directories are automatically placed in the program menu inside METAjour. When placed in the core directory you have to make a menu entry manually. Using extension directories makes it a lot easier for you to preserve the extension between METAjour versions, and it makes it easier for you to distribute the extension.

Functional extensions
The functional extensions are what you might see as "website components". They only exist on the resulting website, not in the METAjour application itself. Common functional extensions are search, which will provide the search mechanism on the website, and shop, which implements the entire shopping system on the website.

The class table
The class table holds a complete list of all datatypes and extensions available in METAjour. The class table has a name column with the name of the datatype or the extension, and a type column indicating whether the class is a core datatype (0), a functional extension (1), a datatype extension (2) or a system class (5).


Application structure

The METAjour user interface is built around the widely accepted Model-View-Control pattern. This makes it easy to maintain and extend the actions and presentations of objects.

Model class
The purpose of a model is to modify an object, i.e. update the data of an object, change properties etc.
Any action has its own class. The basic actions are placed in classes named basic_model_<action> in files named basic_model_<action>.php. Actions made specifically for certain data types are placed in classes named <datatype>_model_<action> in files named <datatype>_model_<action>.php.
Both basic actions and derived actions for specific datatypes can be overridden for applications derived from METAjour. In that case, the files are placed in the app/<appname>/ directory below the main METAjour directory.
The model classes have only one public method named model().

View class
The purpose of a view is to present the user with information about an object, or dialogues with an interface to models that applies to the current object.
Any view has its own class. The basic views are placed in classes named basic_view_<view> in files named basic_view_<view>.php. Views made specifically for certain data types are placed in classes named <datatype>_view_<view> in files named <datatype>_view_<view>.php.
Both basic views and derived views for specific datatypes can be overridden for applications derived from METAjour. In that case, the files are placed in the app/<appname>/ directory below the main METAjour directory.
The view classes have only one public method named view().

Context class
In METAjour we have divided the view into "view" and "context". A view is only a small, yet important, part of the entire screen dialog with the user. The view, as we use the term, is an atomic part of the user interface, i.e. an object listing, a dialog box, an input form etc. A view can even consist of collections of other views. The context on the other hand is, not surprisingly, the context in which the view resides. It can for instance be what we refer to as "normal", the primary user interface, or it can be "dialog", when a view is presented in a dialog box separated from the primary user interface. Which context is used for a view, is determined by the "caller" (the part of the application initiating the view). The caller can only suggest the appropriate context for a view, which will usually be approved, but can't enforce it. In some special cases the view itself will modify the context class, for instance when the view needs to stream binary data to the browser.
 
Control class
The controller class takes care of initiating the appropriate models and views, and in calling their methods as needed. The primary control class is named basic_control and resides in the basic_control.php file.
The controller can be seen as an event handler. It can carry out an action on one or more objects, or it can call a view, i.e. an object listing. In a real life application like METAjour the controllers job is somewhat more complex than that. For instance, when a user presses the delete button, after having selected several objects on an object listing, the controller will call the "delete" view which will ask the user to confirm the action. The "delete" view contains information about which model that will be executed on confirmation (in this case the "delete" model). But the caller (the delete button on the object listing), has also supplied the "delete" view with information about what the "delete" view should do upon confirmation (beside executing the "delete" model). This is usually used for getting back to an appropriate part of the application - in this case refreshing the object listing upon completion. We call this "return information". The return information is, of course, something that only the caller is able to set, because the "delete" view itself has no knowledge at all from which part of the application it was initiated. So just as the context, it is the responsibility of the caller to supply the initiated view with this information. Closing dialog windows, refreshing caller views etc. are also plain views, so the entire application can be seen as views that communicate with each other by adding views and models to a stack maintained by the controller.

Caller view (the delete button on the object listing):
 put the "delete" view in event stack
put return information in event stack ("jsreloadopener")

Delete view:
 on confirmation put "delete" model and "jswindowclose" into event stack

Controller:
 Execute "delete" model
 Execute "jswindowclose" view
 Execute "jsreloadopener" view

Models are always carried out before views.

The control class can be overridden for applications derived from METAjour.