[theme-reviewers] wrapping functions with if( ! function_exists() ) {…}

Justin Tadlock justin at justintadlock.com
Mon Oct 13 14:40:40 UTC 2014

I'm OK with us bumping backwards compatibility to 3 or 4 versions.  I just
don't think it's that important.  By far, the most `function_exists()`
usage I see is for stuff that has been in core for years.  I'd say a good
90% of it is to check for the `dynamic_sidebar` and related functions.  The
other 10% checks for `add_image_size`.

The problem is not that themes are really checking for backwards
compatibility.  They'll use functions only available in WP 4.0 but check if
a function exists that was introduced in WP 2.2.

On Sat, Oct 11, 2014 at 2:36 PM, Ulrich Pogson <grapplerulrich at gmail.com>

> Thanks Otto!
> "The two version guideline was made back when versions were a bit more
> spread out. Two versions now is like 6 months. I think being a bit lenient
> on this one makes sense."
> @tammie - Can we discuss this at the next Team Meeting?
> On 11 October 2014 18:33, Otto <otto at ottodestruct.com> wrote:
>> On Sat, Oct 11, 2014 at 10:48 AM, Ulrich Pogson <grapplerulrich at gmail.com
>> > wrote:
>>> The guidelines states: "Themes must not provide backward compatibility
>>> for out-of-date WordPress versions (more than two prior major WordPress
>>> versions – currently, that means versions prior to WordPress 3.8),
>>> including using function_exists() conditional wrappers for current *WordPress
>>> functions*." https://make.wordpress.org/themes/handbook/guidelines/
>>> This is one thing we require but I could not find in the guidelines.
>>> "Function calls must be placed inside callbacks and hooked into
>>> appropriate actions or filters (such as after_setup_theme for Theme setup
>>> functions, or widgets_init for Widgets/dynamic sidebar functions)"
>>> The *theme functions* can be wrapped in a if( !function_exists()) {…}.
>>> At the moment this is not required nor recommended.
>>> Actually Chris wrote a good answer below Ottos:
>>> http://wordpress.stackexchange.com/a/111318/17937
>>> P.S I personally don't think every every theme function needs to be
>>> wrapped in if( !function_exists()) {…} because depending on the function
>>> you can just as well overwrite it with another function hooking into the
>>> same hook. If the function was a bit more complex then it would be better
>>> to make the function extendable with hooks and filters. So that child theme
>>> could change single values instead of having to copy the whole function.
>> The two version guideline was made back when versions were a bit more
>> spread out. Two versions now is like 6 months. I think being a bit lenient
>> on this one makes sense.
>> As for the if(exists) check, I would recommend against it except when
>> it's really necessary.
>> Let's say a theme (parent) defines its functions like this:
>> function whatever() {
>> }
>> add_action('init','whatever');
>> Now, a child theme can override any function that is hooked into any hook
>> like that by simply unhooking it in after_setup_theme and replacing it:
>> function child_override() {
>>    remove_action('init','whatever');
>>    add_action('init','child_whatever');
>> }
>> add_action('after_setup_theme','child_override');
>> The exception to this is parent functions that are themselves hooked
>> into after_setup_theme. A child can't easily override these, because it has
>> no hooks that fire earlier for it to unhook. And once the action is
>> running, unhooking from inside it does nothing. So those particular
>> functions, if any, should be pluggable using an if(exists) check.
>> You can see this specific case with the twentyfourteen_setup function.
>> It's not possible for a child theme to unhook that function, only to
>> replace it by redefining it.
>> Now, twentyfourteen actually makes a lot of its functions pluggable. The
>> ones that it makes pluggable are one of the following:
>> a) Hooked to after_setup_theme
>> b) Called directly by something else in the theme
>> (twentyfourteen_the_attached_image), so replacing them in a child is easier
>> than having to replace their calling files too (image.php in that case).
>> c) Used as a callback for something else (twentyfourteen_header_style),
>> so replacing them is simpler than having to adjust the specific callback
>> location in which they are added
>> These are all good reasons for pluggable functions. The downside of
>> pluggables is that they can only be replaced one time. A theme and a plugin
>> cannot both override a pluggable. So, pluggables should really only be used
>> when there's little other good avenues. Most of the time, if you're hooking
>> a function to an action or filter, then it is possible for some other bit
>> of code to unhook and replace it without a whole lot of difficulty, so
>> making it pluggable is unnecessary.
>> -Otto
>> _______________________________________________
>> theme-reviewers mailing list
>> theme-reviewers at lists.wordpress.org
>> http://lists.wordpress.org/mailman/listinfo/theme-reviewers
> _______________________________________________
> theme-reviewers mailing list
> theme-reviewers at lists.wordpress.org
> http://lists.wordpress.org/mailman/listinfo/theme-reviewers
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.wordpress.org/pipermail/theme-reviewers/attachments/20141013/d3158057/attachment.html>

More information about the theme-reviewers mailing list