Code template for a WordPress plugin

I’ve been working on a lot of plugins lately – many for my work at WooThemes and a few for my personal projects – and over time I have developed a standard code base from which I start any of my new plugins. I always keep this handy for any new work, so I don’t have to rewrite the same basic code every time I start something new. I’m sure many people have their own similar frameworks for this kind of thing, but I thought it worth sharing my own in case it helps someone else get started with new plugin development.

The template includes built-in support for:

  • Custom post type with custom fields and custom taxonomies
  • Plugin settings page
  • WPML i18n

The code is entirely object-oriented and is written according to the WordPress coding standards – all it requires is editing in order to remove the demonstration data and add new, more functional, data. The plugin is obviously not meant to be used in its current form, but if you activate it without changing anything it will create a new post type (identified as ‘*Posts’ in your dashboard menu) and a new settings page (found at Settings > Plugin Settings). These pages are entirely functional, so you can see a working demonstration of how a plugin built using this template will work. You can get the code from GitHub below – feel free to change it to make it more practical for your own use.

[button link=”https://github.com/hlashbrooke/WordPress-Plugin-Template” window=”yes”]Get the code![/button]

This site is hosted by SiteGround - running on their incredibly fast and super secure platform that is uniquely tailored for WordPress hosting. Moving my site to SiteGround was the best decision I ever made for it - you should do the same. Today.

8 thoughts on “Code template for a WordPress plugin”

  1. Hi Hugh

    Thank you very much for your contribution on github.

    I’m very new to plugin developpement (usually I went my way using functions.php) but I wish now to separate the design aspect (which would go to the theme functions) to the content that should be within a plugin scope (as far as I have understood the good standart)… after reading WordPress Plugin Developpement book, I try to find how real world developper actually does not to re invent wheels..

    As a rooky, I will have for sure several questions after studying your plugin template, do you mind if I ask you? where is the better place to do so?

    Thank you again in advance

    1. I’m glad you’re finding my code useful. If you have any questions feel free to post them on here and I’ll respond when I can – best to keep the discussion public so that others can benefit too :)

  2. Hi Hugh

    Thank you for your fast answer, please forgive me for dumb question, but plugin is quite new to me.
    here are my questions

    1° files have all the ‘wordpress-plugin-template’ part name, I guess I must change that to something that fits my plugin name, right?
    2° I have seen that in all the classes, for translation purpose if I understand, there is a reference to plugin_textdomain like with
    ‘add_new_item’ => sprintf( __( ‘Add New %s’ , ‘plugin_textdomain’ ), __( ‘Post’ , ‘plugin_textdomain’ ) ),
    and the plugin_textdomain is what is used in the lang direction… shall I change this plugin_textdomain everytwhere in everyclass each time I wish to do a new plugin to avoid colision?
    3° let say that I want to register a new CPT, shall I duplicate class-wordpress-plugin-template-post_type.php with another name like class-myplugin-other_post_type.php and make changes within that classe, and include/initiatilize in wordpress-plugin-template.php at the root, or this there a way to pass argument to the original class
    4° I wish to have a special meta box for a given CPT with various meta datas on it like drop box, text area and custome taxonomies… would you recomand to add in my plugin a metabox builder class like Metaboxes by http://www.deluxeblogtips.com/meta-box/ or WP alchimy, or anything you would advise me, or should I add each type by hand?.

    Thank you very much in advance for your help

    1. To answer your questions, Steffy:

      1. Yes, you should change that part of the file name to whatever is relevant for you. Names should always be lower case and use hyphens for spaces (according to the WordPress standards).

      2. Right again – you must change the ‘plugin_textdomain’ bit to whatever is a relevant name for your plugins text domain. This will enable people to translate your plugin when they use it. This must be set as a text string and not passed as a variable.

      3. Yip – the best method is to create another file for the new CPT class and then include it in the main plugin file.

      4. If you want to add metaboxes to the CPT then simply add a new element to the $fields array in the get_custom_fields_settings() function at the bottom of the CPT class. Any fields defined in that array will show up on the screen and their contents will be saved. You can define the type of field it must be, but if you do anything other that text or URL you will need to add some processing to the meta_box_content() function so that it displays properly.

      I hope that helps – it sounds like you’ve got most things worked out already.

      1. Hi Hugh

        Thank you again for your answers..

        some more about the 4th point, if it is ok foryou

        1° if I well understand, all the creation if fired at the _construct stage, this function call other public function, but the job is done there, right?

        2° let say that I want to have another taxonomie, I should duplicate function register_taxonomy() by calling it for example function register_taxonomy_2()
        and call it from the constructor by add_action(‘init’, array( &$this , ‘register_taxonomy_2′ ) ); or is there a smarter way ?

        3° if I want to add other fields to the meta box, I will have to add them to
        — get_custom_fields_settings() like for example
        $fields[‘_custom_field_2′] = array(
        ‘name’ => __( ‘Custom field num2:’ , ‘plugin_textdomain’ ),
        ‘description’ => __( ‘Description of this custom field nub 2.’ , ‘plugin_textdomain’ ),
        ‘type’ => ‘checkbox’,
        ‘default’ => ”,
        ‘section’ => ‘plugin-data’
        );
        (could you explain me what ‘section’ => ‘plugin-data’ refers cuz did not found neither on the class or on the codex)

        if it is not a a text field or checkbox then I have to add condition on the meta_box_content() in between
        if( $v[‘type’] == ‘checkbox’ ) {
        $html .= ” . $v[‘name’] . ‘ ‘ . $v[‘description’] . ” . “\n”;
        $html .= ” . “\n”;
        }

        and
        else {
        $html .= ” . $v[‘name’] . ” . “\n”;
        $html .= ” . $v[‘description’] . ” . “\n”;
        $html .= ” . “\n”;
        }

        I guess the sanitization is made at the meta_box_save() function and that should be putted at the // Handle custom fields part

        right?

        Thank you in advance

        1. Hi Hugh,

          some more questioning at my side

          1° since taxonomies are not necessary related to one CPT but can be assigned to several, would not that make sens to separate them from the postytype class? and have a class for dealing with taxonomies?

          2° actually the same question for the metaboxes

          3° I have seen that many are creating or using kind of Framework/classes/functions to speed up the CPT, Mtaxonomies/metaboxes creation, what do you think of those?

          Thank you again

        2. In your first comment here, you’re 100% spot on with everything – the answer to all three questions in there is yes :) The ‘section’ => ‘plugin-data’ bit is a sorting that would only really be necessary if you have loads of custom fields, but it doesn’t really serve any purpose – I just like to keep it in there in case I need it later.

          In your second comment, my answer to questions 1 & 2 is the same: taxonomies and meta boxes are unique to each post type – I’m not sure who told you that they’re not, but that person was wrong. Every taxonomy and meta box is registered with a CPT and can only be used with that CPT – this means that defining them in this function is the most logical place to do this. With that in mind, my answer to your last question would be that those other frameworks and classes for adding custom fields are totally unnecessary if you are using this code of mine. You can add all the CPTs, taxonomies and meta boxes with my code so why would you need any other framework to do so? More frameworks like that just means more potentially unstable code on your site.

  3. NICE boilerplate. Saved me a lot of time! The only thing it’s missing (in my mind) is to add in multi-site init stuff.

Leave a Reply

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

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>