CodeIgniter Forums

Full Version: Tendoo CMS : Module creation
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Hi, while tendoo cms 1.5 branch still in development, you can already create your own module. This is not a complete guide or tutorial about how to create a tendoo module, but we're not so far.
Now i'll show you have to create a "Hello World" module, so that you'll be able to improve it to do what you want.

1. Download tendoo CMS from Github and Install it

Since tendoo CMS is free, you can download it from Github. You can use Tendoo with WampServer, i have'nt already tested it on other server, but if online it's working (http://ci3.tendoo.org), i'm almost sure it will work everywhere.

2. Preparing module folder

For example, this plugin will be named "helloWorld", so we create a folder with the same name :

[Image: tutoriel-helloworld.png]

(I'm a french guy actually...  Big Grin )

Now we'll create a config.xml file inside that folder. And then open that config.xml file with your favorite IDE. Like any xml file add the header, like this :

Code:
<?xml version="1.0"?>
<application>
    <details>
        <namespace>helloworld</namespace>
        <version>1.1</version>
        <author>John Doe</author>
        <description>Sample Description</description>
        <main>helloworld.php</main>
        <name>Hello World Plugin</name>
    </details>
</application>

Here is how i can explain this code.

Every module details are written within "<application>" tag. There is actually 2 differents details supported "details" tag and "permissions" tag (no yet fully supported).

The details tag host :
  • module namespace : which should be lowcase, should no have any space and no even any special chars.
  • version: required if your module will have version, this will ease update.
  • description: talks about himself.
  • main: this is the relative path to the main file within the module dir, if the file is located at the root of your module, just write his name. for this tutorial, i have written "helloWorld.php".
  • name: this is the public name displayed on the dashboard, write it as you want.

3. Create your main file

now it' time to create your main file, as specified in the config.xml file. 

[Image: helloWorld-fichier.png]

now your module is ready...

4. Add dependency

your module require a specific libraries or model ? no problem. create a folder named "libraries" for you libraries files, "config" for your config file, "models" for your models files, "languages" for languages files. By this time, "controllers" folder is not supported since tendoo has this own way to create controller easily. 


Note: the files of thoses folders will be moved to their respective path within application path (APPPATH). So it would be easy for you to load it as you used with CodeIgniter. You can create unlimited folder, but unsupported folders and files will all be moved to the module folder.

[Image: folder-organisation.png]

So let add some models class to our project. I'll create a "helloWorld_model.php" file within "models" folder inside the module.


when it's done, let tell our module to load this file when tendoo is loading all modules. for this we'll use hook (not CodeIginter hook).


Note : Actually your main file should be a also be a class which extends "CI_model", like this.


PHP Code:
<?php 
class helloWorldClass extends CI_model
{
    function 
__construct()
    {
        
parent::__construct();
        
// Events    
        // load dependency        
        
$this->events->add_action'after_app_init' , array( $this 'after_session_starts' ) );        
    }
    function 
after_session_starts()
    {
        
$this->load->model'helloWorld_model' );
    }
}
new 
helloWorldClass
"after_app_init" is one of the main hook called for modules. It helps you load ressources to tendoo core, so that it will always be available every where. You can use this way to load your language files, your config files, your libraries and so on.

5. How to create a controller

As i told you earlier, tendoo has his own way to create controller which is actually very simple. But before, we'll create your module dashboard menu. We'll do it using a filter "admin_menus" like this.

PHP Code:
<?php 
class helloWorldClass extends CI_model
{
    function 
__construct()
    {
        
parent::__construct();
        
// Events    
        // change send administrator emails        
        
$this->events->add_action'after_app_init' , array( $this 'after_session_starts' ) );        
        
$this->events->add_filter'admin_menus' , array( $this 'menu' ) );        
    }
    function 
after_session_starts()
    {
        
$this->load->model'helloWorld_model' );
    }
    function 
menu$menus )
    {        
        
$menus'hellowolrd' ]        =    array(
            array(
                
'title'            =>        __'Hello World' ), // menu title
                
'icon'            =>        'fa fa-star'// menu icon
                
'href'            =>        site_url('dashboard/foo'// url to the page
            
)
        );    
        return 
$menus// return global menu array
    
}
}
new 
helloWorldClass

As you may see, using "admin_menus" filter, we'll extends global menu array, by adding our own menu. This menu is  a multidimensional array. So you can add multiple menus within this array. Each single menu item has at least 3 entry :
  • "title" : for your menu title,
  • "icon" : for your menu icon
  • "href" : for the url to the menu page
Now we'll create your module first controller using specific action hook "load_dashboard" like this :

PHP Code:
<?php 
class helloWorldClass extends CI_model
{
    function 
__construct()
    {
        
parent::__construct();
        
// Events    
        // change send administrator emails        
        
$this->events->add_action'after_app_init' , array( $this 'after_session_starts' ) );        
        
$this->events->add_filter'admin_menus' , array( $this 'menu' ) );
        
$this->events->add_action'load_dashboard' , array( $this 'dashboard' ) );     // load dashboard    
    
}
    function 
after_session_starts()
    {
        
$this->load->model'helloWorld_model' );
    }
    function 
