Discussion:
Organizing my theme's functions.php file
Micky Hulse
2013-08-15 23:42:09 UTC
Permalink
Howdy,

Here's a "pseudo 10,000 ft. view" of my `functions.php` file:

<https://gist.github.com/mhulse/6245870#file-1-pseudo-functions-before-php>

Long story short, I'm in the process of setting up a child theme for a
co-worker and I decided it was time to do some house cleaning and make
my parent theme's functions/hooks/other easier for child themes to
override.

I found this awesome article out on the net:

"WordPress theme function files"
<http://justintadlock.com/archives/2010/12/30/wordpress-theme-function-files>

Excellent tips!

With that said, I do have some questions:

1. For all custom functions that aren't tied into a WP hook, should I
wrap them with `if ( ! function_exists('some_custom_function')) {
some_custom_function() { ... } }` (as opposed to wrapping all
functions in a `function_exists` call)?

2. Based on Justin's excellent article above, I'm under the impression
that I should move all of my `add_action()`'s, `remove_action()`'s,
`add_filter()`'s, `remove_filter()`'s (and similar) into the
`foo_setup` function (which is hooked into `after_setup_theme`)? In
other words, should my functions.php file look more like this:

<https://gist.github.com/mhulse/6245870#file-2-pseudo-functions-after-php>

I have to admit, that "pseudo 10,000 ft. view" does look much cleaner
and organized.

I just wanted to ask the pros before I go making sweeping changes to
my theme's function.php.

Let me know if I need to clarify my questions better.

Many thanks in advance!

Cheers,
M
Brad Parbs
2013-08-15 23:53:23 UTC
Permalink
There's a few things you could do to improve the structure of the
functions.php file.

One thing quite a few people do is create a folder `inc/` and put
different files there, like `scripts.php` that contains script
functionality, `customizer.php` that holds all the theme customizations
stuff, etc. Then just include those files in your functions.php.

You could also move a lot of your functions to a theme-specific plugin
or multiple plugins, keeping it pretty organized there.

If you're using prefixed functions `foo_bar_theme_setup(){}`, and that
prefix is very unique, you don't have to worry about the
function_exists, unless you plan to override it later. I prefer wrapping
every function in that, so you can always override them easy later.

Moving all of the hooks into a function is a good way to go, as well.

Good luck!

-Brad
August 15, 2013 6:42 PM
Howdy,
<https://gist.github.com/mhulse/6245870#file-1-pseudo-functions-before-php>
Long story short, I'm in the process of setting up a child theme for a
co-worker and I decided it was time to do some house cleaning and make
my parent theme's functions/hooks/other easier for child themes to
override.
"WordPress theme function files"
<http://justintadlock.com/archives/2010/12/30/wordpress-theme-function-files>
Excellent tips!
1. For all custom functions that aren't tied into a WP hook, should I
wrap them with `if ( ! function_exists('some_custom_function')) {
some_custom_function() { ... } }` (as opposed to wrapping all
functions in a `function_exists` call)?
2. Based on Justin's excellent article above, I'm under the impression
that I should move all of my `add_action()`'s, `remove_action()`'s,
`add_filter()`'s, `remove_filter()`'s (and similar) into the
`foo_setup` function (which is hooked into `after_setup_theme`)? In
<https://gist.github.com/mhulse/6245870#file-2-pseudo-functions-after-php>
I have to admit, that "pseudo 10,000 ft. view" does look much cleaner
and organized.
I just wanted to ask the pros before I go making sweeping changes to
my theme's function.php.
Let me know if I need to clarify my questions better.
Many thanks in advance!
Cheers,
M
_______________________________________________
wp-hackers mailing list
http://lists.automattic.com/mailman/listinfo/wp-hackers
Micky Hulse
2013-08-16 06:37:27 UTC
Permalink
Hi Brad! Thanks so much for you help/reply, I really appreciate it. :)
One thing quite a few people do is create a folder `inc/` and put different
files there, like `scripts.php` that contains script functionality,
`customizer.php` that holds all the theme customizations stuff, etc. Then
just include those files in your functions.php.
You could also move a lot of your functions to a theme-specific plugin or
multiple plugins, keeping it pretty organized there.
Awesome, thanks for tips! :)

