Documentation

There's documentation available here but it is by no means a complete documentation yet, I'm still working on it.

Contents

Documentation for Content Managers

Yet to be written...

Documentation for Developers

Introduction

CosMoS is a content management system that intends to offer a great deal of flexibility to the developer. The goal is that the developer can use an existing framework and worry only about the details that really matter to him/her, whilst leaving the rest up to the engine. This gives the developer more time to work on extra modules he/she needs for the project, and it gives the webdesigner more time to focus on the layout of the site.

CosMos offers a framework in which to work, and once set up it is easy to maintain and users can edit their content online through CosMoS' administration center. Developers and webdesigner's needn't worry too much about content, and content providers need not worry about coding or webdesign.

Required skills

The developer/webdesigner needs some skills to customize a CosMoS environment to his liking:

Architecture

The following picture gives a schematic representation of CosMoS' architecture. An explanation is in order here:

The scheme is divided into three areas, the main area concerns the software, the actual PHP scripts, the right hand of the scheme represents styling/layout, and the bottom-left corner represents data/content.

The black arrows indicate that the script is called by the script it points too. The blue arrows indicate that the styles/imagery are loaded by the script/stylesheet they point too. The purple arrows indicate that the particular data is loaded by the script it points too, while the green arrow indicates that the script writes to the data-item it points too.

Then there are coloured areas which tell whether how 'editable' the elements in it are. Red means that it's a core part of CosMoS and needs not be edited (though it's allowed of course, as CosMoS is GPLed), the blue indicates that you could edit these elements if you want a higher level of customization, the green indicates that you MUST edit these elements.

The Architecture of CosMoS

The first thing you should notice is that CosMoS has a very modular approach. CosMoS consists out of a core that in turn loads various modules. Modules can be either base modules or dynamic/optional modules. The base modules are always loaded, the dynamic/optional modules are only loaded when a page requests it.

Modules come in a set of three:

  1. mod_MODNAME.php - The actual module itself (mandatory). This contains the actual code, grouped in callback functions, for the module. Unless it is a base module, the module will only be loaded when required.
  2. mod_admin_MODNAME.php - The administrative module (optional). This contains callback functions for administration of this module. The module will only be loaded when required.
  3. mod_info_MODNAME.php - The info module (mandatory). This module registers tables and tags, and on the basis of that the core can decide whether or not to load the actual module itself or not. Unlike the actual modules, all info modules will always will be loaded by the core.

The base modules have to consist at least out of the following three, without these CosMoS can't function:

How CosMoS requests and delivers any content: stages, sections, pages and languages

There are four important factors in the delivery of any content. The first and most primary is called a stage. This happens to also be the most elusive one so we'll save this for last.

A section represents the navigation layout of your page. Each menu-item is a section. The section is represented by short ID (a string). Sections are ordered into a hierarchy of subsections/subsubsections etc.. Each section should at least have a corresponding page with the very same ID. In URLs a section is selected through s=SECTIONNAME, or in the shorthand notation simply by /SECTIONNAME

A page in CosMoS is respresented by a short ID (a string) that denotes the page which the user requests to load. A page can exist in multiple language versions, or one universal version. A page can also have associated settings and media. In URLs a page is selected through p=PAGENAME, or in the shorthand notation simply by /PAGENAME or SECTIONNAME/PAGENAME.

As there can be multiple language versions of a page, the lang argument is very important when we are not dealing with a universal page. The language is represented by the iso-639-1/3 language code. In URLs a particular language version of a page is seleted with lang=LANGUAGECODE , or in the shorthand notation simply by /PAGENAME.LANGUAGECODE or SECTIONNAME/PAGENAME.LANGUAGECODE.

Now back to the stages. The name stage is ambiguous, it can be seen as particular stage of the content rendering, or it can be seen as setting the stage upon which the actors will play out their game, this latter analogy is the most illustrative one. Note that only in very advanced sites you might have to add your own stages, normally they don't require any attention at all so you don't have to bother with stages or even know what they are.

The built-in stages are handled by the function renderstage() in core.php, which is always called from index.php. If you want to add your own stages, then index.php is the place to do so. Besides loading the core, it's actually the only thing that index.php does, it sets the stage for things to unfold, so to speak.

