Developer Area/Core Subsystems/View Templates

From Mahara Wiki

< Developer Area‎ | Core Subsystems

(see also HowToWriteAViewTemplate)

Templates will be installed during post-inst, they will be parsed at that time and have their parsed data stored serialized in the database.

There will be two locations for templates, within the document root (lib) and inside dataroot. This means that in the future, custom templates can be developed without overriding the system ones.

The parser will split the template into a structure like this:

Array (
0] => Array (
type]    => html,
content] => <p>html code herep>
2] => Array (
type] => block
[data] => Array (
type] => 'label',
3] => Array (
type]    => html,
content] => <p>html code herep>

... etc

A template will be a HTML fragment (from within

tags) and optionally a stylesheet. If a stylesheet exists, mahara will import the mahara wide stylesheet first, and then the template stylesheet.

Blocks will be designated within the template like so:

{{block type="" format="" id="" width="" height="" defaulttype="" defaultformat=""}}

where type is optional and corresponds to an artefact type.

Format is one of: label, listself, listchildren, renderfull and rendermd. The last four of these correspond to the formats (which are constants):


  • My holiday blog (10 posts)

ONE of an item in a list


My holdiday blog would render like:

  • I just arrived in Wellington! (3 November 2006)
  • The weather in Wellington is crap (4 November 2006)

My holiday blog would list posts as FORMAT_ARTEFACT_LISTSELF.


A blog post would render itself here in entirity A blog cannot render to this format.


My holiday blog would render like:

My holiday blog (10 posts) Long description here Created: 1 November 2006 Last updated: 4 November 2006 ... etc

Label is a special case, which will allow the user to add plain text.

Type can also be ommitted, in which case the user can place anything in the block (except treat it as a label).

Each artefact type has a list of formats it can render to, and given a format, can export its ability to crop or scale to that format. For example, an image can always crop and scale in FORMAT_ARTEFACT_RENDERFULL, a pdf cannot render to FORMAT_ARTEFACT_RENDERFULL.

(Back to the /div/p[23]/span, reference to undefined name 'block' description) id is a unique identifier for the block within the template. The parser will complain bitterly if it is not unique. This is similar to the id attribute in HTML.

Width and height are used to define the size of the block on the screen. If they are not present, the artefact won't have to crop or scale to fit. If they are given, the artefact will have to redraw itself to that size (for an image it might be just resizing the image, for a blog it might be a ... more link under the list of posts, etc.

defaulttype and defaultformat together is a special attribute that means that when the editmode renderer is used for the first time, all blocks with defaults will be filled. For example, if the default is careergoals, The renderer will look for a class called ArtefactTypeCareergoals? and if the user has an instance of one, it will automatically render the artefact inside that block (using the ajax method described further down).

At parse time, the parser checks that all given types and formats are valid, the type can render to the given format, and call a static method to determine whether it's a 0 or 1 type artefact (used for defaults). This is true for both type and format, and defaulttype and defaultformat. Additionally, you can not specify one of these without the other.


We will need to write a generic getchildren script that returns json. This script will take the following parameters:

plugintype artefact or 'core' pluginname plugin name or if core, a sub package (eg view) id nullable, if applicable an id can be given (eg view id or artefact id) userid nullable, if applicable, the owner of objects to return.

This script will defer logic to the appropriate plugin and just convert the data to json and return it.

This will be the callback json script used when expanding objects in the tree view in CreateViewStage3. The javascript handler will need to store the returned data in a global hash as well as just redrawing the tree, in order to keep around data about each artefact (eg, which formats it can render to).

Rather than using the name to select an artefact to place in the view, next to the name will be different icons which corresponde to the different formats. Depending on which one is clicked, blocks will become selectable or not, depending on their properties. For example clicking on the FORMAT_ARTEFACT_LISTSELF icon next to an image will cause a block which is type = FORMAT_ARTEFACT_RENDERFULL to be not selecable. The user will be expected to select the artefact they want to embed first, and then the destination block.

Blocks of type label will only be clickable when an artefact is not selected, because they're populated with typing.

When an artefact is 'dropped' into a block, there will be a javascript handler which does an ajax request to another json script that creates an instance of that artefact and calls its render function, giving it the appropriate format. It wraps the HTML that is returned by this method in json and echos it, where it is caught by javascript, which changes the block's content to be that HTML. In the case of some of the formats, there will need to be additional javascript handlers to append HTML rather than replace (eg FORMAT_ARTEFACT_LISTSELF).

Some artefact types will need to be able to 'fold' into a top level artefact type tree node (for example profile fields). This similar to AdminPlugins? page, where the profile fields don't export themselves as configurable, instead they defer to the 'profile' artefact class. This means that when you expand 'profile' as a top level artefact type node, rather than getting all the profile fields as child types, you just see the values.

TODO: table of artefact types and formats TODO: do we need to differentiate between crop and scale?