There are some instances where I've moved what would normally be
multiple related functions in `functions.php` into PHP/OOP classes and
suck them into my theme via an `include_once()`. I try to do this for
the bigger chunks of related code, but not usually for the smaller
functions or chunks of code.

Anyway, thanks for listing a few of the alternatives to having
everything in one file, I appreciate the tips. :)
If you're using prefixed functions `foo_bar_theme_setup(){}`, and that
prefix is very unique, you don't have to worry about the function_exists,
unless you plan to override it later. I prefer wrapping every function in
that, so you can always override them easy later.
Good to know! Thank you for the clarification.

Although, I have to say I'm a little confused ... Looking at:

<https://github.com/WordPress/WordPress/blob/master/wp-content/themes/twentyfourteen/functions.php>

There's not much use of `function_exists()` in WordPress' latest theme.

Not only that, it appears as though most of the `add_action()`'s are
next to their functions, vs. living in the `after_setup_theme`
function. Unless I'm mistaken (I probably am), Justin's article kinda
makes it sound like all function hooks (hook's functions?) should live
in the theme setup function.

So, what's the rule of thumb for when to put stuff inside `after_setup_theme`?

Heck, I'm probably thinking too hard (or, not hard enough) about all this.

My gut is telling me to follow the lead of twentyfoureen (i.e. no
`function_exists()` checks and keep hooks next to their custom
functions vs. move all hooks into `after_setup_theme`).

OTOH, like you say, it can't hurt to use `function_exists()` around everything.

Sorry if I'm rambling.
Moving all of the hooks into a function is a good way to go, as well.
So many options!

Have you built a theme, or do you know of a theme, that has the
perfect setup (in your opinion) for a `functions.php`? I think I need
to see some good/contemporary examples.

My main concern is that I build the most optimal setup for when it
comes to allowing child themes to override my parent theme's functions
(and yes, this is my first child theme setup, so I'll probably sound
less like a noob once I've had some time to experiment). :D

Thanks again Brad! Much appreciated.
Frank Bueltge
2013-08-16 06:41:53 UTC
Permalink
Morning.
Maybe the thread on WPSE is helpful
http://wordpress.stackexchange.com/questions/1403/organizing-code-in-your-wordpress-themes-functions-php-file
Post by Micky Hulse
Hi Brad! Thanks so much for you help/reply, I really appreciate it. :)
Post by Brad Parbs
One thing quite a few people do is create a folder `inc/` and put
different
Post by Brad Parbs
files there, like `scripts.php` that contains script functionality,
`customizer.php` that holds all the theme customizations stuff, etc. Then
just include those files in your functions.php.
You could also move a lot of your functions to a theme-specific plugin or
multiple plugins, keeping it pretty organized there.
Awesome, thanks for tips! :)
There are some instances where I've moved what would normally be
multiple related functions in `functions.php` into PHP/OOP classes and
suck them into my theme via an `include_once()`. I try to do this for
the bigger chunks of related code, but not usually for the smaller
functions or chunks of code.
Anyway, thanks for listing a few of the alternatives to having
everything in one file, I appreciate the tips. :)
Post by Brad Parbs
If you're using prefixed functions `foo_bar_theme_setup(){}`, and that
prefix is very unique, you don't have to worry about the function_exists,
unless you plan to override it later. I prefer wrapping every function in
that, so you can always override them easy later.
Good to know! Thank you for the clarification.
<
https://github.com/WordPress/WordPress/blob/master/wp-content/themes/twentyfourteen/functions.php
There's not much use of `function_exists()` in WordPress' latest theme.
Not only that, it appears as though most of the `add_action()`'s are
next to their functions, vs. living in the `after_setup_theme`
function. Unless I'm mistaken (I probably am), Justin's article kinda
makes it sound like all function hooks (hook's functions?) should live
in the theme setup function.
So, what's the rule of thumb for when to put stuff inside
`after_setup_theme`?
Heck, I'm probably thinking too hard (or, not hard enough) about all this.
My gut is telling me to follow the lead of twentyfoureen (i.e. no
`function_exists()` checks and keep hooks next to their custom
functions vs. move all hooks into `after_setup_theme`).
OTOH, like you say, it can't hurt to use `function_exists()` around everything.
Sorry if I'm rambling.
Post by Brad Parbs
Moving all of the hooks into a function is a good way to go, as well.
So many options!
Have you built a theme, or do you know of a theme, that has the
perfect setup (in your opinion) for a `functions.php`? I think I need
to see some good/contemporary examples.
My main concern is that I build the most optimal setup for when it
comes to allowing child themes to override my parent theme's functions
(and yes, this is my first child theme setup, so I'll probably sound
less like a noob once I've had some time to experiment). :D
Thanks again Brad! Much appreciated.
_______________________________________________
wp-hackers mailing list
http://lists.automattic.com/mailman/listinfo/wp-hackers
Micky Hulse
2013-08-16 06:50:10 UTC
Permalink
Post by Frank Bueltge
Morning.
Morning Frank! :-)
Post by Frank Bueltge
Maybe the thread on WPSE is helpful
http://wordpress.stackexchange.com/questions/1403/organizing-code-in-your-wordpress-themes-functions-php-file
Ah, that looks very helpful. Thank you for sharing link, reading now.

Much appreciated!

Cheers,
M
J.D. Grimes
2013-08-16 13:19:53 UTC
Permalink
Hi, Micky,

I'm not really a theme dev, so bear with me here...
Post by Micky Hulse
1. For all custom functions that aren't tied into a WP hook, should I
wrap them with `if ( ! function_exists('some_custom_function')) {
some_custom_function() { ... } }` (as opposed to wrapping all
functions in a `function_exists` call)?
If you want to allow the function to be overridden, there are several other approaches that you could take:

1. You could replace your calls to the function with do_action() or apply_filters(), i.e., create a custom action/filter and hook your function to that.
2. You could call filter(s) or action(s) within the function, allowing other functions to manipulate its output, or even override it completely.

I think doing something like that would be cleaner and possibly more extensible, but that's just me.
Post by Micky Hulse
2. Based on Justin's excellent article above, I'm under the impression
that I should move all of my `add_action()`'s, `remove_action()`'s,
`add_filter()`'s, `remove_filter()`'s (and similar) into the
`foo_setup` function (which is hooked into `after_setup_theme`)? In
<https://gist.github.com/mhulse/6245870#file-2-pseudo-functions-after-php>
I'm not sure what the logic behind that would be. The child theme won't be able to remove any of the actions or filters like it normally would if they aren't added until 'after_setup_theme'; it would have to hook into a later action just to manipulate the actions of the parent theme. At least that's what I'm thinking, correct me if I'm wrong.

Good luck!

-J.D.
Justin Tadlock
2013-08-16 16:46:23 UTC
Permalink
Post by J.D. Grimes
Post by Micky Hulse
2. Based on Justin's excellent article above, I'm under the impression
that I should move all of my `add_action()`'s, `remove_action()`'s,
`add_filter()`'s, `remove_filter()`'s (and similar) into the
`foo_setup` function (which is hooked into `after_setup_theme`)? In
<https://gist.github.com/mhulse/6245870#file-2-pseudo-functions-after-php>
I'm not sure what the logic behind that would be. The child theme won't be able to remove any of the actions or filters like it normally would if they aren't added until 'after_setup_theme'; it would have to hook into a later action just to manipulate the actions of the parent theme. At least that's what I'm thinking, correct me if I'm wrong.
If you put an action/filter in functions.php, it can't be removed by a
child theme because a child theme's functions.php is loaded before the
parent theme's functions.php. Hooking this code on 'after_setup_theme'
gives child themes an opportunity to change this. Of course, this is
all explained in the referenced article.
Micky Hulse
2013-08-16 17:36:18 UTC
Permalink
Hi Justin! Thanks so much for the reply, I really appreciate it!

Loved your article. I know it's a couple years old now, but it still
seems like it's packed with some awesome tips on `functions.php`
organization.

Out of curiosity, because the article is a little older, and WP has
evolved a little since then, have you discovered anything new that
isn't in your article?

On Fri, Aug 16, 2013 at 9:46 AM, Justin Tadlock
Post by J.D. Grimes
I'm not sure what the logic behind that would be. The child theme won't be
able to remove any of the actions or filters like it normally would if they
aren't added until 'after_setup_theme'; it would have to hook into a later
action just to manipulate the actions of the parent theme. At least that's
what I'm thinking, correct me if I'm wrong.
If you put an action/filter in functions.php, it can't be removed by a child
theme because a child theme's functions.php is loaded before the parent
theme's functions.php. Hooking this code on 'after_setup_theme' gives child
themes an opportunity to change this. Of course, this is all explained in
the referenced article.
... and I hate to sound like a dunce, but there was so much info
packed into that article, that I found myself having to read it a few
extra times and then ask for help with the professionals on this list.

I'm still trying to wrap my head around all the tips (on top of all
the other great links/resources folks have pointed me towards).

