I’d like to allow users to add functions to the theme I’m developing, but don’t want users to change functions.php directly, as this file may be updated with theme updates. In other words, I’d like this to work in a similar fashion to custom CSS files.
How can I setup a user-functions.php file for users and ensure those functions are also run when the theme is activated?
My suggestion would be to use
get_template_part
. I think that is the closest you can get to what you want.You may be able to just drop
get_template_part('userfuncts');
into yourfunctions.php
. That will loaduserfuncts.php
from your theme’s main directory, if the file is present, or from a child theme’s directory if applicable. See the Codex for how the function searches for files. It is a stepped-up version of PHP’sinclude
really. Any function that would work infunctions.php
should work in that included file. But that is an important condition. Some things do not load well from a theme’sfunctions.php
and need to be in a plugin.However, EAMann has a good point. While it is possible to update the theme without losing the
userfuncts.php
file, that is not necessarily the case. It is fairly common to completely delete a theme and then upload the update. I don’t know how the automatic updater does this, as I never use that updater, but if it deletes and then reinstalls you are going to have trouble.You could do something like create two directories for your theme– the main one and a second user functions directory.
Then create a
get_template_part
-like function to load files from that directory. It shouldn’t be hard to do usingget_template_part
as a model. You’d have a kind of pseudo-child theme. It could be a source of confusion but good docs would help a lot and I have no idea how ‘proper’ that solution is. I only just thought about it. Hope I don’t get yelled at 🙂Your theme could just install itself and a child but the you’d have the same update issue if you ever altered the child.
Really, any files you place in the theme will be replaced/removed when the theme updates.
Instead, if you want users to add custom functionality they should do so through a custom plugin. If you have hooks and filters exposed through the theme, a custom functionality plugin will solve the problem.
Basically, it’s two files:
readme.txt
functionality.php
Without knowing what your theme is doing or what custom functionality you need, I can’t be very precise. But if you expose actions where you want users to do something and filter what output you want them to filter, then anyone can use a custom functionality plugin like this without hacking on the theme directly.
For allowing user functions, you really have two options:
functions.php
There is a plugin that allows you to do this in the admin, it allows for portable user input functions (theme agnostic) , with no need to edit to your theme’s functions.php
You can see it here: https://github.com/bungeshea/code-snippets
You can download it from wordpress.org here: http://wordpress.org/extend/plugins/code-snippets/
Screenshot:
To ensure your customers are able to easily override aspects of your theme, the best bet is to stick with WordPress’ existing conventions for this, ie: a child theme. “functions.php” is also intended for custom user-entered code, but you said you’d prefer to stay away from that, so I’ll focus on other options.
The general rule of thumb is as follows:
Styles
Overriding CSS styles should be done in the “style.css” file inside a child theme.
Functions
Overriding procedural functions should be done using pluggable functions. The WordPress Codex has an example of how to setup pluggable functions.
Hooked Functions
While functions that are assigned to a hook or filter could also be made pluggable, you could also just encourage customers to unhook the function and hook in their own replacement. This would save you, at most, 2 lines of code per function in your files, as you wouldn’t be making the functions pluggable.
Template Parts
If you’d like customers to be able to easily override specific sections of your theme’s output without having to copy an entire template file into their child theme, you could make effective use of template parts to achieve this (for example, if your footer area contains widgets and then, maybe, a credits section, each of those could be a template part).
As mentioned above, effective placement of
do_action()
calls is an easy way to allow customers to hook in their own code.Combined with the above options, you should be well on your way to having your customers easily customise your theme using existing WordPress conventions and making it easier for them to update their copy of your theme to future versions. 🙂