WordIgniter, WordPress + CodeIgniter

This post has been up for a while and I think it’s time to make this note. The comments of this post have taken on a life of their own in terms of information. This means that the comments are just as, or nearly more important than the post itself. Please, read through the comments before giving anything a try or commenting yourself.

Thank you.

Recently I’ve been trying to solve a problem that I’m sure has encountered before: how to combine two rather large PHP applications running and based on different frameworks. These applications being WordPress and CodeIgniter. Before any comments, suggestions, or questions arise about why anyone would want to do this in the first place, don’t bother. This isn’t a post answering the why, it is solely about answering the how.

The first thing to tackle is the question of which framework to use as the master. In other words, which framework should load the other within itself. Most people might think CodeIgniter, because it is a basic framework used to create any web application, and it should certainly be ok to load WordPress. This is all true, but I do not want to lose WordPress’ core functionality, that being what is called “The Query”. When you bootstrap WordPress into another framework, you are losing all of the automation it does when parsing a request into the “The Query”. Nobody should want that, so lets look at another option, bootstrapping CodeIgniter into WordPress. This is the route I chose to take which allows for the least amount of code, the most automation from both platforms, and still uses CodeIgniter in such way that my blog specific views can be integrated with the code I have already written for the rest of my site.

Now where to start in WordPress? The answer is in one of two places, either a WordPress plugin or theme. If you know WordPress inside and out, then you may skip most of this, and go your own way. I chose the theme route because I can be assured that all plugins have been loaded, and the WordPress core is primed and ready. Within WordPress templates load after all the core actions and before any output is returned to the browser. What we should be going for is the most minimalist theme we can, which still requires three files:

  • style.css
  • functions.php
  • index.php

All need to be located within our WordPress theme’s directory located somewhere like this…
/blog/wp-content/themes/codeigniter-bootstrap-theme

I will not review the style.css file here. There are plenty of tutorials about how to create a WordPress theme. Here is a quick summary: provide the required info necessary for a WordPress theme wthin this file’s comment header.

I will review the next item listed, the functions.php file. It is very important because it is the only part of any WordPress theme that is loaded around the same time a plugin, essentially making themes a type of plugin themselves. Within this file we must put in the following code to start the process of bootstrapping CodeIgniter:

<?php // This file is required to define a WordPress theme, Don't do anything in here you don't have to
function codeigniter_bootstrap() {
	require_once( 'index.php' );
}
// Add the action before any templates load, but after all other WordPress system actions run
add_action( 'template_redirect', 'codeigniter_bootstrap' );
?>

The outcome of that code is a global WordPress template redirect to the index.php file within our theme, for all WordPress requests. This is necessary for three reasons:

  1. We want CodeIgniter to handle all views, not WordPress
  2. WordPress themes require at least one template by the name of index.php (contrary to popular belief)
  3. CodeIgniter MUST be bootstrapped from within a script file, NOT from a function

Once that code is in place, and we have an empty index.php file within our theme, we should activate our theme now. You should see a blank page for every request to your WordPress client-side view, and your WordPress admin should still remain perfectly functional.

Next, the contents of the index.php file:

<?php // This file is required to define a WordPress theme, DON'T DO ANYTHING IN HERE!!!!
$_GET['/blog/'] = null;
end($_GET);
require_once( dirname( ABSPATH ) . '/index.php' );
?>

This may look weird to most developers, but let me explain. CodeIgniter by default requires a webserver override, or in most cases an apache .htaccess file to redirect all requests to the CodeIgniter bootstrap. This bootstrap then parses the requested URI by any means available to the server’s version of PHP. When using something like an .htaccess file, like the one provided by CodeIgniter’s user guide you will notice the line:

RewriteRule ^(.*)$ index.php?/$1 [L]

This basically takes the string following your rewrite base and appends it to the URI’s search parameters. This means that for an example request URI of …
http://mydomain.com/rewritebase/controller/action/
This actually appears to CodeIgniter as…
http://mydomain.com/rewritebase/index.php?/controller/action/

How CodeIgniter actually grabs this data is very simple. First it checks for any entries within the $_GET super global. If found, it grabs the first entry using the PHP array iterator function of key($GET). This returns the key of the current iteration within the array, which is what CodeIgniter assumes is exactly what it needs to parse.

That all being said, I hope these lines make more sense to you:

$_GET['/blog/'] = null;
end($_GET);

I am entering a manual entry into the super global with $_GET['/blog/'], which is the actual part of the URI I want CodeIgniter to parse into the respective controller and action. The next line of end($_GET), ensures that CodeIgniter will retrieve the correct key using the key() function.

All of these lines of course are subject to change within your own environment, but the next one especially:

require_once( dirname( ABSPATH ) . '/index.php' );

