Adding Layout support like RubyOnRails into CodeIgniter :: By Hooking

28 thoughts on “Adding Layout support like RubyOnRails into CodeIgniter :: By Hooking”

  1. nice! but what if you have 100 controllers and only need one layout? In your system you have to have 100 layouts. right?

  2. By tweaking the hook it coult be done. Make the following line linking to a fixed file

    $layout = “system/application/layouts/{$controller}.php”;

  3. This is very nice. I’m trying to figure out if you could specify a layout among a few different ones, like public.php, admin.php, etc. If you make a $type variable in the controller is there any way to access it in the hooks file?

  4. Thanks for the code… helped me understand hooks. I made the following modifications (also changed some class/method/variable names) to allow for more rails like behavior and respond to Jorge and Matt. You can define $layout anywhere in a controller or add it in the class definition… you could also extend CI’s Controller class. If the requested layout isn’t found, the hook rolls to a default layout. For my code to work, all layouts must be .php and live in /views/layouts/ (both easily changed).

    THE HOOK:

    output->get_output();

    if (!preg_match(‘/(.+).php$/’, $CI->layout)){
    $CI->layout .= ‘.php’;
    }

    if ($CI->layout)
    {
    $requested = BASEPATH . ‘application/views/layouts/’ . $CI->layout;
    $default = BASEPATH . ‘application/views/layouts/default.php’;

    if (file_exists($requested))
    {
    $layout = $CI->load->file($requested, true);
    $view = str_replace(“{yield}”, $output, $layout);
    }
    else
    {
    $layout = $CI->load->file($default, true);
    $view = str_replace(“{yield}”, $output, $layout);
    }
    }
    else
    {
    $view = $output;
    }

    echo $view;
    }
    }

    ?>

    SAMPLE CONTROLLER:

  5. sorry… forgot to strip the php tags…

    THE HOOK:

    if (!defined(‘BASEPATH’)) exit(‘No direct script access allowed’);

    class Yield
    {
    function doYield()
    {
    $CI =& get_instance();
    $output = $CI->output->get_output();

    if (!preg_match(‘/(.+).php$/’, $CI->layout)){
    $CI->layout .= ‘.php’;
    }

    if ($CI->layout)
    {
    $requested = BASEPATH . ‘application/views/layouts/’ . $CI->layout;
    $default = BASEPATH . ‘application/views/layouts/default.php’;

    if (file_exists($requested))
    {
    $layout = $CI->load->file($requested, true);
    $view = str_replace(“{yield}”, $output, $layout);
    }
    else
    {
    $layout = $CI->load->file($default, true);
    $view = str_replace(“{yield}”, $output, $layout);
    }
    }
    else
    {
    $view = $output;
    }

    echo $view;
    }
    }

    SAMPLE CONTROLLER:

    class Test extends Controller
    {
    public $layout = ‘test’;

    function index()
    {
    echo ‘hello’;
    }
    }

  6. Correction to the code:

    Using the ‘OUT’ global replaces some standard variables like {elapsed_time} etc..
    $OUT->_display( $view );

    Also improved some if statements etc.

    ——-

    function doYield()
    {
    global $application_folder, $OUT;

    $CI =& get_instance();
    $output = $CI->output->get_output();

    if ( isset( $CI->layout ) )
    {
    $app_folder = $application_folder;

    if ( !preg_match( ‘/(.+).php$/’, $CI->layout ) )
    {
    $CI->layout .= ‘.php’;
    }

    $requested = BASEPATH . $app_folder . ‘/views/layouts/’ . $CI->layout;
    $default = BASEPATH . $app_folder . ‘/views/layouts/default.php’;

    if (file_exists($requested))
    {
    $layout = $CI->load->file($requested, true);
    $view = str_replace( “{yield}”, $output, $layout );
    }
    else
    {
    $layout = $CI->load->file($default, true);
    $view = str_replace( “{yield}”, $output, $layout);
    }
    }
    else
    {
    $view = $output;
    }
    $OUT->_display( $view );
    }

  7. Hi man,

    Thanx for the hook, it will make my life easier… but perhaps in future make a note to warn people about copying the code from your blog…. those curly quotes cause hell:)

    1. constantly Posted on It’s a joyful day to be able to read an ailcrte that is so clearly researching and written. I love very much enjoyed this information content. Your layout is excellent. I will come back again.

  8. Traditionally, layouts/ would be located as a subdirectory of /views/, but that’s just me being picky. Thanks very much for this hook, it’s made my life much easier! It’s nice having frameworks like CI to use in parallel to developing on RoR.

  9. Great job, guys! And great framework for letting you inject something like layouts with such an ease…

    Worked like a charm 🙂

  10. Easy…

    $data[‘title’] = ‘Hi there!!’;

    $data[‘content’] = $this->load->view(‘myFolder/myView’,$data, TRUE);

    $this->load->view(‘layouts/myLayout’,$data);

    works!! 😉

  11. “nice! but what if you have 100 controllers and only need one layout? In your system you have to have 100 layouts. right?”

    You could change the function to check if a layout file for that controller exists and if not then fall back to a default layout file. If all else fails, just load the view on its own. This is a little more flexible, allowing you to define a layout only for the controllers that you want to differ from the default layout.

    //////////////////////////////////////////////////

    $ci =& get_instance();
    $current_output = $ci->output->get_output();
    $controller = $ci->uri->segment(1);
    $layouts_folder = “layouts”;
    $default_layout_file = “default”;

    if(file_exists(APPPATH.$layouts_folder.’/’.$controller.EXT))
    {
    $output = $ci->load->file(APPPATH.$layouts_folder.’/’.$controller.EXT, TRUE);
    }
    elseif(file_exists(APPPATH.$layouts_folder.’/’.$default_layout_file.EXT))
    {
    $output = $ci->load->file(APPPATH.$layouts_folder.’/’.$default_layout_file.EXT, TRUE);
    }
    else
    {
    $output = NULL;
    }

    echo $the_output = str_replace(“{yield}”, $current_output, $output);

    //////////////////////////////////////////////////

    @hasin: Thanks for sharing this solution, I think it’s one of the simplest and most effective I’ve seen for CodeIgniter. 🙂

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s