Codeigniter Theme Library
This post while relevant is a little out of date, check out the newest post
I'm a huge fan of Codeigniter. Like a lot of developers, I used to think that if I didn't write the code myself, it's not worth me using it - Codeigniter changed that for me. Codeigniter's got lots of strengths, but also quite a few weaknesses. In my opinion, its biggest weakness is the way views are ouput. If you want a header and footer on every page, you're going to struggle by default (as evidenced by the number of forum threads and questions in IRC).
There are multiple ways to do it, including using php_include for the header/footer files in your views using PHP. Some other options are to load the header view, then your content, then your footer view in each controller method. As you can imagine, this is a lot of code duplication, and would be difficult to update in future. The solution I used for a while was to create a container view that loaded the header and footer on either side of a variable $content. Then, in the controller I loaded the view I needed into $data['content'] by setting the third parameter to true, and passed it to my container view. Again, this was more duplication than I liked. I took it one step further and wrote a helper that took a view name and data as parameters, and loaded the container view like I needed.
This was alright for a while, but I soon thought of a better way to do it. As I needed to extend the base Controller to handle some authentication, I could load the header in MY_Controller's constructor. I could also use _output() in that class to load my footer. Perfect! All I needed to do was to load the view I wanted and it'd automatically be framed. I didn't get chance to try this method however, as I realised how rigid my layout would have to be to fit inside and decided to bite the bullet and write my own theme management class.
My class handles the loading of multiple partials, and they are all available right up until they are output to be edited or reordered. It's hard to explain in words, so here's an example:
(Assuming theme is autoloaded)
In the MY_Controller constructor:
$this->theme->registerHeader('layout/header');
$this->theme->registerFooter('layout/footer');
In MY_Controller _output():
echo $this->theme->outputPage();
Partials are registered in almost the same way, except the first parameter is the section identifier (set to enable manipulation later) e.g.
$this->theme->registerPartial($name, $viewFile, $data, $position, $nodeBeforeAfter);
In the test controller:
$data['key'] = 'val';
$this->theme->registerPartial('first_s', 'test_section_one');
$this->theme->registerPartial('third_s','test_section_three', $data);
$this->theme->registerPartial('second_s','test_section_two', '', 'before', 'third_s');
$this->theme->registerPartial('fourth_s','test_section_four', $data, 'after', 'second_s');
This would output the views: layout/header, then test_section_one, test_section_two, test_section_four test_section_three, layout_footer on the page in order.
This is just a very basic example of how it can be used. I've put the theme class on github for everyone to see + use. It still needs documenting, but it's not too hard to work out how to use it given the examples above.
Feel free to, and please do use/fork the library and improve it. If you make any changes, let me know and I'll pull them into the master so that everyone can benefit from them.
Related posts:
Nice new theme. Also, decent post. Now do one on wtf codeigniter is?
Very nice, will definately give it a try.
Suggestion: extend your library for Meta information, especially SEO stuff.
public function addMetaKeywords($meta = array()){$this->_assets['meta_keywords'][] = $meta["keywords"];
$this->_assets['meta_descriiption'][] = $meta["description"];
$this->_assets['meta_author'][] = $meta["author"];
}
I can see this being quite a helpful library, although the partial syntax is a little complex. It could do with a little more explanation I think.
Also my main issue with this is the name. This is nothing to do with “Themes”. A “Theme” is similar to a “Skin” which in my mind is more of a graphical variation over the top of a set collection of “Views” which together are a “Template” or “Layout”. A Theme library suggests a way in which you can easily switch the header/footer/view files/ etc which this doesn’t do.
They all appear very similar but mean very different things.
Either way, good code Mike, and thanks for the follow on GitHub.
@Jorix: Cheers. I’ll add in meta keywords for my next commit
@Phil: There’s some proper documentation and examples coming. I just wanted to get this out there and get some feedback. I see what you mean about it being a layout building library as opposed to a theme library. Something for me to consider when I’m working on the next version
I do like what you’ve done with this. The one issue that I see is that there is no easy way to set variables to be passed to the header view itself. I would suggest appending the function to allow custom variables.
I just wanted to do a quick follow-up with my last comment. My main issue with the custom variables was that I have dynamic menus that are inside of my header file. I realized that I could actually write menu items to the header file, but the problem is on the outputPage function, it replaces the entire data array with the assets array. I fixed this by simply making the assets array an item to the data array as so:
if ($name == 'header'){ $details['data']['assets'] = $this->_assets; }So now I can add my menus to my header. I’ll extend this so that I can add more, but that was my primary issue. (Sorry if the formatting on that is bad, I’m not sure what your site allows.)
Hey Donny,
I’ve been meaning to add data support to headers and footers for a while now. I’ll get to it sometime over the next day or two and push an update to github