With that said, if it's not too much trouble, could you take a quick
look at my pseudocode `functions.php` examples:

<https://gist.github.com/mhulse/6245870>

Just to be clear, in the above Gist, the first file is "BEFORE" and
the second is "AFTER".

Questions:

1. In the second file (the "AFTER"), is that basically what your
article is recommending? Essentially, your saying to move all
action/filters into `after_setup_theme`?

2. I did not see an example in your article where a you show a
action/filter/other outside of `after_setup_theme`; are there
situation where you wouldn't wan't to put an action/filter inside
`after_setup_theme` (other than if you didn't want something to be
overridden)?

3. Have you built a theme, one that I could look at, that uses the
techniques you explain in your blog post?

4. Is there a reason why a theme like `twentyfourteen` doesn't follow
these guidelines? Is it because that theme wasn't meant to have
children?

Again, sorry for being dense here. I just really want to fully
understand the tips you provide in your article.

Thanks for your time.

Thanks to everyone for listening to (and helping to answer) my silly questions.

Have an awesome day!

Cheers,
Micky
Micky Hulse
2013-08-16 17:38:45 UTC
Permalink
On Fri, Aug 16, 2013 at 10:36 AM, Micky Hulse
Post by Micky Hulse
4. Is there a reason why a theme like `twentyfourteen` doesn't follow
these guidelines? Is it because that theme wasn't meant to have
children?
I should say, "doesn't follow SOME of these guidelines".

