PyroCMS Module

PyroCMS Module

README

This is how to create a PyroCMS module (at least in the current version available 2.1.4). PyroCMS is one of the most powerfull CMS in the web, nor Wordpress nor Joomla count in the list because no one of them have a framework below their codes; in first place Wordpress is a functional/procedural project where we write functions and return values to get data in/out the database, and in second place Joomla just has an API (very extensive and heavy to learn in one life); I don’t like these CMS systems (and many others) not because they haven’t a framework behind them, but because they haven’t and standard/structure to develop new features.

I use CodeIgniter as my favorite framework to develop web-applications because:

  • It use MVC (Model - View - Controller) standard;
  • It is lightweight (very lightweight) not only in the total file size of the package but in the final payload of a project, basically because it doesn’t load unnecessary resources which won’t be used in a web-view;
  • It has a good Cache system, it doesn’t extraordinary but there is an utility in it to use Memcached or APC to improve the performance of our projects;
  • Very good and super-understandable configuration files which let us override all of them with a simple code from any Controller;
  • It let us create multiple applications like Symfony to separate the Back-end and the Front-end;
  • Basic but very useful libraries like Security, Unit testing, Session, Cart system, File handling, Input, Form and Validations, Email, Image manipulation, File compression, RPC and many others;
  • Count with a very good routing system which accept regular expressions to work properly;
  • It let us use a Parser library to create templates like a designer (works with pseudo-tags to handling data);
  • Accept multiple environments to separate the development/stage/production states of the project;
  • It has hooks, a very-very useful feature to change/override/add functionality to the core without hacking the code of the framework;
  • CodeIgniter has a very good support from the Elislab developer team creators of the project Expression Engine;
  • And finally, but not less important, CodeIgniter has a very similar structure to the Ruby on Rails framework; so we could have Ruby and PHP code stored in similar locations :D

Explanation

Create a module for PyroCMS it’s to very easy, just create a folder with the name of the new module (in lowercase and try to use one word to avoid problems) in one of these paths:

  • System: system/cms/modules, the module will be identified as part of the Core of the CMS, we generally couldn’t uninstall these type of modules only disable because there are more dependencies in the code of other modules.
  • Site module: addons/default/modules, the modules located in the site folder will be only visible in the administration panel of that site; this is generally used by the professional edition of the PyroCMS Pro package.
  • Shared addons: addons/shared_addons/modules, the modules located in this folder will be accessible for all the users and viewers if we configure a front-end interface.

I will use this name cixtor to call my new module and will create the folder in the _sharedaddons directory; then I will generate the folder structure of the module (not all of them will be used in this post, but you can request a full explanation if it’s necessary) creating various directories:

$ mkdir addons/shared_addons/modules/cixtor
$ cd addons/shared_addons/modules/cixtor
$ mkdir {config,controllers,css,img,js,helpers,language,libraries,models,views}
$ touch {details,plugin}.php

Now I need to fill the content of the file details.php with the information required by PyroCMS to install the new module in the CMS; this is a basic example of a configuration for this file:

// details.php
defined('BASEPATH') or exit('No direct script access allowed');
class Module_Cixtor extends Module {
    public $version = 1.0;
    public function info(){
        return array(
            'name'=>array(
                'en'=>'Cixtor module',
                'fr'=>'Cixtor module',
                'es'=>'Cixtor module'
            ),
            'description'=>array(
                'en'=>'This is just a simple module for testing in PyroCMS.',
                'fr'=>'Cet un module pour essayer en PyroCMS.',
                'es'=>'Este es simplemente un modulo de prueba.'
            ),
            'frontend'=>true,
            'backend'=>true,
            'menu'=>'content'
        );
    }
    public function install(){ return true; }
    public function uninstall(){ return false; }
    public function upgrade($old_version){ return true; }
}

We can use the method Module_\App\Models\Cixtor::install() to create tables and the Module_\App\Models\Cixtor::uninstall() method to drop them; this is an example of how look an install/uninstall sentence:

...
public function install(){
    $tables = array(
        'table_name'=>array(
            'id'=>array('type'=>'INT', 'constraint'=>11, 'auto_increment'=>true, 'primary'=>true),
            'title'=>array('type'=>'VARCHAR', 'constraint'=>255, 'default'=>''),
            'content'=>array('type'=>'TEXT'),
            'created_on'=>array('type'=>'DATETIME'),
            'updated_on'=>array('type'=>'DATETIME')
        ),
    );
    if( !$this->install_tables($tables)){
        return false;
    }
    return true;
}
public function uninstall(){
    return $this->dbforge->drop_table('contact_log');
}
...

After that, I need to create a file called equally to the module with extension PHP in the Controllers folder, this file will be the front-end controller of this module, at the same time I will create the back-end controller used in the administration interface:

$ pwd
/home/cixtor/public_html/addons/shared_addons/modules/cixtor
$ touch controllers/{admin,cixtor}.php
// controllers/cixtor.php
defined('BASEPATH') OR exit('No direct script access allowed');
class Cixtor extends Public_Controller{
    public function __construct(){
        parent::__construct();
        $this->load->model('cixtor_m');
        $this->load->model('blog_m');
        $this->load->library('cixtor_lib');
        $this->load->helper(array( 'form', 'url', 'cixtor' ));
    }
    public function index(){
        $this->template->set('variable_name', 'variable_value');
        $this->template->build('frontend/default');
    }
}

The administrator controller of the module should be always have the name Admin and extends from the Admin_Controller

// controllers/admin.php
defined('BASEPATH') OR exit('No direct script access allowed');
class Admin extends Admin_Controller{
    public function __construct(){
        parent::__construct();
        $this->load->model('cixtor_m');
        $this->load->library('cixtor_lib');
        $this->load->helper(array( 'form', 'url', 'cixtor' ));
    }
    public function index(){
        $this->template->set('variable_name', 'variable_value');
        $this->template->build('backend/default');
    }
}

In this case I created two views called default but in different folders:

$ mkdir views/{front,back}end
$ touch {front,back}end/default.php

That is basically that you need to get started with a new module in PyroCMS, accessing in my case to the path http://www.cixtor.com/cixtor/index will appear the content of the view frontend/default, but if you want to load by default this module on-load your project you’ll need to change the value of the parameter default_controller in the file routes.php located in this path: system/cms/config/routes.php

Do you have a project idea? Let's make it together!