CI How-to: Load global data in a view across all controllers

One the first issues I encountered with CodeIgniter was that I wanted to be able to use the same dynamic data in my header view across all controllers. And, I didn't want to repeat myself in each controller to load the model data that needed to be persistent site wide. For example, see the twitter feed in the header? I didn't want to have to do something like this in each method of every controller.

// *** inside the blog controller

function index() {
    $data['twitter'] = $this->twitter->get_twitter_status();

    return $this->load->view('entry_list', $data);
}

function entry() {
    $data['twitter'] = $this->twitter->get_twitter_status();

    return $this->load->view('entry_detail', $data);
}

// *** inside the about controller

function index() {
    $data['twitter'] = $this->twitter->get_twitter_status();

    return $this->load->view('about', $data);
}

// *** etc...

There is too much repetition here, so let's streamline the process. Start by creating a file in ./system/application/libraries/MY_Controller.php. When you prefix it with "MY_", CI will automatically load the file because it thinks you want to extend the base class. We do. Win.

class MY_Controller extends Controller {
    var $global_data = array();

    function MY_Controller() {
        parent::Controller();

        $this->load->model('Twitter_model', 'twitter');
        $this->global_data['twitter'] = $this->twitter->get_twitter_status();

        // other common stuff; for example you may want a global cart, login/logout, etc.
    }

    // create a simple wrapper for the CI load->view() method
    // but first, merge the global and local data into one array
    function display_view($view, $local_data = array()) {
        $data = array_merge($this->global_data, $local_data);

        return $this->load->view($view, $data);
    }
}

Now in your controllers, extend MY_Controller instead of Controller. And in your controller methods, instead of calling $this->load->view(), call the wrapper function.

class Blog extends MY_Controller {
    function Blog() {
        parent::MY_Controller();
    }

    function index() {
        $data['will_it_blend'] = "Yes, it will blend.";

        // ... do stuff ...

        $this->display_view("entry_list", $data);
    }
}

The "entry_list" view in this example will have both the global $twitter and the local $will_it_blend data variables set. While trolling the CodeIgniter forums, I also came across Template Library for CodeIgniter which looks to be even more über. But I think it might be overkill for what I'm after today.

CodeIgniter to the rescue?

For the last several weeks, our development team at Rare Bird has been evaluating a PHP framework called CodeIgniter. First, some background. We've been hand-rolling sites using a home-brewed PHP framework I first cobbled together over 10 years ago. Over the past 10 years it has seen it's share of evolution and has served us well. However, as we add more staff, each new developer comes with new ideas and habits. It's getting more difficult to educate each on doing it my way when my way is full of strange nuances, and concepts that were great in 2001, but not so great not now.

The time has come to push the restart button and we have a couple of options. We can home-brew something new. I'm sure we could do this, but why? PHP frameworks like Zend, CakePHP and CodeIgniter are readily available and have active communities. My goal is to find something similar to what we're already used to, and see if we can make it work for us.

On the surface, CodeIgniter fit the bill. It has high performance, a small footprint, and allows us to code in an unrestrictive way. (I should interject that we're an Apple shop, and software bloat is not welcome.) We're also a bunch of guys that have been brought up in different programming eras. I like procedural programming in certain cases, and I don't have a problem writing raw SQL — I actually prefer it.

So we're going to see how it goes with CodeIgniter. My first project? This very blog. I did stumble along the way, and you can read more about that in the next post.

A new blog for a brave new world

Astute observers might notice something different. No, it's not that we have a new President-elect. Give up? It's a new blog with 21st century features such as commenting and RSS feeds. I know a lot of our readers aren't technophiles, so I'll keep it simple. If you read or see something you like, you can leave us a message directly on the web site. And, if you use a news aggregator such as Google Reader, you can add our RSS feed. Don't worry, the photographs are still the main focus, and I'll continue to update them frequently.

So what's the big deal about these new features? The old blog was a one-page static web site that I cobbled together over a weekend several years ago. It was cumbersome to update, didn't encourage feedback, and wasn't very user- or internet-friendly. Our development team at Rare Bird is evaluating a new programming framework, so I thought reworking the family blog would be a great opportunity for me to kick the tires of the new software as well as reap some benefit for doing so. I plan to use my corner of the site to blog about the experience from a technical standpoint without adding cruft to the family posts.