Part of the EllisLab Network
   
1 of 3
1
Modulated Templated CMS system
Posted: 05 March 2008 01:02 PM   [ Ignore ]  
Lab Assistant
Avatar
RankRank
Total Posts:  209
Joined  09-07-2007

Here I will explain how to build a smarty templated modulated CMS.
please follow the instructions on this thread to setup your smarty templates system
http://codeigniter.com/forums/viewthread/60050/
also please see this thread for modules setup instructions:
http://codeigniter.com/forums/viewthread/73177
configure your routes.php file like this:

$route['default_controller'] = "default_controller";
$route['scaffolding_trigger'] = "";
$route['(.*)'] = 'default_controller/$1';

now create a controller called default_controller like so in your app/controllers directory:

<?php if (!defined('BASEPATH')) exit('No direct script access allowed');

class
Default_controller extends Controller
{
    
function Default_controller()
    
{
        parent
::Controller();
        
$this->load->library('smarty_parser');
        
$this->load->helper('modules');
        
$this->init();
    
}
    
var $method;
    var
$data=array();
    function
_remap($page, $content = '')
    
{
        modules
::load('search');
        
$data['page']=$page;
        switch (
$page)
        
{
            
case 'index':
            case
'home':
                    
$content = modules::run('home',$data,$this->method);
                break;
        case
'user':
            
$content = modules::run($page,'',$this->method);
        break;
            default:
                
//$content = modules::run('home');
                
show_404();
        
}        

        $this
->render($content);
    
}
    
function init()
    
{
        
if($this->uri->segment(2)!='')
        
{
            $this
->method=$this->uri->segment(2);
        
}
        
else
        
{
            $this
->method='index';
        
}
    }
    
    
function render($content)
    
{       
        $default_template
= array(
            
'template'=> $content
        
);
        
/*default_layout only contains this string <?=$template?>*/
        
$this->smarty_parser->parse("ci:default_layout",$default_template);
    
}
}

now create a view inside you app/views directory called default_layout.php like so:

<?=$template?>

 Signature 

smarty-hmvc-enviroment-variables

