WordPress MVC: Easily add a touch of MVC to plugins

Building web-apps for some years now, I’ve worked a lot with multiple MVC-frameworks. Most recently with CakePHP, which is great. As WordPress plugin developer I sometimes miss that strictly structured way of coding, a WordPress MVC pattern. While the code of a lot plugins I see, is organised very well generally, I really don’t like the way many developers mixing HTML-output with their plugin functions and classes. Here an examples, from the Hello Dolly plugin.

// This just echoes the chosen line, we'll position it later
function hello_dolly() {
    $chosen = hello_dolly_get_lyric();
    echo "<p id='dolly'>$chosen</p>";
}

Another one from the akismet plugin, included in a standard WordPress installation:

function akismet_stats_display() {
    global $akismet_api_host, $akismet_api_port, $wpcom_api_key;
    $blog = urlencode( get_bloginfo('url') );

    $url = 'http://';
    if ( is_ssl() )
        $url = 'https://';

    $url .= 'akismet.com/web/1.0/user-stats.php';
    $url .= "?blog={$blog}&api_key=" . akismet_get_key();
    ?>
    <div class="wrap">
    <iframe src="<?php echo $url; ?>" width="100%" height="100%" frameborder="0" id="akismet-stats-frame"></iframe>
    </div>
    <?php
}

Even if I don’t think that is a big deal, I see at least a readability issue. That’s why I prefer to store my HTML in separate files, just as you would do in every MVC-framework. It just needs a little view-class and this gets really easy. It has three logical parts: The first one is to locate the file, containing the HTML-view, the second one makes it possible to set variables in the views context and the last one renders the view.

WordPress MVC – The views location

I like to store my views in a folder called views in my plugin directory and I even add the fact that it is a view to the filename. Thus, in my plugins a settings view would be located in plugins/my-plugin/views/settings.view.php. Now, creating an instance of that view in one of my plugin-functions, I don’t want to add the complete path, the relevant part “settings” should do, and the view-class does the rest in the constructor:

public function __construct($view) {
    $path = $plugin_path."/views/".$view.".view.php";
    if (file_exists($path")) {
        $this->view = $path;
    } else {
        wp_die(__("View ".$path." not found"));
    }	
}

WordPress MVC – Setting variables to use in the view

Having the location of the file, we can now add data, that we want to render the view with. Take the Hello Dolly snippet as example, the content of our view file would look like:

<p id="dolly">
    <?php echo $chosen; ?>
</p>

Now we have to set the variable $chosen in the views context. Therefore we use an array called vars containing all data coming in via the set-function of the view-class.

public function set($name,$value) {
    $this->vars[$name] = $value;
}

WordPress MVC – Rendering the view

Finally we need a function to print out the view. It just registers the variables set in the vars-array and uses the output-buffering-functions of php to include and echo the view:

public function render() {
    extract($this->vars,EXTR_SKIP);
    ob_start();
    include $this->view;
    echo ob_get_clean();
}	

WordPress MVC – The view class

Setting all together in a view class (for copy and paste use, see github-link below), enables you to cleanly separate your views from your plugin-code. So, in a plugin, we can instantiate the view, set variables and render it, like this:

include "classes/MyView.class.php";
$view = new My_view("dolly-example");
$view->set("chosen","Lorem ipsum");
$view->render();
Tagged with:

3 thoughts on “WordPress MVC: Easily add a touch of MVC to plugins

  1. If you are loading views from the plugin, then it would also be worthwhile checking for the views in the theme too. That way a developer can override any of your plugin views in their own theme without having to hack your plugin.

    1. I agree, if we talking views which are included in the theme. But I think that views, which are used in the admin-interface, like a meta-box, shouldn’t be altered by the theme developer. What do you think?

      1. Yes, I agree – admin views are very specific.

        I’m thinking more where a plugin has lots of front-end output. For example where it might display tables, a calendar, have a series of pages or forms to go through to apply for something.

        I found this post because I am embarking on a project with some quite complex functionality, and a requirement that it was to be implemented in WordPress. So I am looking for a full MVC apporach, but want to keep the Model inside WordPress (some MVC plugins exist, but take the data outside of the core WP tables) but also looking for a simple Controller framework. This looks ideal for the View parrt – I can concentrate on getting the functionality working, and outputting to some simple templates that just work, but then have someone else working on the theme to override those templates to style it all up.

        Anyway – this is all a great start. I guess this would be the hidden “Helper” part of MVC.

Leave a Reply

Your email address will not be published. Required fields are marked *