Skeleton project

From CMC for PHP
Jump to: navigation, search

Installing the skeleton fileset

The skeleton which is available contains a typical files set. Here is the skeleton repository:

It contains:

  • cache/, a writable directory for holding session and caches files
  • js/cmc.js, the javascript part of the framework,
  • js/javascript-xpath.min.js, a javascript dependency, which allows xpath DOM selection in javascript
  • php/cmc.phar, the compressed version of the framework
  • php/config.php, main configuration items (main datadabase, default view, and many settings)
  • php/myApp.php, the file holding the main application classes (session and application implementation)
  • php/skelFrame.php, a demo frame implementation
  • index.php, the application/website entry point; this is the item related to the 'rewrite' rules
  • index.html, a default view

As the skeleton does not use a database connection this is the simplest program that can be done with the framework.

It shows the 4 levels of updating data: static, initial, dynamic and in an event throw Ajax (button click)

It can be tested by just uncompressing in a folder of the web server.

The skeleton display

The skeleton basically shows the differences between the "static updated", the "initial update", and "update" events. There is also a button action implementation.

Skel sc1b.jpg

Skeleton items

The view

see 'index.html' of the skeleton

<html data-cmc-id="skel">
<meta charset="UTF-8" />
<title>CMC Skeleton</title>

<!-- minimal for ajax: jquery+xpath+cmc -->
<script type="text/javascript" src="//"></script> 
<script src="js/javascript-xpath.min.js"></script>
<script type="text/javascript" src="//"></script> 

<script src="js/cmc.js"></script>

    <h1>Welcome to the CMC skeleton</h1>
    <div id="hellostat">html hello stat</div>
    <div id="helloworld">html hello</div>
    <div id="hellodyn">html hello dyn</div>
    <div id="helloclick"></div>    
    <input id="testbutton" type="button" value="Test button"></input>

Here we see just standard html. Just note that components have 'id' for each of them. We also have a identifier to bind the view to the appropriate frame of process (the controller):

data-cmc-id="skel": here it was on the 'html' main tag, but could be on a 'div' of the page. Putting it on the html main tag defines a global scope for the frame.

The other particular code are the javascript and css references. Those are required only if interaction is needed in the page. In this case the javascript/css requirements are:

  • jQuery, and jQueryUI css/javascript items
  • javascript-xpath: used by framework to access DOM items throw xpath expressions
  • cmc.js for the framework widget and ajax implementation (needs jQuery to work)

The frame

see 'php/skelFrame.php' in the skeleton


namespace cmcskel;

use cmc\ui\dynframe;
// used components
use cmc\ui\widgets\label,cmc\ui\widgets\button;

class skelFrame extends dynframe {

We have the components references (here label, button), and declaration of a 'dynframe' kind frame

widget definition

    protected $_widgetdef = array(
        'div_hello' => array(label::factory, 'helloworld'),
        'div_hellostat' => array(label::factory, 'hellostat'),        
        'div_hellodyn' => array(label::factory, 'hellodyn'),
        'div_helloclick' => array(label::factory, 'helloclick'),
        'bt_test' => array(button::factory, 'testbutton'),

Here we declare all static components of the frame. The key of the item array is the local name, whereas the first argument after factory class is the id value. Note that it can be an xpath expression here (designating one item). For example, 'div_hello' is the component name (like a local variable), and 'helloworld' is the id in the view.


    static public function getId() {
        return 'skel';

    public function getName() {
        return 'dynframe';

This is here that the frame is bound to the view. The static function is returning the identity of the frame; it will be instantiated only if the framework needs to work with a view that has a reference to that identity. This way the frame implementation can be cached-code (we will see also in the application file), but is instantiated on need.

frame events

The skeleton shows the most common frame events, and an implementation in each of them:

    // view is upon update, static part
    public function viewStaticUpdate($view) {
        $this->w('div_hellostat')->setHtml('Hello world from <b>static update; </b>date is: ' . date(DATE_RFC2822));
    public function viewInitialUpdate($view) {
        $this->w('div_hello')->setHtml('Hello world from <b>initial update; </b>date is: ' . date(DATE_RFC2822));
        $this->AddClickEvent('bt_test', array($this, 'click'));

    public function viewUpdate($view, $sess) {
        $this->w('div_hellodyn')->setHtml('Hello world from <b>update; </b>date is: ' . date(DATE_RFC2822));

It references a different label in each cache, and updates with the date, so the result speaks as itself: - viewStaticUpdate is the cached version of the view, common to every user.cache. - viewInitialUpdate is the first update for a user session. - viewUpdate is called each time the page is refreshed Depending on options (mainly if cached and/or session are enabled) the behaviors can vary.

See frame events, or the reference manual entries for each function: viewStaticUpdate, viewInitialUpdate, viewUpdate

component events

The skeleton shows the most common and simple event: a click handler. First the handler is defined in 'initialupdate' (for example), and a function handler is implemented:

    public function viewInitialUpdate($view) {
        $this->w('div_hello')->setHtml('Hello world from <b>initial update; </b>date is: ' . date(DATE_RFC2822));
        $this->AddClickEvent('bt_test', array($this, 'click'));
    /******* EVENTS ******/
    public function click() {
        $this->w('div_helloclick')->setHtml('Click on server '. $this->count.'; </b>date is: ' . date(DATE_RFC2822));

Note that the component is referenced by his 'local' name, and that we used a callback of our own class.

The application

see 'php/myApp.php' in the skeleton

if ($config=='prod') 

require_once 'skelFrame.php';       // a sample frame

class myApp extends app {

    private $_frameclasses = array(
         skelFrame::className,        // sample frame

    static function current($ClassName = __CLASS__) {
        return parent::current($ClassName);
    protected function getFrameClasses() {
        return array_merge(parent::getFrameClasses(), $this->_frameclasses);

The skeleton loads the compressed or the debug version of the framework depending on $config global variable (see #entry file#).

Then it includes all frame definitions, and reference it in the $_frameclasses variable. The protected function 'getFrameClasses' is used to pass it to the framework.

The entry file

see 'index.php' in the skeleton

/** check environment  **/
$doc = filter_input(INPUT_SERVER, 'DOCUMENT_ROOT');
$srv = filter_input(INPUT_SERVER, 'HTTP_HOST');

if ($doc) {
    if (preg_match('|^/homez\.|', $doc))
        $config = 'prod';   // ovh
    else if ($srv=='devtest2.home.lan')
        $config = 'test';    // serveur local test
    else $config = 'dev';     

if ($config == 'prod')
    ini_set('include_path', 'php:/usr/lib/pear');
    ini_set('include_path', '/var/www/devpt/cmc:php:/usr/lib/pear');

require_once 'php/myApp.php';

// application create instance
$myApp = myApp::current();
// run application

This is a sample on defining different configuration profiles depending on the document root or server. Then application is included, instantiated and 'run' (for current request).

The configuration file

see 'php/config.php' in the skeleton

The config.php file of the skeleton is showing how to add database and general options. See cmc\dftconfig for all available options.