The default stage is called default. This is a composite stage which calls the include stage to render the header from styles/YOURSTYLE/header.inc, the page stage to render the requested page, and another include stage to render the footer from styles/YOURSTYLE/footer.inc. The include stage enables you to include any styles/YOURSTYLE/*.inc file, it takes the filename (without path and extension as argument: include:header is thus the full stage-name for including styles/YOURSTYLE/header.inc.

Other special predefined stages are admin, which loads the administration center, mod, which after outputting the header and footer passes control directly to a module, and raw, which passes all output control directly to the module and doesn't even render headers and footer, this can be used for rendering raw data, mod_log.php for example uses this to present RSS XML data.

Communicating with modules

A stage thus also determines the way in which the CosMoS core speaks to its modules, the following scheme may help illustrate the technicalities of this concept:

Serving modules: Three methods

Step 1: Installing the software

Uncompress the package in a location of your choice, accessible by the webserver. Then set the group permissions of all files and directories (recursively) to the group of your webserver (for example 'www-data' or 'apache'):

$ chgrp -R www-data *

Step 2: Configuring the software

Open conf.inc and edit it according to the instructions in it.

Step 3: Creating a simple Style

One most likely does not want to use the default CosMoS style for a website, but instead wants to make a new style for the website. In this section you'll be guided to set up a style of your own. You will need to know at least CSS and XHTML for this. You obviously also need to create any graphics you want to use in your style.

The available styles, just the default one at the moment, are found in the styles/ directory. It is suggested that you first copy or rename the style named cosmos to your own (we'll call it YOURSTYLE in this documentation), then adjust the 'style' directive in conf.inc accordingly. All files for your style are in styles/YOURSTYLE: imagery, stylesheets and include-files.

The 'default' stage calls two include-files, a header and a footer:

Advanced users can feel free to alter the stage in index.php to account for more includes.

Fire up your favorite text editor to edit these two files, you can add your xhtml and PHP code here. You can create divisions which you define in the main stylesheet: styles/YOURSTYLE/page.css. If you open a division in the header and close it later on in the footer, it will naturally span the contents of the site.

Editing these two includes and the page.css stylesheet should allow you to set up the global layout for your site. If you want to customize layout in all detail, you might want to edit the other stylesheets as well (each module has its own stylesheet).

Step 4: Create users, sections and pages

(See Documentation for Content Managers)

CosMoS Core API

Now we will present an overview of the CosMoS Core API.

$conf

This variable, an associative array, is globally available and contains configuration data, it is available for readonly use (writing is possible too, but might mess up the system if you don't know what you are doing). The data is set in the file conf.inc, which is heavily commented so for now check there for documentation.

$navdata

This variable, an associative array, is globally available and contains data for page navigation, it is available for readonly use (writing is possible too, but might mess up the system if you don't know what you are doing)

$userdata

This variable, an associative array, is globally available and contains user data, it is available for readonly use (writing is possible too, but might mess up the system if you don't know what you are doing)

getarg

Arguments: ($id, $fallback = '')

Retrieves a specific argument named $id from the server, first from POST, then from GET, then from SESSION, until it finds the specified argument. If none is found, then $fallback is returned.

setarg

Arguments: ($id, $value)

Sets an argument (GET/POST/SESSION) so later getarg() calls return the new value.

delarg

Arguments: ($id)

Deletes a set argument (GET/POST/SESSION) so it cannot be retrieved later.

href

Arguments: ($section [, $page [, $lang [, $args [, $stage [, $bookmark [, $urlonly = false ]]]]])
Returns: (xhtml) String

Creates a hyperlink to a particular internal page and returns this as the href="" attribute which you can then include in for example an A tag. Though, if $ulronly is set, only the URL will be returned.

Here a small example:

$s = "Go to the <a " . href('index','index','de') . ">German index page</a>"; 

selfhref

Arguments: ($args [, $bookmark [, $stage [, $urlonly = false ]]])
Returns: (xhtml) String

Creates a hyperlink back to the same page and stage (but with different argument perhaps) and returns this as the href="" attribute which you can then include in for example an A tag. Though, if $ulronly is set, only the URL will be returned.

(Note that for archaic reasons $bookmark and $stage are swapped with respect to the href function)

imgsrc

Arguments: ($filename [,$alt [,$width [, $height]]]])
Returns: (xhtml) String

Constructs the src and alt attributes of an image tag, based on the image you requests. Automatically checks for availability and displays an error if the image is not found!

beginform

Arguments: ($args [, $method = 'post'])
Returns: (xhtml) String

Begins a form, analogous to html's form tag, but this html element should never be used for creating forms within CosMoS (with the sole exception of forms that submit data externally, out of the CosMoS framework). $args is an associative array that you can use for setting various form properties, such as id, class and name. This will return a properly formatted HTML code of a form element. To close a form, always use the endform function.

Note that no action needs to be set, as an internal form will always point back to CosMoS.

endform

Arguments: ([$args [, $stage [, $jumpto ]]])
Returns: (xhtml) String

Ends a form that was previously started with the beginform function. $args is an associative array of various values you want to pass along, hidden input fields will be automatically generated for each key/value pair. $stage dictates what $stage to load, leave this to false if you don't mean to switch stages. $jumpto can contain a bookmark that will be jumped to (without the hash sign).

This function submits a form to exactly the same page as it was called from, which is most common. If you want to submit your form to a different (but still internal) page, then use endform_submitto:

A small example of a form, $s is string that can serve as return value of a callback function:

$s = "Fill in your name in the form below:";
$s .= beginform();
$s .= 'Name: <input type="name" value="proycon"/>';
$s .= '<input type="submit" />';
$s .= endform();

endform_submitto

Arguments: ($section, $page, [, $lang [$args [, $stage [, $jumpto ]]]])
Returns: (xhtml) String

Works like endform, but submits to a different page instead of the current one.

register_tag

See introduction to the module API

register_admin_tag

See introduction to the module API

require_module

See introduction to the module API

CosMoS Page API

outputpage

Arguments: ($section, $page [, $lang])
Returns: (xhtml) String

Outputs the requested page, with all tags resolved, into a string.

parse

Arguments: ($data)
Returns: (xhtml) String

Parses and resolves any CosMoS tags found in the data and returns the result as a string.

adminlink

Arguments: ([$text])
Returns: (xhtml) String

Insert a link to the administration center.

CosMoS User API

loginbox

Arguments: ()
Returns: (xhtml) String

Insert a loginbox which users can use to log in and out.

access

Argument: ([ $necessary_rights [,$sufficient_rights [,$forbidden_rights [,$user_whitelist [, $user_blacklist]]]]])
Returns: Boolean

Checks whether the current user has access based on the arguments to this function. Each argument is a string, which can consist out of a comma seperated list of various rights.

Access is determined as follows, in order:

CosMoS Module API

CosMoS modules consist of a set of callback functions, these functions are called by the CosMoS core.

As already mentioned, a CosMoS module does not come alone. It comes with an info module, and optionally with an administrative module. We will first take a look at the info module, mod_info_MODNAME.php.

Info modules merely call a set of registration functions. They register the name of the module, the tags the module will resolve, and can register tables for the Database Management System (DBMS). Here's an example:

1 $curmod = 'MODNAME'; 
2 register_admin_name($curmod,'My module name');
x register_tag('hello', false, $curmod,'resolvetag_hello',true); 
x register_tag('uppercase', true, $curmod,'resolvetag_uppercase'); 
x register_tag_alias('hello', 'hi'); 
x register_admin_tag('adminmymod', false, resolvetag_adminmymod); 
  1. The first line merely sets a variable so we don't have to type it over and over, it's the ID of the current module.
  2. The second line sets the name for this module, as it will show up in the menu of the Administration Center, if you omit this, there will be no item for this module in the Administration Center
  3. The third line registers a tag. The first argument is the name of the tag, always without the brackets. The 2nd argument tells whether it's a bi tag or not. This one is a mono-tag so it's set to false. The 3rd argument is simply the name of the module that will handle this tag, and the fourth argument is the callback function that will resolve this tag as desired. Then the last (optional) argument is a boolean that informs the system whether this tag is cacheable (defaults to false). This function will be defined in your actual module (NEVER IN THE INFO MODULE!). Though the "resolvetag_" prefix would be a good custom, you're entirely free to chose any function name you want.
  4. The fourth line also registers a tag. This is a bi-tag (one that has an open-tag and a close-tag, with content (in CosMoS: $buffer) in between.
  5. The fifth line merely defines an alias for our hello tag. We can use the tag 'hi' in the same way as the tag 'hello'
  6. The last line registers a tag as well, but this being an administrative tag. Such a tag only will be resolved when administrative privileges are present (unless you pass it an extra boolean 'false', which will set strict mode to false and allow anyone to resolve it). The resolve function of such a tag is generally in mod_admin_MODNAME.php, separating admin modules from normal modules, although there is no strict rule to do so.

The actual CosMoS module, mod_MODNAME.php, starts as follows, where MODNAME should be replaced with a short lowercase ID for the module:

1 require_cosmos('200701.20','MODNAME');
2 function mod_MODNAME_rev() return 1; //revision of this module
And optionally:
3 require_module(OTHERMODNAME);
  1. Line 1 dictates which version of CosMoS is required. Replace MODNAME with the name of your module. Always start with this, this ensures not only that a version mismatch occurs, but also offers security it prevents the module from being called directly, without the core (as the function require_cosmos is defined in the core)
  2. Line 2 reports the version revision number of the module itself, you should increment this number each time you update the module. Replace MODNAME with the name of your module
  3. Line 3 tells CosMoS that this module depends on another CosMoS module and that that module should thus be loaded

At this point, you should feel free to require/include any php scripts of your own (don't include other CosMoS modules directly though, use require_module() for that). You can also set constants or global variables if necessary.

Important to know is that all functionality comes from the callback functions. If you put code globally it will be executed each time the module is loaded, which is most likely not what you want. Another thing to keep in mind is that you should never directly output, print, "echo" or escape PHP mode. All output should be neatly returned as a string from one of the resolvetag_* callback functions you registered.

Note that an admin module isn't any different in setup. It too would start like:

1 require_cosmos('200701.20','admin_MODNAME');
2 function mod_admin_MODNAME_rev() return 1; //revision of this module

Now follows an overview of the various callback functions, each of them includes the module name which you should of course replace with your own unique name

Callback function: resolvetag_* (or any other name)

arguments:: ($cosmosid='',$attrs = false,$buffer = '')
returns: (xhtml) string

This is a callback function specified in register_tag. It will be called with these three arguments. The function should return an (xhtml) string.

The $attrs argument will be an array where the keys correspond to the various attributes mentioned in the tag, and where the array's values correspond to the attribute values.

As said before, $buffer will consist of the CosMoS-HTML code that was found by the parser between the start-tag and the end-tag, as such this variable will be empty in case of a mono-tag. This $buffer string is unresolved, it's up to you to do what it whatever you want. If you want the parser to continue to resolve any of it, then call parse($buffer), which will return a resolved string.

The argument we haven't discussed yet now is $cosmosid, this will usually be empty but can be populated by an ID that is attached directly to the tagname with a colon. This is a feature of CosMoS-HTML and is illegal in normal (x)HTML.

To make things a bit more illustrative, here's an example of a bi-tag (the one we defined in our info module) and how the parser will fill the arguments in your callback function:

<uppercase>Blah blah!</uppercase>

An example of how to handle this tag:

In the INFO module, we make sure we register it (the value true indicates that this is a bi-tag, as opposed to a mono tag):

register_tag('uppercase', true, $MODNAME,'resolvetag_uppercase'); 

And in the module itself, we implement it:

function resolvetag_uppercase($cosmosid='',$attrs = false,$buffer = '') {
   return strtoupper($buffer);
}

In this example, what would be outputted is, literally, 'BLAH BLAH!'. We have made a tag that ignores its cosmosid and arguments and simply renders its buffer to upper-case

Callback function: mod_MODNAME_rev (mandatory!)

arguments:: ()
returns: integer

This one you have already seen, it simply returns an integer that is the revision number of this module. It's mandatory for every module!

Callback function: init_MODNAME

Called directly when the module is loaded, before any rendering (including headers) is done. Do NEVER output anything at this stage

Callback function: prerender_MODNAME

Called directly before rendering a page

Callback function: postrender_MODNAME

Called directly after rendering a page

Callback function: deliver_MODNAME

Called at the very end of all processing (end of footer)

Callback function: mod_MODNAME

arguments:: ()
returns: string

This function is called when in the 'mod' stage, a very useful stage because it is not subserved through pages and tags, but is a direct call to the specified module, and only the specified module, to render content, which is returned in a string.

In shorturl notation, this is invoked like: http://mydomain/mysite/mod/MODNAME

Callback function: MODNAME_raw

arguments:: ()
returns: string

This function is called when in the 'raw' stage. It renders full output control to the module, the core doesn't output a single line (except when it has an error to report), so the module can manipulate even HTTP header information in this stage, which is for example very useful for presenting data in other mime-types than HTML. All content is returned in a string.

In shorturl notation, this is invoked like: http://mydomain/mysite/raw/MODNAME

Callback function: MODNAME_admin

arguments:: ()
returns: string

This function is called when in the 'admin' stage, that is when the module is selected from the administration center. The return value is to contain the content. Use this function to output whatever you want for the administration of this particular module. It will never be displayed by a non-administrator.

CosMoS Data Storage API

For most systems, data in CosMoS can be stored in two ways, either in cosmosdata-XML files, or in a Database Management System (of which only MySQL is currently supported).

"cosmosdata" is a generalized way of representing and storing data.

loadcosmosdata()

savecosmosdata()