Colored Paper Bokeh

7-minute read

Plugin Structure for ClassicPress Plugins

A bit of thought to the structure of your plugin can save your project from becoming an unmaintainable nightmare. Learn the basics and get your plugins off to a good start!

When creating a ClassicPress plugin, it might be tempting to jump right in and start writing code. Where will you store the file(s)? And, will you need just one file? Or, will you need multiple files and subdirectories? Decisions, decisions! In case you didn’t notice, all these questions are about your plugin structure. Luckily, you can avoid pitfalls that make your plugin harder to maintain. Moreover, by avoiding poor organization, your project will be much more pleasurable to work on now…and in a year. Now, let’s get this! If you’d like to learn more, be sure to check the tutorials on converting a code snip into a ClasicPress utility plugin or creating a utility plugin for ClassicPress.

Basic Plugin Structure

For the following plugin structure example, it is assumed that I’m creating a plugin called Plugin Name and it will live in the `../wp-content/plugins/` directory of my ClassicPress site.

To clarify, the `+` signs indicate directories and the `-` signs indicate files. Now, look over the example structure and then see the explanations that follow.

+ codepotent-plugin-name
    + classes
        - SomeClassName.class.php
        - AnotherClassName.class.php
        - index.php
    + images
        - active.png
        - inative.png
        - index.php
    + includes
        - constants.php
        - functions.php
        - index.php
    + languages
        - codepotent-plugin-name-de_DE.po
        - codepotent-plugin-name-fa_IR.po
        - index.php
    + libs
        + some-lib
        + some-other-lib
        - index.php
    + scripts
        - admin-global.js
        - admin-edit.js
        - index.php
        - user-global.js
        - user-{POST TYPE}-archive.js
        - user-{POST TYPE}-single.js
    + styles
        - admin-global.css
        - admin-edit.css
        - index.php
        - user-global.css
        - user-{POST TYPE}-archive.css
        - user-{POST TYPE}-single.css
    + templates
        - index.php
        - user-{POST TYPE}-archive.php
        - user-{POST TYPE}-single.php
    - codepotent-plugin-name.php
    - index.php
    - license.txt
    - README
    - readme.txt

Main Directory – Line 1

This is your plugin’s main directory. Notably, it should use all lowercase letters, and hyphens instead of spaces. There is no need to prefix your plugins with cp-; instead, prefix your plugins with your own unique prefix. This ensures your plugin doesn’t collide with any other plugins a user may have installed.

Subdirectories – Lines 2, 6, 10, 14, 18, 22, 29, 36

These are common subdirectories found in a plugin. This is neither an exhaustive list nor are any of these directories required. If you don’t have a need for a particular directory in your plugin, omit it. Subdirectory names should be lowercase, and hyphens used instead of spaces.

Index Files – Lines 5, 9, 13, 17, 21, 25, 32, 37, 41

Your main plugin directory and each subdirectory should contain an index.php file. While this doesn’t add a layer of security, it does add a layer of privacy. The files ensure that the directory contents cannot be listed in the browser. This is not a requirement, just a better practice.

Class Files – Lines 3, 4

If your plugin is object oriented, these files would be your classes. The class names use Pascal case in the form `TheClassName.class.php` where the class name is mirrored in the file name.

Image Files – Lines 7, 8

If your plugin has images in it, these might be a couple of them. If your plugin has a lot of images, it might make sense to create subdirectories for some or all of them. However, if you just have a few images, a single directory will suffice.

Included Files – Lines 11, 12

If your plugin includes PHP files, store them here. The example depicts a file for constants and a file for functions. See the tutorial on using path and URL constants in ClassicPress plugins to learn more. If you have particular code for admin and user views, you can use the format `admin-functions.php` and user-functions.php to separate them.

Language Files – Lines 15, 16

If your plugin has been translated into other languages, these might be examples of the translation files.

Libraries – Lines 19, 20

If your plugin uses other pre-existing libraries, they can be stored here in their own subdirectories. The subdirectory capitalization should match the library name(s), and hyphens used instead of spaces.

Scripts – Lines 23, 24, 26, 27, 28

  • `admin-global.js` for scripts that apply to all views of your plugin’s admin screens
  • `admin-edit.js` for scripts that apply only to your plugin’s edit screen
  • `user-global.js` for scripts that apply globally on the front-end, if any
  • `user-{POST TYPE}-archive.js`for scripts that apply only to the archive view of your plugin
  • `user-{POST TYPE}-single.js` for scripts that apply only to the single view of your plugin