At this point I am loading the CodeIgniter bootstrap manually. It happens to be within my document root, which is one directory above my WordPress installation. This is why I know I can rely on the call of dirname( ABSPATH ), but this may change depending on your own setup. Just be sure that the file you are looking for is the CodeIgniter bootstrap. You shouldn’t need anything else.

With all of the previous setup in place, there are a couple more things to do within WordPress to make things work smoothly. These include WordPress’ usage of permalinks. If you wish to use custom permalinks, be sure to set these up within the WordPress admin, as well as putting another .htaccess file within the root of the WordPress installation. If you wish to use the default setting for WordPress permalinks (just query strings), you need to enable query strings within your CodeIgniter config.

Now you should see a default CodeIgniter 404 page when viewing any WordPress response. If you do, you know the bootstrap is working correctly, if you do not, go back over the steps to see if you missed something.

The error page is most likely the result of calling a controller that doesn’t exist within your CodeIgniter application. For my example, I forced CodeIgniter to load “/blog/”, therefore I need a controller by the name of “blog”. My default controller for CodeIgniter is set to “home” in my config, this may also be different for your setup, but for this one I needed to define a controller here, /system/application/controllers/blog/home.php. Of course along with the class, you need your standard index() method for the default controller action. I like using the subdirectory route for this controller particularly because WordPress can get massive pretty fast, better safe than messy. Then I setup a corresponding view here /system/application/views/blog/home.php.

Now you may notice that everything seems to be working except for one thing, all of your WordPress views point to one view, and you have lost that bit of automation that WordPress does for you. Don’t panic yet, we just have to pull a little WordPress logic into our controller. This logic is within the WordPress file of wp-includes/template-loader.php. If you have never seen or looked at this file, you may be surprised. All of that beautiful automation is just one big if conditional statement, yuck! Well… whether or not it is pretty, it does its job, and we want to do the same from within CodeIgniter. So what I am showing you here, is my interpretation of the logic from within that file, translated within the index() method of my blog controller:

function index() {
	$this->load->view('common/header' );

	// The following is similar to WordPress's template-loader.php - Use that as reference for this logic
	// Notice the mixture of WordPress API with the CodeIgniter API

	// Start template-loader
	if ( is_robots() ) {
		do_action('do_robots');
		return;
	} else if ( is_feed() ) {
		do_feed();
		return;
	} else if ( is_trackback() ) {
		include(ABSPATH . 'wp-trackback.php');
		return;
	} else if ( is_404() ) {
		// show Code Igniter 404
		show_404();
		// OR load a view
		// $this->load->view('404' );
	} else if ( is_search() ) {
		$this->load->view('blog/search' );
	} else if ( is_tax() ) {
		$this->load->view('blog/taxonomy' );
	} else if ( is_home() ) {
		$this->load->view('blog/index' );
	} else if ( is_attachment() ) {
		remove_filter('the_content', 'prepend_attachment');
		$this->load->view('blog/attachment' );
	} else if ( is_single() ) {
		$this->load->view('blog/single' );
	} else if ( is_page() ) {
		$this->load->view('blog/page' );
	} else if ( is_category() ) {
		$this->load->view('blog/category' );
	} else if ( is_tag() ) {
		$this->load->view('blog/tag' );
	} else if ( is_author() ) {
		$this->load->view('blog/author' );
	} else if ( is_date() ) {
		$this->load->view('blog/date' );
	} else if ( is_archive() ) {
		$this->load->view('blog/archive' );
	} else if ( is_comments_popup() ) {
		$this->load->view('blog/comments_popup' );
	} else if ( is_paged() ) {
		$this->load->view('blog/paged' );
	} else {
		$this->load->view('blog/index' );
	}
	// End template-loader

	$this->load->view('common/footer' );
}

From the code above, you may have noticed the views look a lot like a normal WordPress theme. This is intentional so we may still feel comfortable in our habits while using both frameworks simultaneously. The difference is, now we are loading the views from a CodeIgniter controller, we have full control of the MVC pattern from within WordPress, we don’t have to rewrite any views for two frameworks, and we have access to the full API of each framework equally.

The end.


Posted

in

, ,

by

Tags:

Comments

