CodeIgniter Forums

Full Version: Advanced Shard Loading v0.1 (modular seperation)
You're currently viewing a stripped down version of our content. View the full version with proper formatting.

El Forum

[eluser]Code Arachn!d[/eluser]
This morning I released some my take on modular separation. Zacharias has a great take on full blown modular separation - however it was a little more than what I was looking for on several projects... I didn't need to modularize the whole application which led me to building a library to handle loading shards and their related data models as needed. Since it doesn't rewrite large portions of the core it still uses the same functionality as you would starting out. However it allows for a more organized structure of individual modules (callouts) on a page.

It is still "beta" mode since some pieces are still being roughed in - but in it's present moment it works for the basic needs. At it's core it can load static shards (views) essentially a step above $this->load->file by adding custom pathing as well as access to specific data tailored by the model (think of it as file/view loading on steroids with tighter file organization).

TODO:
* add parsing for CSS and JavaScript
* add ability to separate CSS and JavaScript from render if desired.
* add organized manner for images to be added in
* add way for module helpers to be included.

USAGE:
Code:
$this->load->library('Module');
$this->module->render('module_name',true/false); // true/false for return/echo of the processed shard

Folder & File structure:
Code:
/application
   /modules
     /[module_name]
       |shard.php
       |config.php (optional)
       |model.php (optional)
       |[helper_name].php (coming soon)
       |[style_name].css (coming soon)
       |[script_name].js (coming soon)

Needed files:
* library
* language
* module (duh)

The library: (Module.php)
Code:
class Module {
    
    var $CI;
    var $module_prefix = 'module_';
    var $module_folder = 'modules';
    var $modules_loaded = array();

    function Module() {
        $this->CI =& get_instance();
        $this->CI->lang->load('module');
    }
    
    function set_config($load_module) {
    $file = APPPATH.$this->module_folder.'/'.$load_module.'/config'.EXT;
    if (file_exists($file)) {
      include($file);
      $this->module_prefix = (isset($config['module_prefix'])) ? $config['module_prefix'] : $this->module_prefix;
      $this->module_folder = (isset($config['module_folder'])) ? $config['module_folder'] : $this->module_folder;
      $this->CI->config->set_item($this->module_prefix.$load_module, $config);
    }
  }
  
  function set_model($load_module, $name = '', $db_conn = FALSE) {
        if ($this->isempty($load_module)) return;
        if ($this->isempty($name)) $name = $this->module_prefix.$load_module;
        if (in_array($name, $this->CI->load->_ci_models, TRUE)) return;

        if (isset($this->CI->load->$name)) {
            show_error('The model name you are loading is the name of a resource that is already being used: '.$name);
        }
    
        $load_module = strtolower($load_module);
        
        if ( ! file_exists(APPPATH.$this->module_folder.'/'.$load_module.'/model'.EXT)) {
            show_error('Unable to locate the model you have specified: '.$load_module);
        }
                
        if ($db_conn !== FALSE AND ! class_exists('CI_DB')) {
            if ($db_conn === TRUE) $db_conn = '';
            $this->CI->load->database($db_conn, FALSE, TRUE);
        }
    
        if ( ! class_exists('Model')) require_once(BASEPATH.'libraries/Model'.EXT);

        require_once(APPPATH.$this->module_folder.'/'.$load_module.'/model'.EXT);

        $load_module = ucfirst($this->module_prefix.$load_module);
                
        $this->CI->load->$name = new $load_module();
        $this->CI->load->$name->_assign_libraries();
        
        $this->CI->load->_ci_models[] = $name;    
  }

  function render($load_module, $method = TRUE) {
    if(!$this->isempty($load_module)) {
      if (file_exists(APPPATH.$this->module_folder.'/'.$load_module)) {
        if(!in_array($load_module, $this->modules_loaded)) {
          $this->set_config($load_module);
          $config = $this->CI->config->item($this->module_prefix.$load_module);
          $this->set_model($load_module,@$config['model_name']);
        }
        $this->modules_loaded[] = $load_module;
        if($method) {
          return $this->CI->load->_ci_load(array('path' => APPPATH.$this->module_folder.'/'.$load_module.'/shard'.EXT, 'vars' => $this->CI->load->_ci_object_to_array($this->CI->config->item($this->module_prefix.$load_module)), 'return' => TRUE));
        } else {
          echo $this->CI->load->_ci_load(array('path' => APPPATH.$this->module_folder.'/'.$load_module.'/shard'.EXT, 'vars' => $this->CI->load->_ci_object_to_array($this->CI->config->item($this->module_prefix.$load_module)), 'return' => TRUE));
        }
      } else {
        $err = $this->CI->lang->line('error_missing_module',$load_module);
        if($method) {
          return $err;
        } else {
          echo $err;
        }
      }
    } else {
      $err = $this->CI->lang->line('error_blank_module',$load_module);
      if($method) {
        return $err;
      } else {
        echo $err;
      }
    }
  }

    function isempty($var) {
      if (((is_null($var) || rtrim($var) == "") && $var !== false) || (is_array($var) && empty($var))) {
        return true;
      } else {
        return false;
      }
    }
    
}

Language: (module_lang.php)
Code:
$lang['error_missing_module'] = "Module %s has gone missing.";
$lang['error_blank_module'] = "You seem to be missing a module to load.";

enjoy

EDIT: fixed typo...

El Forum

[eluser]Phil Sturgeon[/eluser]
Spelling mistake!

Code:
$lang['error_blank_module'] = "You seep <- seem to be missing a module to load.";

Other than that, good stuff. Reminds me more of the way old Postnuke modules worked. Have a file for each and it knows exactly what ones to load. This is a very different take on modules to Zachs, but both have very good reasons for implementation. Good work!

For your asset management, why not take a look at the helper I made when I started using Zach's system, plainly called Asset Helper.

An example being:

Code:
image_asset('imagename.jpg', 'modulename', array('alt'=>'Image alt tag!'));

The folder structure would be:

Quote:assets/
-- images/
-- css/
-- js/
-- modules/
-- -- modulename/
-- -- -- images/
-- -- -- css/
-- -- -- js/

As you can see in the code the folder names are all hard-coded, but it would take about 30 seconds to add a config file if you wished to use this.

El Forum

[eluser]Code Arachn!d[/eluser]
Thanks for the catch - yeah working on code at 3am sometimes isn't good for the grammar ;D

I like how your asset manager works - I might snag some ideas from that.