Select Page

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.

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.jsfor 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!