Skip to content

Jesse's Software Engineering Blog

Jan 06

Jesse

Integrating WordPress into existing PHP site

I decided to re-do my portfolio site and wanted a way to easily post articles on topics that I have learned or am learning, and to allow others to comment on them. The site was to be built using a PHP framework and I wanted the blog to integrate into the MVC application seamlessly, i.e. work with the routes and not have a blog.domain.com URL or a /blog route. I also wanted to use all my own design elements, HTML and CSS, and not have to try and pick, customize, or create a WordPress template.

Coding in WordPress

Researching the problem

I don’t have a lot of experience with WordPress and I couldn’t find many good tutorials on blog integration, so I started off by browsing through the WordPress docs. Surprisingly, it only took two articles to figure out how to do what I wanted:

http://codex.wordpress.org/The_Loop_in_Action – WordPress refers to it’s main process as “the Loop”. At it’s basic form, it is a iteration through the available posts based on defined filters. One really nice feature that is built into the Loop, is everything is filtered for you based on the URL by default and/or easily filterable by passing in params to PHP function calls. So once you start the Loop, you don’t have to worry about filtering through or checking the posts, that’s already done.

http://codex.wordpress.org/Template_Tags – This is a function reference for the Loop. A list of different functions that you can access during the Loop’s iterations. From here I was able to find all the functions I needed.

Installing WordPress

Installing WordPress was pretty straight forward, I don’t feel like I need to touch on this much. One thing I noticed is an installation is not specific to a blog, rather specific to variables defined in your wp-config.php file and database. So let’s say you install a blog into your development environment: http://wordpress.local. When you’re ready to push to staging or production, you don’t have to reinstall the blog. You can just upload the WordPress files, create the tables, update the wp_options table (siteurl and home columns) and you’re good to go.

Including the Code

Before you can get the loop to work inside of you application you need to include the WordPress files and tell WordPress you are not using the templating system:

define('WP_USE_THEMES' , false);
require( WORDPRESS_PATH . '/wp-blog-header.php' );

One issue I ran into when integrating the WordPress code into the framework is that the WordPress functions use the global keyword so placing the require() inside a view or controller messes up the scope. Simply place the require() in your index.php file and then it will remain global. One thing to consider is you may not want the WordPress files to be included on every request so depending on your framework you can add a check in your index based on the route whether you need to include the WordPress files or not:

/**
 * Check if WordPress files are needed
 */
if ($this->router->getControllerName() == ‘development-notes’) {
    require( WORDPRESS_PATH . '/WordPress-blog-header.php' );
}

Once the files are included you can access the WordPress data from anywhere in your application:

<?php if ( have_posts() ) : ?>
    <?php while ( have_posts() ) : the_post(); ?>

        <!--- enter blog post html here -->

    <?php endwhile; ?>
<?php endif; ?>
Integrating the Loop into your views

I placed the Loop code right into the view file for my main blog page. Inside the Loop you can do things like: <?php the_title(); ?>, <?php the_excerpt(); ?>, etc. (see above link for complete list). This allows you to easily integrate blog post data into your custom HTML. WordPress usually give you two ways to access the information, either as a returned piece of data or it just outputs to the screen for you.

Since I put the Loop code on my main blog page: jessesnet.com/development-notes/, there are no filters, and therefore the loop gives all the posts by default (up to the limit specified in the admin section). When you click on a filter like category, or tag, you get redirected to: jessesnet.com/development-notes/category/PHP, etc. Now at this point your MVC application will probably look for the categoryAction in your controller. One nice feature about WordPress’s loop is that it will automatically filter itself based on the URL and will only iterate through the applicable posts. This allows you to reuse your index view in your different actions. So you could either route the different URL structures into the same indexAction to reuse your main view, or what I did is make simple actions that set misc display variables then reused the index view:

/**
 * Action for view update when posts are filtered by category
 */
public function categoryAction()
{
    // need to determine the category based on the slug
    $slug = $this->getSlug();
    $category = get_category_by_slug($slug);
    $title = isset($category->cat_name) ? $category->cat_name : 'None Found';

    // save title, set view
    $this->view->setVar('title', $this->getTitleHTML($title));
    $this->view->pick("development-notes/index");
}

I also wanted to set up a different layout for viewing a post, so I just created a route for it based on my particular URL structure, /2014/01/article-title, and in that action picked the view for the single post. In that view you still use the same loop code, but it will only go through one iteration as the post has already been filtered to the single article based off of the URL:

/**
 * Route for single post view
 */
$router->add(
    "/blog/([0-9]{4})/([0-9]{2})/([a-zA-Z0-9_-]+)",
    [
        "controller" => "development-notes",
        "action" => "viewPost"
    ]
);

/**
 * Action for picking the single post view html
 */
public function viewPostAction()
{
    $this->view->pick("development-notes/view-post");
}

/**
 * Code inside view file 
 * (will already be filtered based off the URL to have a single iteration)
 */
<?php if ( have_posts() ) : ?>
    <?php while ( have_posts() ) : the_post(); ?>

        <!--- enter blog post html here -->

    <?php endwhile; ?>
<?php endif; ?>
Custom Comment Form

A big part of the project requirements were allowing others to comment on my posts. I wasn’t necessarily going for discussion style threads but I wanted to give people the ability to add feedback to my articles. I wasn’t sure how to set up the form so I used the the following WordPress function to output the default HTML for a comment form: <?php comment_form(); ?> From that point I was able to copy the necessary input tags and create my own custom form. Things to be aware of when you do this, make sure that you take all inputs, including the hidden ones, and that the names match. If you want to change any of the name values then you just have to update the corresponding wp-comments-post.php file which is where the form posts to.

Adding Search Capabilities

When it came to adding the search capabilities to my blog it was the same process as with the custom comment form. I created a default WordPress form and copied the HTML: <?php get_search_form(); ?>. As I mentioned before, a nice thing about the Loop is it filters which posts are supposed to be displayed. This applies to the searching of posts as well in that when you search you just pass a GET param of s and the Loop will automatically filter the posts it generates. So where ever you want to add a search form, just set the method to GET, action to your blog route, and set the search input field name to s. It’s that easy.

Securing Your Installation

I strongly suggest Google’ing “WordPress security plugins” and finding some plugins that fit your purposes. In addition to that, here are a couple more security steps one could take:

  • Change the login from the default and pick a strong password
  • Take sensitive constants out of the document root
  • Restrict files, directory access with .htaccess files
  • Limit the number of plugins / themes you have installed
  • Create a MySQL user for WordPress with restrictive permissions
  • Discourage anonymous posts to your WordPress scripts
  • Limit the size of the WordPress database

Blog Powered By Wordpress