DEVTRENCH.COM

Extending a WordPress Site: Core Hijack

It's pretty easy to hijack some core WordPress code and use it to extend the functionality of your WordPress site while keeping a cohesive look and feel. Basically, this technique creates a WordPress 'shell' that you can code inside of; utilizing all of WordPress's functions and themes, but leaving out the blog. I use this technique to add on functionality to my WordPress sites that don't fit within the WordPress framework, such as zip code locators and other custom database applications. You can even use this technique to build custom includes based on WordPress functions. Lets get to it...

Assumtions

First I need to tell you about how my WordPress blogs are set up. I usually set up my blogs in the root directory, and that is how this tutorial assumes you have done it as well. This means all of our coding will be going on inside of the WordPress install. Of course, your setup may be different than this, so just keep that in mind.

I'm also assuming that you've been good and have upgraded to WordPress 2.6. The WP developers have changed how the core code is included in WP 2.6 and this tutorial reflects that.

Set Up

To begin create a directory in your WordPress install for testing (this directory should be parallel to the wp-content folder). You can call it anything you like - I'm calling mine 'tool'. Next, create a blank index.php file in that folder.

Go on to learn how to include the WordPress core code...

Including WordPress

Every WordPress site runs off of the main index.php file as a front controller. If you open the index.php file you'll see that it includes a single file: wp-blog-header.php. In that file you'll see that it includes another file: wp-load.php (the contents of which used to be in the wp-blog-header.php file in pre 2.6 WP). The code in wp-load.php is the code that we are going to hijack and modify for our own purposes. Luckily for us, the people that coded wordpress made this really easy for us to do :)

Simply copy this code out of wp-load.php to your index.php file that we created in the set up.

/** Define ABSPATH as this files directory */
define( 'ABSPATH', dirname(__FILE__) . '/' );

error_reporting(E_ALL ^ E_NOTICE ^ E_USER_NOTICE);

if ( file_exists( ABSPATH . 'wp-config.php') ) {

	/** The config file resides in ABSPATH */
	require_once( ABSPATH . 'wp-config.php' );

} elseif ( file_exists( dirname(ABSPATH) . '/wp-config.php' ) ) {

	/** The config file resides one level below ABSPATH */
	require_once( dirname(ABSPATH) . '/wp-config.php' );

} else {

	// A config file doesn't exist

	// Set a path for the link to the installer
	if (strpos($_SERVER['PHP_SELF'], 'wp-admin') !== false) $path = '';
	else $path = 'wp-admin/';

	// Die with an error message
	require_once( ABSPATH . '/wp-includes/classes.php' );
	require_once( ABSPATH . '/wp-includes/functions.php' );
	require_once( ABSPATH . '/wp-includes/plugin.php' );
	wp_die(sprintf(/*WP_I18N_NO_CONFIG*/"There doesn't seem to be a wp-config.php file. I need this before we can get started. Need more help? We got it. You can create a wp-config.php file through a web interface, but this doesn't work for all server setups. The safest way is to manually create the file.

Create a Configuration File"/*/WP_I18N_NO_CONFIG*/, $path), /*WP_I18N_ERROR_TITLE*/"WordPress › Error"/*/WP_I18N_ERROR_TITLE*/);

}

The modifications we are going to make are as follows:

  1. Set the ABSPATH constant to the path of our WordPress install.
  2. Remove the code that checks for the config file - WP should already be installed if you are extending it and we know where it is.

Here is the modified code:

/** Define ABSPATH as this files directory */
define( 'ABSPATH', '/home/jamese/public_html' . '/' ); //This line used to be: define( 'ABSPATH', dirname(__FILE__) . '/' ); CHANGE [wp_dir] to your directory path that wpconfig.php is in

error_reporting(E_ALL ^ E_NOTICE ^ E_USER_NOTICE);

/** The config file resides in ABSPATH */
require_once( ABSPATH . 'wp-config.php' );

On the next page you'll learn how add your theme...

Adding Your Theme

Now that we have included the core WP files, the next step is to add our theme. Since we have all the necessary functions to do so, this is really easy. Simply add the following lines after the code we just modified in our index.php.

// includes the theme header
include(TEMPLATEPATH.'/header.php');

// includes the theme footer
include(TEMPLATEPATH.'/footer.php');

Obviously, header.php and footer.php have to exist in your theme in order for this to work, but most (if not all), WordPress themes have at least these two files. If you decide to change your theme in the future, the theme will change on these hijacked pages as well. Cool, huh?

Now you can code away and insert as much php goodness between the header and footer includes as you like. But what if you want to have friendly URLs like WordPress has?

Modifying .htaccess for Friendly URLS

Having Friendly URLs in the subdirectory of WordPress can be tricky since the rewrite rules affect files that are in your subdirectory. You have to add another rewrite rule in .htaccess above the one for WordPress that will filter out our directory first. It's added above because rewrite rules are executed in the order the come (and the [L] option tells apache that rule is the last one to be processed). Add this code above The main rewrite for WordPress:

[code]
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^tool/(.*) tool/index.php [L]
[/code]

Replace 'tool' with the name of your directory. The entire thing should look something like this:

[code]
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^tool/(.*) tool/index.php [L]


RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]

[/code]

This will allow you to have urls like /tool/screw-driver. Any url that does not actually exist as a file or directory will be passed through your index.php file. You'll need to write code there to parse the url appropriately.

On the next page you'll find out how to make custom includes...

Making Includes

Since we have the full power of WordPress at our finger tips, now we can make custom includes. Here's an example to load only the most recent posts as an HTML list:




/** Define ABSPATH as this files directory */
define( 'ABSPATH', '/home/jamese/public_html' . '/' ); //This line used to be: define( 'ABSPATH', dirname(__FILE__) . '/' ); CHANGE [wp_dir] to your directory path that wpconfig.php is in

error_reporting(E_ALL ^ E_NOTICE ^ E_USER_NOTICE);

/** The config file resides in ABSPATH */
require_once( ABSPATH . 'wp-config.php' );

#======================================================================#
# EDIT THEME START                                                     #
#======================================================================#
?>

This is cool because now you can include this page as an iframe or php include in other third party software (include your most recent posts on your forum for instance).

Wrap Up

I hope this post has opened your eyes to how you can extend the functionality of WordPress to non-WordPress pages. In this tutorial I've used the tool directory on this site for an example, and here are some actual tools that I've built using this method to wrap my code with the WordPress core.

Here is a collection of links to learn more about extending wordpress: