• 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Modulated Templated CMS system

#1
[eluser]Avatar[/eluser]
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://ellislab.com/forums/viewthread/60050/
also please see this thread for modules setup instructions:
http://ellislab.com/forums/viewthread/73177
configure your routes.php file like this:
Code:
$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:
Code:
<?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:
Code:
<?=$template?>

#2
[eluser]Avatar[/eluser]
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.
Code:
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.

#3
[eluser]Avatar[/eluser]
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:
Code:
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
Code:
&lt;?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);
    }
}

#4
[eluser]Avatar[/eluser]
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.

#5
[eluser]Avatar[/eluser]
tpl_index.php will be located in app/views/smarty/templates/$template like so:

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


&lt;/head&gt;
&lt;body&gt;
<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>
&lt;/body&gt;
&lt;/html&gt;

#6
[eluser]Avatar[/eluser]
Any comments would be greatly appreciated

#7
[eluser]Varzock[/eluser]
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 Big Grin

#8
[eluser]Avatar[/eluser]
no problem, let me know what you think once you test it

#9
[eluser]a&w[/eluser]
[quote author="yingyes" date="1204762557"]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:
Code:
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
[/quote]

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.

#10
[eluser]Avatar[/eluser]
@a&w;- yes your modules will be located inside the app/modules/ directory like this:
Code:
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
Code:
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
Code:
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 &lt;?=$template?&gt;*/
        $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
Code:
show_error("Unable to locate the requested file: ".$path2file);
Code:
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.


Digg   Delicious   Reddit   Facebook   Twitter   StumbleUpon  


Users browsing this thread:
1 Guest(s)


  Theme © 2014 iAndrew  
Powered By MyBB, © 2002-2018 MyBB Group.