When it comes to introducing custom functionality into a WordPress project, the debate between functions.php vs. plugin usage is nothing new.
Generally speaking, I think of themes are presentation and plugins as functionality that transcend whatever theme or themes with which they’re installed.
But sometimes, this delineation isn’t so clear. For example, let’s say that you’re working on a theme that needs to introduce a custom meta box – or several – into the post editor screen.
Though this is presentation related in that it will impact what’s displayed to the users, it’s also a bit of custom functionality but it’s only relegated to this particular theme.
Functions.php vs. Plugin Files
Here’s the thing: Conventional wisdom is the WordPress development community says that anything that exists in
functions.php can exist in a plugin file.
This is true, although I think plugins – especially larger ones – should be developed using alternative techniques such as object-oriented programming which is something that
functions.php cannot offer.
That said, we have to remember that when we’re working on our projects, it’s not always a matter of picking either
functions.php or using a plugin especially when the custom functionality is unique to the theme yet impacts the presentation of the theme.
Anyone who has built relatively large themes or slightly complex web applications using WordPress knows that
functions.php can get large very quickly. On top of that, no matter what amount of documentation you provide, the file simply gets larger which can make it difficult to locate whatever it is that you’re looking to find.
I think one thing that we often forget is maintenance factor that comes with creating and releasing a theme or application.
Finding Middle Ground
To that end, there is middle ground that exists between
functions.php and plugins and that’s to use separate files and place them in a separate directory.
Perhaps it’s a
lib directory, perhaps its an
inc directory (which is short for includes), or whatever convention your theme uses.
The idea behind this strategy is to make sure that that core theme functionality is kept in
functions.php. This includes features such as:
- The content width
- Theme features such as support for featured images
- Functionality related to custom header and custom background support
- …and more
Files kept in the
inc directory are usually related to core theme functionality but are more specialized. They aren’t quite plugin territory because they don’t need to be made available to all themes, but they’re specific enough to warrant their own file.
This can include:
- Custom post types
- Meta boxes
- Custom menu pages
- …and more
Note that this strategy is also employed by a variety of boilerplates and starter themes such as Underscores.
And For What It’s Worth
If you find yourself torn between placing something in
functions.php or writing a plugin, but still feeling as if both options are wrong, consider this third alternative.
Personally, when it comes to organizing code, I use
lib directory, as will my CSS, and so on.
Then, I use
inc as the directory for my own libraries, code, and functions that are used throughout the theme.
Ultimately, this comes down to a factor of maintenance – you can make a place for each piece of functionality without sacrificing the integrity of your project, and without having to generalize the functionality into a plugin.