menu$menus )
    {        
        
$menus'helloworld' ]        =    array(
            array(
                
'title'            =>        __'Hello World' ), // menu title
                
'icon'            =>        'fa fa-star'// menu icon
                
'href'            =>        site_url('dashboard/foo'// url to the page
            
)
        );    
        return 
$menus// return global menu array
    
}
    function 
dashboard()
    {
        
$this->gui->register_page'foo' , array( $this 'foo' ) ); 
 
               // will register a page with "foo" as slug reachable like this "http//example.com/index.php/dahsboard/foo
        
 
               $this->gui->register_page'bar' , array( $this 'bar' ) ); 
 
               // will register a page with "foo" as slug reachable like this "http//example.com/index.php/dahsboard/bar
    
}
}
new 
helloWorldClass

As you may see here, we're using "load_dashboard" action hook to register pages, using "GUI" library responsible of Dashboard UI management. "register_page" method save the method to call when registered page is loaded. 

Now the controller himself :

PHP Code:
// with your module main file (helloWorldClass)
function foo()
{
    
$this->load->view('../modules/helloworld/views/foo_view' );
}
function 
bar()
{
    
$this->load->view('../modules/helloworld/views/bar_view' );


This is one issue i'm facing, i'm trying to create a custom loader class to ease views loading. Untill that, load view will follow that structure, after "../modules/" you put your module namespace (that's where it's important to lowcase it). 

For this example, i have created a "views" folder within module folder (remember unsupported folders and files are moved to the module folder instead of the application folder "APPPATH"). There i have created "foo_view.php" file and "bar_view.php" file.

To ease integration with Tendoo dashboard, you must use GUI library (auto-loaded) within your view file like this (for foo_view.php).

PHP Code:
<?php
$this
->gui->output(); 

If you want to add custom HTML elements, here is how you will proceed.
Note: GUI library ease settings page creation, without having to use any HTML tag. Buy if you want to add your own html element, GUI library also have such method.

First define your page cols (like those on bootstrap), you can have up to 4 cols with 4 as maximum width. Beware, if you set 4 as width for each cols they will be overflowed, since each item width is multiplied per 3 so :
  • Col 1 width 1 as width will create a "col-lg-(3x1)" = col-lg-3
  • Col 2 width 2 as width will create a "col-lg-(3x2)" = col-lg-6
  • Col 3 width 3 as width will create a "col-lg-(3x3)" = col-lg-9
  • Col 4 width 4 as width will create a "col-lg-(3x4)" = col-lg-12
Here is how to define it within "foo_view.php", before "$this->gui->output();"

PHP Code:
<?php
$this
->gui->col_width); // for "col-lg-12"

$this->gui->output(); 

Each col can have unlimited meta boxes. Here is how to create it

PHP Code:
<?php
$this
->gui->col_width);

$this->gui->add_meta( array(
    
'namespace'        =>    'foo_namespace'// required
    
'title'            =>    __'Foo Meta box' ), // meta box title
    
'col_id'        =>    1// col id
    
'type'            =>    'box' // box type (all types : box, unwrapped)
) );

$this->gui->output(); 

As this code suggest, meta box namespace is required, you must also provide "col_id", which is the id you defined earlier using "col_width".
Now let's add a DOM item : 
PHP Code:
<?php
$this
->gui->add_item( array(
    
'type'            =>    'dom',
    
'content'        =>    '<h1>Hello World</h1>'
) , 'foo_namespace' ); 

This method accept 3 parameters : Array (item config), meta namespace, and col id.
You should specify a type for this item. In this example i used "dom", and then i provided a content to it. An easy way may suggest you to use ob_start() and ob_get_clean() to get PHP buffer. You can also load specific view file there like this :

PHP Code:
<?php
$this
->gui->add_item( array(
    
'type'            =>    'dom',
    
'content'        =>    $this->load->view('../helloWorld/views/bar_view.php' , array() , true )
) , 
'foo_namespace' ); 
Now Zip your module
[Image: zipmodule-helloworld.png]
Install it from tendoo dashboard at this location "dashboard/modules/install_zip".
[Image: upload-zip-file.png]
You can see now the module in action after having enabled it :
[Image: foo-page.png]
You're done. any questions ?

Sorry for my english mistakes, i'm a french guy Big Grin
I have attached the demo module down here... you can explore it... 

Thanks for readding this Wink
Hi Tendoo, looks good. Not had a chance to test it yet however I have some good news.

The error you posted when trying to install ignitedCMS on windows 8.1, I was unable to replicate with a fresh install of ignitedCMS and a fresh install of wamp 64bit.

Therefore this leads me to believe one of two things are causing you the error. I'm pretty certain it is a routing issue, or winrar has not unzipped the files properly as it is not finding the write_file controller. I would highly recommend using windows built in unzip utility over winrar. (Right click zip file and choose unzip)

However, I suspect it is a routing issue as I had this before. Can you please go to your www folder and remove any .htaccess files you have set up. As ignitedCMS doesn't require any .htaccess files I can only assume this is causing the issue, also check your apache .ini files and remove any redirects. If it was a write file permission it would have returned a 'not able to write file error message.'

Please let me know if this fixes the problem and sorry for hijacking your thread Wink