Styles – Lines 30, 31, 33, 34, 35

  • `admin-global.css` for styles that apply to all views of your plugin’s admin screens
  • `admin-edit.css` for styles that apply only to your plugin’s edit screen
  • `user-global.css` for styles that apply globally on the front-end, if any
  • `user-{POST TYPE}-archive.css` for styles that apply only to the archive view of your plugin
  • `user-{POST TYPE}-single.css` for styles that apply only to the single view of your plugin

Template Files – Lines 38, 39

  • `{POST TYPE}-archive.php` is a template for displaying a custom post type’s archive view
  • `{POST TYPE}-single.php` is a template for displaying a custom post type’s single view

Main Plugin File – Line 40

The main PHP file for your plugin should mirror its directory name, followed by a PHP extension. For example, a plugin named “My Great Plugin” would be stored in a directory named my-great-plugin and inside that directory would be the main PHP file `my-great-plugin.php`. This file will contain the plugin header comment section that registers the plugin in the system. This is a required file.

Additional Files – Lines 42, 43, 44

If your plugin contains extra files, such as a license or readme file, it it common to store these in the root directory of your plugin.

Additional Considerations

Why split my plugin out into a bunch of files?

By splitting your plugin structure into separate directories and files, you can then load only the assets that you need for any given view. Unfortunately, some plugin developers tend to load everything everywhere – this is a lazy approach that can quickly lead to performance issues for users – don’t be that developer.

Should my plugin structure have public and admin directories?

Well, you can do it that way, if you like. I don’t find it necessary, though. For most plugins, simply separating the functionality into files and naming them appropriately will suffice. Indeed, creating admin and public directories might lead to twice as many subdirectories to manage. Ultimately, the decision is yours.

Why use the same value for the directory and main file?

If your plugin directory name and main PHP filename match, then ClassicPress will automatically load the appropriate language files for your plugin. Subsequently, this means you don’t have to explicitly load the text domain in your PHP code. For example, a plugin of `my-cool-plugin/my-cool-plugin.php` would enjoy the automatic text domain loading.

Wrapping Up

Well, here we are at the end! It’s my hope that you have a good idea of how you might structure a basic ClassicPress plugin. Keep in mind that this is merely one way to structure a plugin and the information here is not a set of hard rules. This information is more a set of guidelines to point you in some direction and to keep you on the right track. If you avoid mistakes that are tedious to undo later, my job is done.

What do you think?

There are infinite ways to structure a plugin for ClassicPress – how do you approach it? Do you create admin and public directories, or just separate the functionality into separate files? Was this helpful to you, or are you wondering how to get these minutes of your life back? I’d love to hear your thoughts – let me know in the comments!

2 comments on “Plugin Structure for ClassicPress Plugins”

  1. A commenter said:

    Great article, thanks. I have a question… I’ve been working on a utility plugin that I now use on all my sites and I’m finding it incredibly useful, but it’s also growing rather long and unwieldy (over a 1,000 lines of code in the main php file). So, I had been thinking of breaking it up.

    Is this just a matter of taking out sections of code and making a new file in the includes folder, and then doing a call to include this in the main php file? Does it need any special formatting or headers? Would appreciate any tips on how to break up one big file into more manageable smaller chunks.

    • AUTHOR
      Code Potent replied:

      Hi Alan,
      Glad you enjoyed the article. Yes, you can take functions and/or classes from your main PHP file and insert them into other files instead. Then, you can use include_once() or require_once() in your main PHP file to bring your new files in.

      For the headers of your new files, there are no requirements. You can copy the same basic information from the header of your main PHP file, if you like. However, in your new files, be sure to omit the line that reads:

      Plugin Name: SC Utility

      …only your main PHP file can have that particular line in the header. Of course, you’ll also want to prevent direct access to your included files, just like you’ve done in your main PHP file.

      As far as how to break up your code for the utility plugin, a simple rule of thumb is probably best: keep similar functionality together in the same files or directories.

      If you have any questions, feel free to hit me back up!

Leave a Reply

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

Click to access the login or register cheese