0

I'm creating a Wordpress site in which I wanted to use a custom taxonomy in my theme options, which I had registered using the 'init' hook. But the problem was that the 'init' hooks gets fired after the theme options (I'm using the Redux Framework plugin for the theme options). So when I used the get_categories() function inside my theme options, and tried to get the custom taxonomy, I was getting an 'invalid_category' error.

So I decided to just register the taxonomy without any hooks and simply calling the register_taxonomy() function in the functions.php file and it worked.

I just want to know if this is 'safe', as in, what would be the consequences if I simply call register_taxonomy function without using any hooks.

Here is the code that doesn't work, while using the init hook:

function my_function(){
  register_taxonomy( 'portfolio_category', 'portfolio', array(
                    'labels' => array(
                              'name' => _x( 'Portfolio Categories', 'taxonomy general name' ),
                              'singular_name'     => _x( 'Portfolio Category', 'taxonomy singular name'     ),
                              'search_items'      => __( 'Search Portfolio Categories' ),
                              'all_items'         => __( 'All Portfolio Categories' ),
                              'parent_item'       => __( 'Parent Portfolio Category' ),
                              'parent_item_colon' => __( 'Parent Portfolio Category:' ),
                              'edit_item'         => __( 'Edit Portfolio Category' ),
                              'update_item'       => __( 'Update Portfolio Category' ),
                              'add_new_item'      => __( 'Add New Portfolio Category' ),
                              'new_item_name'     => __( 'New Portfolio Category' ),
                              'menu_name'         => __( 'Portfolio Categories' ),
                          ),
                    'hierarchical' => true,
                  ) );

}
add_action('init', 'my_function');

$portfolio_categories = get_categories(array('taxonomy' => 'portfolio_category', 'hide_empty'=> 0));
echo "<pre>", print_r($portfolio_categories), "</pre>"; // This will return an error of 'invalid_taxonomy'

And here is one that works, (without using any hooks):

register_taxonomy( 'portfolio_category', 'portfolio', array(
                    'labels' => array(
                              'name' => _x( 'Portfolio Categories', 'taxonomy general name' ),
                              'singular_name'     => _x( 'Portfolio Category', 'taxonomy singular name'     ),
                              'search_items'      => __( 'Search Portfolio Categories' ),
                              'all_items'         => __( 'All Portfolio Categories' ),
                              'parent_item'       => __( 'Parent Portfolio Category' ),
                              'parent_item_colon' => __( 'Parent Portfolio Category:' ),
                              'edit_item'         => __( 'Edit Portfolio Category' ),
                              'update_item'       => __( 'Update Portfolio Category' ),
                              'add_new_item'      => __( 'Add New Portfolio Category' ),
                              'new_item_name'     => __( 'New Portfolio Category' ),
                              'menu_name'         => __( 'Portfolio Categories' ),
                          ),
                    'hierarchical' => true,
                  ) );

$portfolio_categories = get_categories(array('taxonomy' => 'portfolio_category', 'hide_empty'=> 0));
echo "<pre>", print_r($portfolio_categories), "</pre>";

Also the first code works, if I put it in a page template, so I know I'm doing it correctly. Please let me know about this

Thanks.

1
  • Just as a sidenote, I've always registered my taxonomy using the init hook and just tested with get_categories() and was able to use it on my taxonomy without problems. Also, are you trying to run get_categories() in your functions.php file or are you registering your taxonomy outside your functions.php file? Register your taxonomy in your functions.php and use get_categories() in a template file.
    – Howdy_McGee
    May 19, 2014 at 19:16

3 Answers 3

1

Your code without using the init hook use also a hook, but not fired from your source. A last it was fired from the include of the your theme, which was loaded in WordPress. It is much bad for your control. If you use a hook, then is the include from your source on your control, you choose the hook. If you will leave this open and the core of WP change the order or other points of the include of theme, maybe you have problem, like the function will never work. Also it is bad style, that you not catch your source inside a wrapper, like a function for the control. Is also easier to read, fied on this hook, this callback - your function.

1

According to the WordPress Codex on register_taxonomy()

Use the init action to call this function. Calling it outside of an action can lead to troubles. See #15568 for details.

Better be safe than sorry when registering custom taxonomies for custom post types. Use register_taxonomy_for_object_type() right after the function to interconnect them. Else you could run into minetraps where the post type isn't attached inside filter callback that run during parse_request or pre_get_posts.

So I would trust the codex and stick with using the init hook then try to figure out why get_categories() isn't working properly.

3
  • 1
    When trusting "The Codex", then in this case you are suggesting to trust me as I have been the one to add that paragraph (compare diff). In other words: Never suggest blindly trusting the codex. It's written by people... like the Bible.
    – kaiser
    May 19, 2014 at 20:23
  • While I agree to an extent because the Codex is editable like Wikipedia and I do understand some articles may get outdated over time but saying "Never blindly trust the codex" is harsh. Unlike The Bible we can test the functions, methods, and statements to either prove them true or false. So like Wikipedia Articles I say you have to take it with a grain of salt.
    – Howdy_McGee
    May 19, 2014 at 20:42
  • The problem that I see is suggesting something without explaining the why behind it - that's why I compared it to the Bible (or any other holy book that people believe in). For an in depth explanation for the why, read this article and please file an edit to add that bit to your answer.
    – kaiser
    May 19, 2014 at 20:53
0

It is inherently unsafe to do anything outside of a hook, ever.

In your case, the real problem is not the fact that you're using the init action hook, it is that your call to get_categories is not inside a function on an action hook.

I believe you need to understand "hooks" in more general terms.

The purpose of the "hook" system in WordPress is to have code execute in the correct place, at the correct time. Simple, really. Certain things need to happen in a certain order.

Now, one way to ensure a certain order is to simply write a bunch of code in a file in the order you want it to run and then run it. The simple approach. However, this has the problem of adding in arbitrary code at specific points in that file later. This is where hooks solve the problem.

WordPress runs a whole lot of code in a specific order. Hooks are used to insert other code into that predefined specific order, in named places. So, code that is not inside functions attached to hooks just runs in order, from the top of the file to the bottom of the file, wherever that file happens to be included. And that file might be included in different ways. You cannot know for certain. Using a hook lets you put your code basically anywhere, but have it called at exactly the right time, a time of your own choosing.

So for code in plugins, or code in a theme's functions.php file, then realistically you should never have any code that is not in a function and hooked, ever. There's a couple special cases here and there, but darned few of them.

ALL code in a theme's functions.php file should be in functions that are attached to some hook somewhere. It's named "functions.php" for a reason, it only should contain functions, not code outside of functions.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.