<div dir="ltr"><div>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`.</div><div><br></div><div>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.</div><div><br></div></div><div class="gmail_extra"><br><div class="gmail_quote">On Sat, Oct 11, 2014 at 2:36 PM, Ulrich Pogson <span dir="ltr"><<a href="mailto:grapplerulrich@gmail.com" target="_blank">grapplerulrich@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">Thanks Otto!<span class=""><div><br></div><div>"<span style="font-family:arial,sans-serif;font-size:13px">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."</span></div></span><div><span style="font-family:arial,sans-serif;font-size:13px">@tammie - Can we discuss this at the next Team Meeting?</span></div></div><div class="gmail_extra"><br><div class="gmail_quote"><div><div class="h5">On 11 October 2014 18:33, Otto <span dir="ltr"><<a href="mailto:otto@ottodestruct.com" target="_blank">otto@ottodestruct.com</a>></span> wrote:<br></div></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div><div class="h5"><div dir="ltr"><span><div class="gmail_extra"><div class="gmail_quote">On Sat, Oct 11, 2014 at 10:48 AM, Ulrich Pogson <span dir="ltr"><<a href="mailto:grapplerulrich@gmail.com" target="_blank">grapplerulrich@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div dir="ltr"><div>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 <b>WordPress functions</b>." <a href="https://make.wordpress.org/themes/handbook/guidelines/" target="_blank">https://make.wordpress.org/themes/handbook/guidelines/</a></div><div><br></div><div>This is one thing we require but I could not find in the guidelines.</div><div>"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)"<br></div><div><br></div><div>The <b>theme functions</b> can be wrapped in a <font face="arial, sans-serif">if( !function_exists()) {…}. At the moment this is not required nor recommended.</font></div><div><br></div><div>Actually Chris wrote a good answer below Ottos: <a href="http://wordpress.stackexchange.com/a/111318/17937" target="_blank">http://wordpress.stackexchange.com/a/111318/17937</a><br></div><div><br></div><div>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.</div></div><div class="gmail_extra"></div></blockquote></div><br></div><div class="gmail_extra"><br></div></span><div class="gmail_extra">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.<div><br></div><div>As for the if(exists) check, I would recommend against it except when it's really necessary. </div><div><br></div><div>Let's say a theme (parent) defines its functions like this:</div><div><br></div><div>function whatever() {</div><div>}</div><div>add_action('init','whatever');</div><div><br></div><div>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:</div><div><br></div><div><div>function child_override() {</div><div>   remove_action('init','whatever');<br></div><div>   add_action('init','child_whatever');</div><div>}</div><div>add_action('after_setup_theme','child_override');</div></div><div><br></div><div>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.</div><div><br></div><div>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.</div><div><br></div><div>Now, twentyfourteen actually makes a lot of its functions pluggable. The ones that it makes pluggable are one of the following:</div><div><br></div><div>a) Hooked to after_setup_theme</div><div><br></div><div>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).</div><div><br></div><div>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</div><div><br></div><div>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.</div><span><font color="#888888"><div><br></div><div><br></div><div class="gmail_extra">-Otto</div><div><br></div></font></span></div></div>
<br></div></div><span class="">_______________________________________________<br>
theme-reviewers mailing list<br>
<a href="mailto:theme-reviewers@lists.wordpress.org" target="_blank">theme-reviewers@lists.wordpress.org</a><br>
<a href="http://lists.wordpress.org/mailman/listinfo/theme-reviewers" target="_blank">http://lists.wordpress.org/mailman/listinfo/theme-reviewers</a><br>
<br></span></blockquote></div><br></div>
<br>_______________________________________________<br>
theme-reviewers mailing list<br>
<a href="mailto:theme-reviewers@lists.wordpress.org">theme-reviewers@lists.wordpress.org</a><br>
<a href="http://lists.wordpress.org/mailman/listinfo/theme-reviewers" target="_blank">http://lists.wordpress.org/mailman/listinfo/theme-reviewers</a><br>
<br></blockquote></div><br></div>