50 responses to “WordIgniter, WordPress + CodeIgniter”

  1. Richard Lee Avatar

    Nice… and Thanks this is really awesome I have been searching for ever for a good solution! This is just in time for me. Does this apply to having wordpress in your root? and putting codeigniter in a sub folder.

    Basically WordPress is my site and all my pages are set up on that as a cms. I just want to pull in some functionality from codeigniter in order to manipulate a separate database and pull results (profile summaries linking to profiles) from that database via a search box and display them to users on search results pages that will be a wordpress template page… I will essentially be passing data through the get method to a template page that I would be using some codeigniter functions on. Then I will also try to create a plugin that allows the user / admin to manage the data from the wp dashboard also utilizing some codeigniter functionality to manipulate that data and make it viewable to the admin.

    Would the solution above suite me for this or do you think wordpress has enough functionality that I wouldn't need to have to integrate code igniter. I am very familiar with wordpress but I didn't think that it alone could handle this type of functionality.

    1. jimisaacs Avatar

      Richard, thank you for the comment, let me try to explain as well as I can from just reading your summary there.

      First off this post is really targeting people who want to use CodeIgniter to the full extent of it's ability with controllers and views while still using WordPress as well. Full itnegration, without loosing any functionality of either one. Essentially this method could possibly turn WordPress into a back-end, and sends all front-end requests to a pseudo CodeIgniter URI.

      What you are describing does not necessarily need CodeIgniter. If you are comfortable in WordPress, my suggestion is to stay there for this. You can do this a number of ways of course. My further suggestion on this is that since you are planning to create a plugin anyway, just make everything self contained within that plugin. You can make a call to another database with WordPress if you create a new instance of the class "wpdb", ex: new wpdb(). I would study that class if you haven't already, it is based on the old ez-sql class from a long time ago. It is just a connection manager, that with every new instance, these represent either the same, or completely new connections to different databases. It is actually pretty similar to CodeIgniter's Active Record, just more old-school.

      If you simply don't want to write anything new, you have a choice. Use the WordPress codebase, or the CodeIgniter codebase. The method I described in this post doesn't necessarily mean how to do this on a case by case basis. Again, it is just to use CodeIgniter as a whole, while leaving WordPress as a whole. How to pull what you need from the CodeIgniter codebase can be as simple as putting as many require_once's as you need for what you need.

      That's the big difference with WordPress when compared to other regular frameworks. WordPress pre-loads everything in what they like to call "The Core" for you. It is a major debate within the WordPress community how to change this.

      On the other side is CodeIgniter, which is on-demand, use as you need it. So if you need it in WordPress, you are still good to go. Yes there are some core classes and files within CodeIgniter as well, but this is only to use it to it's full potential, which is managing URI routes within an MVC architecture. Even still this this core is very small, a total of like 6-10 files. Everything else provided which is something like 20-30 files are optional library files to load on-demand how ever you decide to build you CodeIgniter application.

      Conclusion, I don't think you need CodeIgniter. If you are comfortable with something, I don't a see a problem in using it. Eventually, in a fantastical future, WordPress will take on a more CodeIgniter-like codebase anyway. When that day comes, we will rejoice. Until then, happy hacking 😉

  2. programmer Avatar
    programmer

    Hi, I am currently working on a website and most of its contents are dynamic. I'm currently using CodeIgniter as a framework and has finished some modules already. I decided to use WordPress for the blog. The problem I'm having right now is that the blog pages should also display some dynamic content that will be generated by functions/methods from one of my models in CodeIgniter. Is this possible? How?

  3. jimisaacs Avatar

    Well, based on your description there, I think this post pretty much described what you could do to get what you want working. I'm not sure how you will be integrating WordPress, or to what level. This post is simply one of the options.

  4. Chris Avatar

    This is really useful – I am planning on building some simple apps on top of WordPress, but using CI as the "theme". WordPress gives you so much in terms of plugins, sheer number of users and good admin interface – but rewriting URLs to correspond to templates in the theme is messy as. Thanks for the writeup.

  5. Chris Avatar

    For others info – I got the URLs to work as normal ( CI takes all the arguments from whatever URL you use ) by changing the URI Protocol setting in /application/config/config.php to $config['uri_protocol']= "REQUEST_URI";

    This means you can now pass any arguments to your controllers and methods, while having full access to all the WordPress functions and variables.

    1. Bryan Avatar

      I'm trying to make heads or tails out of this, and so far so good, except i am not passing the requests properly it would seem.

      I set everything up the way it is listed in this tutorial. I have a sub subdirectory of wordpress, and CI in my main root dir. Once I activate my application, it is loading my default controller, which I have called main. This is good. But when I click one of my links to go to another controller, it just keeps reloading the main controller. I turned on profilign to see what's happening, and it doesn't seem to be getting the url properly and passing it into codeigniter.

      I tried changing my config to REQUEST_URI but this just generates 404 errors for every method I have defined.

      Outside the WordPress theme, the app functions normally. There's just something I am missing here with passing the uri string back to codeigniter. I've been reviewing this post and the comments, but I haven't figured it out yet. I'm fairly new to CI so I might just be missing something small. *re reads again*

  6. Bizim Oyun Sitesi Avatar

    Great and easy follow solution , thanks . I will try this.

  7. Shiro Avatar
    Shiro

    Hi, and thanks for this solution.
    I actually did almost the samething with WordPress and CI, the thing is your solution is much more better than mine, mine need to hack the WP code, and make it manually set get the controller, and each of the controller I need to create a page for it. This is one of the problem that I facing, because WordPress couldn't understand the URI, but from your solution I find what I want, thanks a lot! really appreciate that.

    But one of my main concern for this is the performance, because loading 2 frameworks really a heavy stuff ongoing… u have any idea make the improvement?

    1. jimisaacs Avatar
      jimisaacs

      Performance wise this shouldn't be much of a problem if you build your application correctly. CodeIgniter has a very small foot print at the bootstrap level. Even still you should always cache. In this respect caching output, will save on the amount of PHP processing. There are also so many ways to increase PHP performance at the compiler level, this isn't much of an issue anymore. As long as you steer clear of using eval(), using these performance enhancers should be relatively ok. (Caching is still always good)

      1. Shiro Avatar
        Shiro

        Ok, Thank you for your fast reply.
        I tried your way create a wordpress with codeigniter theme.

        How did you handle the URI, do you have to create every page first in wordpress?
        For example, Contact Us.
        http://localhost/wordpress/contact_us
        when I type this it auto redirect to 404, I know I didn't create the page. How did u solve it.

        My "always" problem is, After I create a page in local development environment, like create a page (Contact Us), and I done the coding part, I upload my code to live version, but I always forget create the page in live version. then when ppl want to access for that page go to 404. This is one of the limitation by using this approach.

        I can't sync the database is because the live version always got comment and pages created by other. How did u resolve this situation.

        1. jimisaacs Avatar
          jimisaacs

          I'm sorry, I can't follow you after you get into the live not live pages. What I will try to tell you how to handle is the URIs and how I am handling them. Well first and foremost what you have to remember is that the reason you did this is because you didn't want to rewrite in CodeIgniter everything WordPress can do already. All you are trying to do is, clean up the parts of WordPress that you don't mind rewriting, particularly the template loading. In the post I mentioned the file in WordPress called "template-loader.php". Then I mentioned mimicking this logic in this file, in your controller's method. Now I'd like to mention a slightly different way to do this, that actually lets CodeIgniter feel more like CodeIgniter.

          That is putting the logic inside your routes.php file. That's right, using all the WordPress conditionals to build a big if statement like in "template-loader.php", and in that if statement you are routing to particular controllers and methods regardless if they exist. If they don't exist you'll just get a 404, if they do exists it will find them. That is the point of CodeIgniter!

          Anyway, this should actually make your controller feel a lot better that you aren't looking at all that messy logic. Kind of similar to the way a WordPress theme feels better too. Sorry, this doesn't mean it isn't there, and you don't have to worry about it, but being in the routes file means it really is where it is supposed to be. Also don't worry about using WordPress conditionals, they work, and work well.

          1. Shiro Avatar
            Shiro

            Hi, sorry for my bad English. What means is if I didn't create post/page in wordpress wp-admin, it will automatic go to is_404, because when I enter the URI, wordpress first thing is check the db first, is that id/post_name exist. I do understand what you mean by routing it. However, if you didn't create the post/page first in wp-admin how can the wordpress regconize it and route it?

            Is it possible share your theme source code how you edit the theme? I think from there I can have more understanding, and check what is the different from mine and your.

            What I mean from the live not live page is basically the post/page I created in development machine, definitely in live I haven't created. For example, contact us, this post I had created in my development environment, and I create the coding for handle this page. However, when I upload the source code file to live version. and I forgot to create the post/page. WordPress will show 404 (page not found) for contact us. This is the problem of my current development. Hope you can understand more from what I explanation here.

          2. jimisaacs Avatar

            Ok, I think I may have what you are asking, but just making sure.

            You want CodeIgniter to be able to fall back on controllers and methods that may not be in WordPress DB?

            So if you have "system/application/controllers/testing" and then "system/application/controllers/blog/blah" there is no interference there. http://host.com/testing/ then falls back to the codeigniter controller even though a page by the name of "testing" is not in the db.

            Is this what you mean?

          3. Shiro Avatar
            Shiro

            yup. This is what I means. Your solution if you didn't create the page/post name "testing", does it able to call codeigniter that "testing" controller?

            My problem is if the "testing" page didn't create, it will go to route to 404.

            Sorry for troubling you, and thank you for your reply 🙂

          4. jimisaacs Avatar

            Have you tried this yet? If you put everything in as you described then it should work…

            Don't look at my big if statement as set in stone, play around with it to get what you want.

            For the one I posted here, I am showing a CodeIgniter 404 error for everything WordPress sees as a 404 with is_404()

            Try to see what you need a build your routes file with the if statements as necessary.

            There are many ways to work with conditionals, just play around until you get what you need. Think of the WP conditionals as a way of checking the DB, while codeigniter is left to everything else.

            I hope I could be of some use, I can't really show you my theme I am using this for because it is actually for a private client. Let me know what you can work out.

  8. Shiro Avatar
    Shiro

    thanks for your reply. If you can only show a plant wordpress with plant codeigniter (perhape example.com) this kind of sample, and the changes you have meet to make both working as your blog description then that is more than enough.

    I tried the way , if I didn't create the "testing" post, it will go to 404, and not go to testing controller. because what I understand for the wordpress is (do correct me if I am wrong)

    user key in URI -> response to webserver -> wordpress will get $_GET-> get the id / postname (depend the permalink) from the db-> after that go to template-loader.php / index.php (that you create) -> Codeigniter

    so as you can see, wordpress will get to the db first rather than go to templater loader, if I didn't create the post/page, it automatic will go to 404. I just wonder how you bypass the wordpress database checking that part.

  9. jimisaacs Avatar

    I think I just realized something that I never updated in the post. If you want to receive information for CodeIgniter to get the correct URI information you need to do one of 2 things before bootstrapping CodeIgniter. The first and more easy method is using Chris's method posted above in these comments. That is to change the CodeIgniter uri_protocol to use REQUEST_URI explicitly. This way CodeIgniter will always see the current URI without you setting it.

    Doing things the manual way which is what this post described, you need to do a little URI parsing. Then send that to CodeIgniter.
    In the post my example showed this $_GET['/blog/'] = 1;
    What you need is something like this $_GET[$uri_pathname] = 1;

    Get this pathname by parsing the REQUEST_URI, or one of the many WordPress URI helper functions. Check the link-template.php in wp-includes for more info. There are also a lot of filters you could go after such as 'home_url'. Then within the filter callback, edit the $_GET superglobal like I mentioned before, and remove the filter all in one shot. Not sure if this will do you any good unless you just call the function anyway. But a lot of those filters already have the information parsed for you, that's the only reason I mentioned it.

    Once CodeIgniter is getting the right URLs just make your controllers as necessary. If you still want to handle all WordPress URLs from one controller, just make sure you route it correctly in CodeIgniter to do so. This is where that WordPress conditional comes in handy.

    if( !is_404() ) $route[''] = 'wordpress_controller'; // if WordPress sees something, use this controller, else let it go through.

    1. Shiro Avatar
      Shiro

      wow! Thank you so much for your answer. I roughly get the idea already! I totally didn't think about is_404(), this link wake me up directly :p
      I still very new in wordpress, I am trying to work hard get understand for it!
      Jimisaacs you are the man! Thanks~

  10. subbu Avatar
    subbu

    @jimisaacs,

    Real nice post. Firstly I m almost a newbie in PHP. Most of the time I have developed applications on J2EE and .Net. This was really what I was looking out for a long time now. I was planning to build a personal website and wanted to use the powerful MVC, WP for its excellent theming, plug-ins and CMS admin features. One thing I understand from the post is that with the above changes (Please correct me if I m wrong)
    – we can re-direct all calls to wordpress into a CI controller.
    – perform a process and forward it directly to a view that either wordpress can handle or a CI view which would get embedded into current WP theme layout.

    Now, coming to my question – I wanted to load my application specific views if the url pattern was something like / or /app and blog specific information if it was /blog. Please help me out how would I achieve this.

    1. jimisaacs Avatar
      jimisaacs

      Thanks for the compliments. Based on your question, I want to point out the difference of doing something like this, versus completely merging both codebases into one central location, which is what a lot of other examples on the web explain how to do. The difference is that your WordPress install and your CodeIgniter system can essentially be anywhere you want them to be on your server. What this explains is how to bootstrap in CodeIgniter manually rather than from a request.

      So what you are talking about with having your application in one place and blog in another is exactly what I was demonstrating with passing pseudo URLs to the $_GET before bootstrapping CodeIgniter. This means what ever you pass CodeIgniter is what it thinks it needs to serve. As for WordPress you can put it where ever you want, it just needs to load the CodeIgniter bootstrap from where ever it is located.

      Please read through the comment thread for more ideas, especially the one from @Chris, and my last comment to @Shiro

  11. lance Avatar
    lance

    Jim – Thanks for taking the time to write this up. Ever since I learned codeigniter (recently) I've been obsessed to finding a way to create a site in codeigniter that's powered with a wordpress backend ( w/o losing the 'the query' ).

    I've been over this procedure for 2 nights now (and apologize for my amateur status) and am still having a problem understanding exactly what
    2$_GET['/blog/'] = null;
    3end($_GET);
    does in your setup. Does the above code replace the need for the standard .htaccess file found on CI's website?

    Lastly, is it possible for me to put wordpress in my root directory and bootstrap ci from another locaction? Forgive my newbness in the following explanation. Want i'm wanting is to put wordpress in the root directory of http://www.example.com (not http://www.example.com/blog). I feel wordpress has come a long way as a nearly complete CMS (with hacking) and I like to use wordpress to control each page (by adding pages in the admin screen) including my home page. However I've discovered CI and am pushing to code more MVC strictly and would like to install CI and have it control ALL my views like in your above example. Plus I like CI for database interactivity (with the help of Doctrine) and it's helpers like url, form, html, etc.

    Is this possible. I guess the opposite of what you've done so I can create everypage in wordpress, and then write the template code in codeigniter instead of writing index.php/single.php/page.php etc in my wordpres theme folder?

    1. jimisaacs Avatar
      jimisaacs

      The original post doesn't take into account passing anything useful from WordPress to CodeIgniter. In the post it was expecting you to have to use WordPress conditionals to make a kind of 'mock' routing setup similar to WordPress but instead within a CodeIgniter controller. Please read through the comments between myself and @Shiro for more information on what I mean, and especially look at the comment from @Chris in utilizing CodeIgniter's configuration for how it parses the URI of the current request. Those lines you mentioned in the post, as well as the comment example I gave @Shiro have to do with manually 'feeding' CodeIgniter a request. So in that sense no, you don't need .htaccess anymore.

      In the post, it was for an implementation of CodeIgniter AND WordPress handling requests separately and WordPress simply using CodeIgniter views for a theme. So in regards to this, in my setup I had CodeIgniter in the root with .htaccess, WordPress in /blog also with .htaccess, and WordPress using the type of theme described pulling in CodeIgniter views. This type of setup could also work vice versa, with WordPress in the root with .htaccess, and CI in /somedirectory with .htaccess, and everything else remaining the same as described before.

      In your question of wether you can use WordPress in the root, the answer is yes! Of course! This actually makes things a lot simpler. Let's say you have WordPress in the root, and you want CodeIgniter to handle the theme. You could put all of the CI codebase actually in the theme, and rename the CI bootstrap of 'index.php' to 'functions.php'. Then change the CI config to use the REQUEST_URI or some other flavor of URI parsing, and have at it. With CI as a theme, and WordPress using .htaccess on the root, there is not need for any other .htaccess files. If you can't get any of the CI config URI parsing flavors to work for some weird server configuration reason, then you can refer back to this post for manually feeding CI what it needs. That is where those lines of code you mentioned come back into play again.

      Most people don't know that in PHP Super Globals can be modified during the duration of the script, even though this practice is well documented on php.net. This is what I am doing here, I am modifying the $_GET Super Global adding a key of the URI pathname (relative to the base URI set within CodeIgniter), and then reseting the array's internal pointer to be at the end. The reason this works is because if CodeIgniter finds a key in the $_GET array, it uses the current position of the pointer with key(). So it actually does something along these lines:
      $pathname = key($_GET);

      So if you simply modify the $_GET array just before loading the CI bootstrap you can tell CI what to load.

      To continue in this implementation, you must be a aware that there are some conflicts with WordPress functions and CI helpers. WordPress functions are not all wrapped with functions_exists() conditionals, while all CI helpers are. This means it won't cause a fatal error, but it will just mean a CI helper function in conflict with a WordPress function will always be overwritten by the WordPress function.

      If you do decide to put CodeIgniter in as a WordPress theme, keep in mind the CI codebase isn't required to be there. You just have to load the bootstrap from where ever it is located on your server.

      1. lance Avatar
        lance

        Thanks Jim, and wow that was a speedy response. I've been unsuccessful so far, but I'll be keeping at it and let you know that it has worked.

  12. Sanjay Avatar
    Sanjay

    Thank you Jim. I have been looking for a clean solution for a bit of time, and this really clean and elegant. I managed to get it working in 15 minutes. Bless you!

  13. safwan Avatar

    Hi.. thanx for this excellent tutorial… now in the controller blog.php I have added a function
    function logged()
    {
    echo 'hi';

    }

    But i can't access it… index function is loading great… how can i access another function?other controllers etc…
    This url works fine… http://localhost/wordigniter/
    but how do i access the function logged()?
    i tried
    http://localhost/wordigniter/blog/logged
    http://localhost/wordigniter/index.php/blog/logged
    http://localhost/wordigniter/logged
    None of it worked. Is it with the config file?
    I have set the $config['base_url'] to the wordpress root that is http://localhost/wordigniter
    I just can't understand where is things wrong

    1. jimisaacs Avatar
      jimisaacs

      @safwan, Please read through the comments of this post, because the most likely the answer you are looking for is there.

    2. magic Avatar
      magic

      try creating a new controller file and calling it logged and access through link below
      http://localhost/wordigniter/blog/index.php/blog/logged

      I've still got problems with re-write rules as I am trying to run it on windoze will give a try on unix
      later to see if It gets sorted out.

  14. Joris Witteman Avatar

    Forgive me if I'm posting too fast, but to me your choice seems fundamentally flawed.

    "When you bootstrap WordPress into another framework, you are losing all of the automation it does when parsing a request into the “The Query”."

    Why? Why couldn't you make whatever The Query consists of (a global object of sorts?) work within CodeIgniter? Surely you could put it into a SuperController , then in $this->Data, then pass it to the view?

    To me, a CodeIgniter installation sitting in a theme is nothing like a WordIgniter I'd be looking for. It's a theme with a jailed CodeIgniter in it.

  15. jimisaacs Avatar
    jimisaacs

    I don't mean to sound rude because I appreciate comments, but based on your comment, I don't think you read the post.

  16. […] Ok! I got CodeIgniter and WordPress more or less integrated. Maybe an unholy marriage, but at the moment I think it’s very cool. This got me started: https://jidd.jimisaacs.com/archives/892/ […]

  17. Todd Avatar

    Just implementing this right now, and I like it so far.

    However, I did have a small problem, and I was wondering how you got around it.

    If you have the WP files in /blog, and the app/system files above the root (../), you can't set the paths in CIs index.php to ../, because then it doesn't work from the /blog (because you're including it one dir above than normal, so it needs ../../).

    I had to use $_SERVER['DOCUMENT_ROOT'] in the end.

    Did you do it another way?

    1. jimisaacs Avatar
      jimisaacs

      I assume you are talking about including CI from WordPress, if so you should always try to use constants from either platform.

  18. Rogier Avatar
    Rogier

    This looks like a great solution for my current project.

    But I can't get it to work properly. After creating the index.php and functions.php in the themes/mytheme/ folder, when I browse to mydomain.com/blog/ I get the following error:

    Your system folder path (system/) does not appear to be set correctly. Please open the following file and correct this: index.php

    I'm pretty sure this has to do with .htaccess files not setup correctly. Could you please give me an overview of what .htaccess files are needed in which folders, and what their content should be respectively? (I'm using the setup suggested in the main article -> codeigniter files and folders in the root, wordpress in subfolder 'blog')

  19. jimisaacs Avatar
    jimisaacs

    The htaccess files for each platform are not any different than if you installed each of them normally.
    For CodeIngiter: http://codeigniter.com/wiki/mod_rewrite/
    For WordPress: http://codex.wordpress.org/Using_Permalinks#Creat

  20. Michael Avatar
    Michael

    This is so badass. The possibilities with this are huge. I've been messing with this for a day and right now I have a working model using codeigniter 2 and wordpress 3.

    The way mine is working is wordpress is in the root, codeigniter in a subfolder. If you view a wordpress page it works, if you view a codeigniter only page it works, and if you try to view nothing it throws the 404 page. I can build a codeigniter app and "frame" it in wordpress. No double header includes, no trying to style your blog to match your app… etc.

    I'm going to package up what I have so people can use it. I just had to make this post because this is amazing.

    1. phtls Avatar
      phtls

      Can't wait!

    2. Mike Salway Avatar

      Would be very interested in this 'package' if you have it available.
      Any update on it?

  21. Joh Avatar
    Joh

    Hi,
    I wonder if you can point me in the right direction. I am gonna WordPress as the CMS of the site (so will mostly be using the Page not Post). So I have loaded WordPress at the root.

    Now, where do I load the CI files, would it be http://www.domain.com/codeigniter/? So all the CI files reside in the said directory or do I put all the CI file in the root as well – same level as where all the wp files are?

    1. jimisaacs Avatar
      jimisaacs

      Joh,
      Don't take this in the wrong way, but it sounds like you may not be that familiar with either platform this post is about. My first advice would be to checkout the documentation of each: http://codex.wordpress.org/Main_Page and http://codeigniter.com/user_guide/

  22. chaz Avatar
    chaz

    hi,
    i am trying to do the same thing… i need to add user type for my wordpress and codeigniter is very good at CMS so, I am planning to let the users log in to the site and will be redirected to the page they subscribed… can i somehow use sessions in CI having the above configuration or do i need to enable session in wordpress?

  23. Jaybee Avatar
    Jaybee

    Hi Jim,

    I have this data source file from an existing website which I believed built in CI framework. I want it to convert in WordPress but I don't know how to get started it with. This article of yours might be a big help of what I'm looking for but some part of it doesn't make sense to me.

    My question is..would it possible to convert the existing website to wordpress platform where all its function, layout, etc will be as is as the original?

    Looking forward to hearing back from you.

    Thanks!

    Chito

  24. twoWires Avatar
    twoWires

    Thanks for this info… I have tried a couple of the solutions found here and as well tried this ci + wp plugin . Seems i am missing something…. What i am trying to accomplish is to simply bring a mini CI app into wordpress framework. My biggest problem is getting the links within the CI app to integrate into the site proper (wp).

  25. Lee Avatar

    Good post man,

    I have 2 separate sites 1 is a CI membership management system and 2 is a WP public and members area site.

    Our requirement is to be able to add/edit users on the WP site from CI whilst keeping CI protected from WP. To achieve this I've created a copy of the WP site on the same site as CI, pointed it to the live WP database and blocked all public access to the copy. This way we can allow CI read/write access to WP and keep the CI system secure and minimising the risk of attack via WP.

    I have added to the CI index.php: require_once './wordpress/wp-load.php';
    Which works great, we are adding and editing users but…
    AJAX requests to some CI functions:- /members/getMemberJSON are returning 404's. I think that this is due to the fact that on the WP site /members/%username% already exists.

    Somehow need to override the routing for WP and am now a bit stuck. Any suggestions gratefully received

  26. yokohurley Avatar
    yokohurley

    Being a CodeIgniter Developer I would say that, CodeIgniter is a powerful framework that helps in providing efficient PHP Solutions. As it is light weighted and user friendly it would be easy to deal with it by saving lot of your time while tackling to any web application.

  27. Ben Avatar
    Ben

    Would be nice if someone had a example of this setup on github so you can just fork the code.

  28. Nookeen Avatar

    Thank you so much, it was the best integration I could find.

    Some might find these tips helpful, this is done in MAMP:

    ROOT: /wordpress/
    Codeigniter: /codeigniter/

    1.
    Added the following to /codeigniter/index.php to avoid System and Application folder being missing:

    // this is mostly for testing, going to codeigniter directly ABSPATH is showing ‘.’, so…
    if(dirname( ABSPATH ) == ‘.’){
    // so it needs the full path
    // PS: I modified apache to see /htdocs/myfolder/ as root
    $folder_path = ‘/Applications/MAMP/htdocs/myfolder/codeigniter/’;
    } else {
    // but coming from wordpress this can be done (easier to transfer to another server later)
    $folder_path = dirname( ABSPATH ).’/codeigniter/’;
    }

    THUS: $system_path = $folder_path.’system’;
    so on…

    2.
    CI – config.php
    $config[‘base_url’] = ‘http://localhost:8888/codeigniter/’;
    $config[‘index_page’] = ”; //get rid of ‘index.php’;

    3.
    .htaccess inside /codeigniter/ folder
    RewriteEngine on
    RewriteCond $1 !^(index\.php|images|robots\.txt)
    RewriteRule ^(.*)$ http://localhost:7878/codeigniter/index.php/$1 [L]

    4.
    WP’s template-loader.php function looks different nowadays, so what I did, I removed the 404 redirect and now my 404 is handled by CI. This is to make controllers work if there is no article in WP’s DB.

    if ( defined(‘WP_USE_THEMES’) && WP_USE_THEMES ) :
    $template = false;
    if ( is_search() && $template = get_search_template() ) :
    elseif ( is_tax() && $template = get_taxonomy_template() ) :
    elseif ( is_front_page() && $template = get_front_page_template() ) :
    elseif ( is_home() && $template = get_home_template() ) :
    elseif ( is_attachment() && $template = get_attachment_template() ) :
    remove_filter(‘the_content’, ‘prepend_attachment’);
    elseif ( is_single() && $template = get_single_template() ) :
    elseif ( is_page() && $template = get_page_template() ) :
    elseif ( is_category() && $template = get_category_template() ) :
    elseif ( is_tag() && $template = get_tag_template() ) :
    elseif ( is_author() && $template = get_author_template() ) :
    elseif ( is_date() && $template = get_date_template() ) :
    elseif ( is_archive() && $template = get_archive_template() ) :
    elseif ( is_comments_popup() && $template = get_comments_popup_template() ) :
    elseif ( is_paged() && $template = get_paged_template() ) :
    else :
    $template = get_index_template();
    endif;
    if ( $template = apply_filters( ‘template_include’, $template ) )
    include( $template );
    return;
    endif;

    These are NOT ALL, but some changes I consider useful.

    Thanks again!

  29. Maria Allen Quiambao Avatar

    Good post…will try this…

  30. Maria Allen Quiambao Avatar

    by the way, could you share how you do this leave a reply form with login with facebook,gmail or twitter account?

  31. Ibrahim Vatih Avatar

    I just hope WordPress can be integrated with another MVC framework

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.