Development
WordPress logo
- Development

Disconnect your frontend from WordPress

Head shot of AlexBy Alex Crooks

Almost all of our projects require an admin or content management system at some point. We tend to build our own from scratch to perfectly suit the project’s requirements. However when the budget or complexity doesn’t require it, we turn to our trusty friend WordPress.

WordPress doesn’t have the greatest reputation sometimes, with dodgy plugins leaving sites exposed to hacking and developers struggling with the restrictions of its blogging legacy.

To overcome this we take a slightly different approach to using WordPress in our projects. WordPress is still a winner in client’s eyes because of its polished UI and simplicity. We don’t take any of that away, but we completely disconnect the frontend of WordPress from its admin panel. We don’t use its theming functionality and as a result we are given complete freedom over what we can do with the data, while still giving our clients a great admin experience.

Frontend freedom

To do this we wrote a PHP wrapper that the frontend uses to fetch the database data at any point, not just when the themeing system allows you to. This means we can choose to include WordPress functionality where it’s needed, rather than blanketing the entire site.

An example of this can be seen in our own site, check out the source code for the team page and try to work out where WordPress comes in. It’s the timeline section, but you’d never know. We’ve used WordPress there to manage our company’s history, but we don’t need it anywhere else, meaning we aren’t shackled to WordPress for the rest of the site. As a result we have the freedom to do some really cool things.

A more extreme example of us using this technique is Raconteur. The entire backend is controlled by WordPress, even the interactive pages such as Infographics. Often you can immediately tell if a site is built with WordPress by looking at all the junk it pollutes the header with, but with this method you’re in full control.

Using plugins

When we’ve mentioned this method in the past people have asked how we handle plugins if we aren’t using a theme. If you look at the source code of the plugin you can simply call its internal functions in your own PHP code. This is all it’s doing inside a theme anyway, and often you end up writing your own plugins as a result, reducing the amount of security holes your site might have. We’ve used complex plugins like “advanced custom fields” and “adrotate pro” without any issues using this method. You just need to look at how they are storing their data in the database and go grab it!

Example code

Below is a simplified wrapper pulled from our custom framework so you can get started. The code is also on our Github repo.

<?php
/**
 * Model for interfacing with a Wordpress backend
 *
 * @author Alex Crooks, Si digital http://sidigital.co
 **/

// Load the wordpress bootstrap and it's helpers
define('WP_USE_THEMES', false);
require_once(APP_PATH.WP_INSTALL_FOLDER.'wp-blog-header.php');

class WordpressNoTheme 
{    
    function __construct() {
        // STUB
    }

    // Get posts of any type
    function getPosts($numOfPosts = MAX_ARTICLES, $offset = 0, $type = 'post', $dateFilter = FALSE, $orderBy = 'post_date', $order = 'DESC') {

        $query = array(
            'post_status'   => 'publish',
            'post_type'     => $type,
            'orderby'       => $orderBy,
            'order'         => $order,
            'offset'        => $offset,
            'numberposts'   => $numOfPosts,
        );

        if($dateFilter) {
            $query['monthnum'] = $dateFilter['month'];      
            $query['year'] = $dateFilter['year'];           
        }

        return get_posts($query);
    }

    // Get 'post' or 'page' etc by slug ("post_name" in wp db)
    function getEntryBySlug($slug = FALSE, $type = 'post') {

        if(!$slug)
            return FALSE;

        $getPost = get_page_by_path($slug, 'OBJECT', $type);

        if($getPost) {

            if($getPost->post_status == "publish")
                return $getPost;
            else
                return false;
        } else {
            return false;
        }
    }

    function getAttachedImage($id, $type) {
        return wp_get_attachment_url(get_post_meta($id, $type, true));
    }

    // Get preview to a post
    function getPreview($id = FALSE) {
        if(!$id)
            return FALSE;

        return get_post($id, 'OBJECT');        
    }

    // Get related posts based on tags used in original post
    function getRelated($postID, $exclude = '', $numResults = 5) {

        $related = array();
        $tags = array();
        $getTags = wp_get_post_tags($postID);

        if($getTags && $postID) 
        {            
            foreach($getTags as $tag) {
                $tags[] = $tag->term_id;
            }

            $related = get_posts(array(
                'numberposts'   => $numResults,
                'tag__in'       => $tags,
                'post__not_in'  => array($postID),
                'exclude'       => $exclude,
            ));
        }

        return $related;
    }

    function getCategoryBySlug($slug) {
        return get_category_by_slug($slug);
    }

    // Return post's category info
    function getPostCategory($postID) {

        $category = get_the_category($postID);
        
        if($category) {
            $data = new stdClass();

            $data->ID = $category[0]->cat_ID;
            $data->name = $category[0]->name;
            $data->slug = $category[0]->slug;

            return $data;
        } else {
            return FALSE;
        }
    }

    // Return posts in a particular category, by category ID
    function getPostsInCategory($categoryID, $exclude = '', $offset = 0, $maxPosts = MAX_ARTICLES, $type = 'post') {

        return get_posts(array(
            'post_status'   => 'publish',
            'post_type'     => $type,
            'category_name' => $categoryID,
            'exclude'       => $exclude,
            'offset'        => $offset,
            'numberposts'   => $maxPosts
        ));
    }

    // Return posts in a custom taxonomy
    function getPostsInCustomCategory($taxonomy, $categoryID, $type = 'post', $maxPosts = MAX_ARTICLES) {
        return get_posts(array(
            'post_status'   => 'publish',
            'post_type'     => $type,
            $taxonomy       => $categoryID,
            'numberposts'   => $maxPosts
        ));
    }

    // Return our latest blog posts
    function getLatest($numOfPosts = MAX_ARTICLES, $offset = 0) {
        return wp_get_recent_posts(array(
            'numberposts' => $numOfPosts,
            'offset' => $offset,
            'post_status' => 'publish'
        ), 'OBJECT');
    }

    function search($term, $offset = 0, $maxPosts = MAX_ARTICLES) {
        return get_posts(array(
            's'             => $term,
            'post_status'   => 'publish',
            'offset'        => $offset,
            'numberposts'   => $maxPosts
        ));
    }

    // Clean output
    function clean($content) {
        return stripslashes(htmlspecialchars($content, ENT_QUOTES, 'UTF-8'));
    }
}

$wp = new WordpressNoTheme();
Next Post

Get started

Plan your project