Profile
 
 
Posted: 05 March 2008 01:08 PM   [ Ignore ]   [ # 1 ]  
Lab Assistant
Avatar
RankRank
Total Posts:  209
Joined  09-07-2007

now for the fun part. copy over the modular_extentsions.php to your app/libs and modular_helper.php to app/helpers, make sure that your smarty templates folder is located inside app/views and inside the smarty folder create a folder default_template and templates inside the templates directory all your site templates will go, your structure should looks like this.

app/
      
views/
            
smarty/
                  
default_template/
                        
css/
                        
images/
                        
tpl_index.php
                        tpl_content
.php
                  templates
/
                        
dark/
                              
css/
                              
images/
                              
tpl_index.php
                              tpl_content
.php
                        light
/
                              
css/
                              
images/
                              
tpl_index.php
                              tpl_content
.php

for now the code will be loading the light template.

 Signature 

smarty-hmvc-enviroment-variables

Profile
 
 
Posted: 05 March 2008 01:15 PM   [ Ignore ]   [ # 2 ]  
Lab Assistant
Avatar
RankRank
Total Posts:  209
Joined  09-07-2007

now for the modules:
in your app/ directory make sute to have a directory named modules, this is where all your modules will go. Structure like this:

app/
      
modules/
            
home/
                  
controllers/
                  
models/
                  
modules/
                  
views/ <- you can statically link this in linux with ln -sf /full/path/to/smarty/templates views(your modules will then use them)

now inside app/modules/home/controllers/ or in app/modules/home/ create a file named home.php

$this->environ->template holds the path to the active template which is easy enough to figure out so I won’t go into details ex. smarty/templates/$template

<?php if (!defined('BASEPATH')) exit('No direct script access allowed');

class
Home extends Module
{
    
function Home()
    
{
        parent
::Module();
        
//modules::debug($this);
    
}
   
    
function index($data)
    
{
        $data
= array(
            
'breadcrumb_tpl'=>'ci:'.$this->environ->template.'tpl_breadcrumb'.EXT,
            
'content_tpl'=>'ci:'.$this->environ->template.'tpl_content'.EXT,
//load module located inside app/modules/home/modules/home_page/controllers/home_page.php
            
'content'=>modules::run('content',$data),
            
'footer'=>modules::run('footer'),$data)
        );

//since your using smarty to parse your templates after CI finishes you get to have the best of both worlds
        
return $this->render('ci:'.$this->environ->template.'tpl_index',$data);

    
}

    
function render($template,$data)
    
{       
        
return $this->smarty_parser->parse($template,$data,true);
    
}
}

 Signature 

smarty-hmvc-enviroment-variables

Profile
 
 
Posted: 05 March 2008 01:18 PM   [ Ignore ]   [ # 3 ]  
Lab Assistant
Avatar
RankRank
Total Posts:  209
Joined  09-07-2007

this way you can load modules within modules and have them either display there module/view or a template from the templates folder ditermined by the template environ variable. Enjoy. I’ve been waiting for something like this for a while myself. Any comments at all would be greatly appreciated.

 Signature 

smarty-hmvc-enviroment-variables

Profile
 
 
Posted: 05 March 2008 02:03 PM   [ Ignore ]   [ # 4 ]  
Lab Assistant
Avatar
RankRank
Total Posts:  209
Joined  09-07-2007

tpl_index.php will be located in app/views/smarty/templates/$template like so:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<
html xmlns="http://www.w3.org/1999/xhtml">
<
head>
<
meta http-equiv="content-type" content="text/html; charset=utf-8" />
<
meta name="keywords" content="{$meta}" />
<
link rel="shortcut icon" href="media/favicon.ico" type="image/ico" />
<
title>{$title}</title>
{foreach from=$theme_css item=theme}{$theme}{/foreach}
{foreach from
=$theme_js item=theme}{$theme}{/foreach}


</head>
<
body>
<
div id="container" >
        <
div id="headerWrap">
            <
div id="header">
            
{$site_name}
                
            
<ul>{foreach from=$main_menu item=menu}<li>{$menu}</li>{/foreach}</ul>
                
            </
div>
        </
div>
        <
div id="content">
            <
div id="contentHeader">
                <
div id="siteDescription">{$site_slogan}</div>
            </
div>
        
            <
div id="main">
                
{include file="$breadcrumb_tpl"}            
                         
                {include file
="$content_tpl"}    
                {$content}        
                
<br />
                
{$content2}
              
            
</div>
        
            
        </
div>
        <
div id="footer">
{$footer}
</div>
</
div>
</
body>
</
html>

 Signature 

smarty-hmvc-enviroment-variables

Profile
 
 
Posted: 07 March 2008 12:46 AM   [ Ignore ]   [ # 5 ]  
Lab Assistant
Avatar
RankRank
Total Posts:  209
Joined  09-07-2007

Any comments would be greatly appreciated

 Signature 

smarty-hmvc-enviroment-variables

Profile
 
 
Posted: 07 March 2008 02:41 AM   [ Ignore ]   [ # 6 ]  
Summer Student
Total Posts:  13
Joined  07-05-2007

On a quick glanze, this is what I have been planning to do myself but I bet not on this scale. I don’t have time to test it now but it sure looks promising. Thanks for your effort :D

Profile
 
 
Posted: 07 March 2008 04:59 AM   [ Ignore ]   [ # 7 ]  
Lab Assistant
Avatar
RankRank
Total Posts:  209
Joined  09-07-2007

no problem, let me know what you think once you test it

 Signature 

smarty-hmvc-enviroment-variables

Profile
 
 
Posted: 16 March 2008 11:07 AM   [ Ignore ]   [ # 8 ]  
Lab Assistant
RankRank
Total Posts:  164
Joined  04-03-2007
yingyes - 05 March 2008 01:15 PM

now for the modules:
in your app/ directory make sute to have a directory named modules, this is where all your modules will go. Structure like this:

app/
      
home/
            
controllers/
            
models/
            
modules/
            
views/ <- you can statically link this in linux with ln -sf /full/path/to/smarty/templates views(your modules will then use them)

now inside app/modules/home/controllers/ or in app/modules/home/ create a file named home.php

Is this directory correct? (app/modules/home/controllers/) Or did you mean app/home/modules/controllers/

I’m trying to get the basic understanding of using HMVC from your tutorial here, although I haven’t used smarty, so I’m trying to get the point without smarty involved.

I also tried looking at the InkType blog setup, but that server is down so I didn’t get far with that one.  I think another good reference example may have been to use bambooinvoice.org.  A common ‘hello world’ example would be beneficial for all user extensions.

Profile
 
 
Posted: 16 March 2008 06:51 PM   [ Ignore ]   [ # 9 ]  
Lab Assistant
Avatar
RankRank
Total Posts:  209
Joined  09-07-2007

@a&w;- yes your modules will be located inside the app/modules/ directory like this:

app/
      
modules/
            
module1/
                  
config/
                  
controllers/
                  
helpers/
                  
language/
                  
libraries/
                  
methods/
                  
models/
                  
modules/ /*only if you want sibling modules*/
                  
views/
            
module2/
                  
controllers/
                        
module2.php
                  models
/
                        
module2_model.php
                  views
/
                        
module2_view.php

module one is just how I’ve decided to implement my home(main) module that is mapped to in your default controller

function _remap()
    
{
        modules
::load('search');

        
$module = $this->uri->segment(1) OR $module = 'home';
        
$method = $this->uri->segment(2) OR $method = 'index';

        
$this->data=$this->lang->language;//sets my language variables, autoloaded

        
$this->data['current_page']=$module; //used inside my modules

    
$this->data['current_action']=$method; //used inside my modules
//if you want to load modules into views? from here you can
    //$this->data['header']=modules::run('header',$this->data,'index');//I don't do this from my default controller
        
if(modules::exists($module,$module)!=NULL)//I've modified modules_helper.php to include a exists() method
        
{
            $content
= ($module=='admin')?modules::run($module, $this->data, $method):modules::run($module, $this->data, 'index');  
        
}
        
else
        
{
            redirect
('');
        
}
        
        $this
->render($content);
}

and a render method inside default_controller.php

function render($content)
    
{       

        
//This calls the active template index page
        
$default_template = array(
            
'template'=> $content//$this->smarty_parser->parse('ci:'.$this->template.'/index',$content,true)
        
);
        
/*contains only <?=$template?>*/
        
$this->smarty_parser->parse("ci:default_layout",$default_template);
    
}

exists method inside modules_helper.php version 4.0.19
makes it so that if a module doesn’t exist it will redirect to default module and will not show
this line from modules_helper.php

show_error("Unable to locate the requested file: ".$path2file);

function exists($file, $path = '', $base = 'controllers/')
    
{
        $file
.= strpos($file, '.') ? '' : EXT;
        
        if ((
$pos = strrpos($file, '/')) !== FALSE)
        
{
            $path  
= substr($file, 0, $pos);
            
$file  = substr($file, $pos + 1);
        
}
        
        $path
.= '/';
        
        
$path2file = $path.$base.$file;
        
        
$paths2scan = array(MODBASE.$path.$base, MODBASE.$path, MODBASE.$base, MODBASE);
        
        if (!
in_array($base, array('controllers/', 'libraries/', 'methods/')))
        
{
            $paths2scan
= array_merge($paths2scan, array(APPPATH.$base, APPPATH.$base.$path));
        
}
          
        
foreach ($paths2scan as $path2)
        
{                
            
foreach (array($file, ucfirst($file)) as $name)
            
{
                
if (is_file($path2.$name))
                {
                    
return TRUE;
                
}
            }
        }
        
return FALSE; // I don't understand why it returns NULL even though I have this set
    
}

default_controller.php doesn’t have to be so overweight from the bulk of the data being passes in teh views. I use a custom library to do this, which just loads all the options inside the data array upon initialization and then just array_merge that array into your data array inside default_controller.php :) You could load the content into a view instead of a smarty template system just as easy by changing your render method to do this. I’ve added an exists method because I could see a way without one inside modules_helper.php all it is, is just a modified version of the path_to() method. The reason why I use smarty is because it makes my views look much cleaner. So if I am not good at design but Iknow how to do this then a designer can take a gander at the views without knowing how to code. Any more questions are welcome. I gives me more ideas, hope this helps someone.

 Signature 

smarty-hmvc-enviroment-variables

Profile
 
 
Posted: 16 March 2008 08:05 PM   [ Ignore ]   [ # 10 ]  
Lab Assistant
RankRank
Total Posts:  164
Joined  04-03-2007

Thanks.  I’m getting a better picture now.  Thanks for elaborating so well.  Please note, that I think in Post#2 your directory structure is different, hence my seeking clarification on the structure.  Your ‘home’ folder is not inside ‘modules’.

I had not even considered nesting the modules folder, where you’ve shown it being a child folder.  Interesting.  Not sure when it would ever come to practice, but good to know.

What is the difference between modules::load and modules::run?  A cursory look at the code looks like run also loads the module passed.

With reference to the line below, do you check if data[’current_action’] isset in your index method of the controller then?

$this->data['current_action']=$method; //used inside my modules

This next part is probably application specific, nonetheless, anything interesting to note with the following snippet?

$content = ($module=='admin')?modules::run($module, $this->data, $method):modules::run($module, $this->data, 'index');  
        
}
        
else
        
{
            redirect
('');
        
}

I didn’t quite follow you when you say you use a custom library to load all the options inside the data array upon initialization and then just array_merge.  I’m a bit rusty on CI (took a sabatical for a few months learning javascript), but I thought when libraries were loaded, CI automatically checked for a similarly named config file.  Seems like there would be a way befitting of the “CI way” to have the modules check for a config file and to load that.  So when a module is loaded, go ahead and load the config array associated with it.  Not sure if that would connect to the module, or maybe one of the views.

Profile
 
 
   
1 of 3
1
 
Post Marker Legend
New Topic New posts Hot Topic Hot Topic with new posts New Poll New Poll Moved Topic Moved Topic Sticky Topic Sticky topic
Old Topic No new posts Hot Old Topic Hot Topic with no new posts Old Poll Old Poll Closed Topic Closed Topic Announcement Announcements
Theme
Change Theme
Visitor Statistics
The most visitors ever was 719, on June 06, 2008 10:16 AM
Total Registered Members: 61048 Total Logged-in Users: 14
Total Topics: 73849 Total Anonymous Users: 0
Total Replies: 398354 Total Guests: 288
Total Posts: 472203    
Members ( View Memberlist )
Active Members:    BrammeCrucialDark PreacherDyaGaesraJoostVmahutimatthinckleymironchonarutophantom-athurtingWeblizardwiredesignz