This isn’t a question about how to build a WordPress plugin. Rather, what, if any, guides could be applied to how to put together the file architecture of any plugin.
Some other programming languages or libraries have very controlled ways of organizing directories and files. Sometimes this is annoying and highlights the freedom that PHP offers, but on the flip-side WordPress plugins are put together in any fashion as determined by their author.
There isn’t a right answer, but my hope is to refine how I, and others, build plugins to make them more friendly for other developers to disect, easier to debug, easier to navigate, and possibly more efficient.
The final question: what do you think is the best way to organize a plugin?
Below are a few sample structures, but in no way is an exhaustive list. Feel free to add your own recommendations.
Assumed Default Structure
/wp-content
/plugins
/my-plugin
my-plugin.php
Model View Controller (MVC) method
/wp-content
/plugins
/my-plugin
/controller
Controller.php
/model
Model.php
/view
view.php
my-plugin.php
MVC’s three parts:
- The model interacts with the database, querying and saving data, and contains logic.
- The controller would contain template tags and functions that the view would utilize.
- The view is responsible to display the data provided by the model as constructed by the controller.
Organized by type method
/wp-content
/plugins
/my-plugin
/admin
admin.php
/assets
css/
images/
/classes
my-class.php
/lang
my-es_ES.mo
/templates
my-template.php
/widgets
my-widget.php
my-plugin.php
WordPress Plugin Boilerplate
Available on Github
Based on the Plugin API, Coding Standards, and Documentation Standards.
/wp-content
/plugins
/my-plugin
/admin
/css
/js
/partials
my-plugin-admin.php
/includes
my_plugin_activator.php
my_plugin_deactivator.php
my_plugin_i18n.php
my_plugin_loader.php
my_plugin.php
/languages
my_plugin.pot
/public
/css
/js
/partials
my-plugin-public.php
LICENSE.txt
README.txt
index.php
my-plugin.php
uninstall.php
Loosely organized method
/wp-content
/plugins
/my-plugin
css/
images/
js/
my-admin.php
my-class.php
my-template.php
my-widget.php
my-plugin.php
Note that plugins are all “controllers” by WP standards.
It depends on what the plugin is supposed to do, but in all cases I would try to separate the screen output from the PHP code as much as possible.
Here’s one way to do that easily – first, define a function that loads the template:
Now, if the plugin uses a widget to display data:
The template:
Files:
Where do you put your CSS, JS, images, or how do you design the container for the hooks is less important. It’s a matter of personal preference I guess.
It depends on the plugin. This is my basic structure for nearly every plugin:
This would be something that would go in the
lib
folder.If it’s particularly complex plugin, with a lot of admin area functionality, I’d add an
admin
folder to contain all of those PHP files. If the plugin does something like replace included theme files, there maybe atemplate
ortheme
folder as well.So, a directory structure might look like this:
IMHO, the easiest, most powerful, and most maintainable route is to use an MVC structure, and WP MVC is designed to make writing MVC plugins very easy (I’m a little biased, though…). With WP MVC, you simply make the models, views, and controllers, and everything else is handled behind the scenes for you.
Separate controllers and views can be made for the public and admin sections, and the entire framework takes advantage of many of WordPress’s native features. The file structure and much of the functionality is exactly the same as it is in the most popular MVC frameworks (Rails, CakePHP, etc).
More info and a tutorial can be found here:
We’re using a mix of all methods. First of all, we’re using the Zend Framework 1.11 in our plugins and therefore we had to use a similar structure for the class files because of the autoload mechanic.
The structure of our core plugin (which is used by all our plugins as a base) looks similar to this:
webeo-core.php
file in the plugin root folder.Webeo_CoreLoader
class inside this file, which sets some plugin constants, initialize the class autoloader and make a call to the setup method of theCore.php
class inside thelib/Webeo
folder. This runs on theplugins_loaded
action hook with a priority of9
.Core.php
class is our plugin bootstrap file. The name is based on the plugins name.As you can see, we have a subdirectory inside the
lib
folder for all our vendor packages (Webeo
,Zend
). All sub packages inside a vendor are structure by the module itself. For a newMail Settings
admin form, we would have the following structure:Our sub-plugins have the same structure with one exception. We go a level deeper inside the vendor folder due to resolve naming conflicts during the autoload event. We also call the plugins boostrap class
E.g. Faq.php
on priority10
inside theplugins_loaded
hook.I will probably rename the
lib
folder tovendors
and move all public folders (css, images, js, languages) to a folder namedpublic
in the next release.Like many here already answered It really depends on what the plugin is supposed to do, but here is my base structure:
I am partial to the following plugin layout, however it usually changes depending on what the plugin requirements are.
I have yet to create a WordPress plugin requiring a MVC style architecture but if I was to do this I would lay it out with a separate MVC directory, which itself contains views/controllers/models.
All my plugins follow this structure, which seems to be very similar to what most other devs are doing:
plugin-folder.php is then usually a class that loads all required files from the core/ folder. Most often on the init or plugins_loaded hook.
I used to prefix all my files as well, but as @kaiser noted above, it’s really redundant and I’ve recently decided to remove it from any future plugins.
The library/ folder holds all external helper libraries that the plugin might depend on.
Depending on the plugin, there might be an uninstall.php file in the plugin root as well. Most of the time this is being handled via register_uninstall_hook(), though.
Obviously, some plugins might not require any admin files or templates, etc, but the structure above works for me. In the end you just have to find a structure that works for you and then stick with it.
I also have a starter plugin, based on the structure above that I use as a starting point for all my plugins. All I need to do then is do a search/replace for function/class prefixes and off I go. When I was still prefixing my files that was an extra step I had to do (and quite annoying at that), but now I just have to rename the plugin folder and the main plugin file.
My logic, the bigger the plugin the more structure I use.
For big plugins I tend to use MVC.
I use this as a starting point and skip what isn’t needed.
Also, see this great WP widget boilerplate . It gives great hints as of structures (even if there isn’t a class nor folder for separate models).
A less common approach to structuring a plugin’s files and directories is the file type approach. It’s worth mentioning here for completeness:
Each directory contains files of that type only. It’s worth noting that this approach falls short when you have many file types
.png .gif .jpg
that might be more logically filed under a single directory,images/
for example.