I understand that there are many ways to "theme" a cat. :)

I did not mean to imply that the twentyfourteen theme was doing it wrong.

Thanks!
M

Micky Hulse
2013-08-16 17:18:12 UTC
Permalink
Hi J.D., thank you for your help, I really appreciate it. :)
Post by J.D. Grimes
Post by Micky Hulse
1. For all custom functions that aren't tied into a WP hook, should I
wrap them with `if ( ! function_exists('some_custom_function')) {
some_custom_function() { ... } }` (as opposed to wrapping all
functions in a `function_exists` call)?
1. You could replace your calls to the function with do_action() or apply_filters(), i.e., create a custom action/filter and hook your function to that.
2. You could call filter(s) or action(s) within the function, allowing other functions to manipulate its output, or even override it completely.
Good fundamental tips. Thank you.

For my latest theme, I've done a bit of #2 in your list above. It'll
be interesting to play with those from a child theme.

Long story short, I've developed a theme for my day job's blogs
(multisite), and now a co-worker needs to have a blog on the network
that's a bit different than the rest ... I just want to make sure my
parent theme's setup is solid so he can have an easy time setting up
his mods.
Post by J.D. Grimes
I think doing something like that would be cleaner and possibly more extensible, but that's just me.
Good luck!
Thank you J.D.! :)

Have a nice day!

Cheers,
M
Loading...