简体   繁体   中英

WordPress: Why Can't get_terms() See Custom Taxonomy Registered inside Class?

Background

I register a custom post type and custom taxonomy inside a class. Inside the WP admin, I see both the post type, and I see the taxonomy.

Simplified Code:

class Custom_Post_Type {

    function __construct($init_data) {

        if ( is_admin() ) {

            add_action( 'init', array( $this, 'create_ctp' ) );
            add_action( 'admin_head', array( $this, 'create_ctp_icons' ) );
            add_action( 'save_post', array( $this, 'save_ctp_custom_metadata' ), 1, 2 );

        }

    }

    function create_ctp_taxonomy() {
            register_taxonomy(
                $post_type.'_type',
                $post_type,
                array(
                    'labels' => array(
                        'name' => $taxonomy_label,
                        'add_new_item' => 'Add New '.$taxonomy_label
                    ),
                    'public' => true,
                    'show_ui' => true,
                    'show_tagcloud' => true,
                    'hierarchical' => true,
                    'show_in_nav_menus' => true,
                    'show_admin_column' => true
                )
            );

            register_post_type($post_type_slug,
                array(
                    'labels' => array(),
                    'public' => true,
                    'has_archive' => false,
                    'supports' => $this->supports,
                    'register_meta_box_cb' => array( $this, 'create_ctp_custom_metaboxes' ),
                    'taxonomies' => array( $taxonomy_slug ),
                )
            );
    }

}

Again, this works inside the admin area. I can add posts, and I can see the taxonomy and add terms.


Problem

On the front end, get_taxonomies() doesn't see the new custom taxonomy, and get_terms() doesn't see the terms inside it.

I tried several examples of of register_taxonomy , and when I used it outside of the class, it appears on the front end. However, when I moved the examples into my internal create_ctp_taxonomy function, they are suddenly invisible to get_taxonomies .

Any ideas why this would be occurring?


Edit

I've been playing around with different things and I think the issue here is the timing of the init action. When I call the setup function direction from the __construct function, rather than adding an action, then things start working. Example:

class Custom_Post_Type {

    function __construct($init_data) {

        if ( is_admin() ) {

            //add_action( 'init', array( $this, 'create_ctp' ) );
            add_action( 'admin_head', array( $this, 'create_ctp_icons' ) );
            add_action( 'save_post', array( $this, 'save_ctp_custom_metadata' ), 1, 2 );
        }

        $this->create_cpt();

    }

}

By doing this, I skip using init at all. However, this seems to violate standard practice. Is there a downside that anyone knows of for doing it this way?

There are a couple of things you need to be aware of when registering taxonomies to custom post types.

  1. Register the taxonomies first. This seems a bit counter intuitive but taxonomies are registered to post types, so they need to exist before the post type is created.
  2. You also need to register the taxonomy to the post type using the taxonomies argument of the register_post_type function.

Eg.

 register_post_type('cpt_name',array(
        'taxonomies'=>array(
              'taxomony_name1',
              'taxomony_name2')
         ,other_arguments...)
 );

From the docs

When registering a post type, always register your taxonomies using the taxonomies argument. If you do not, the taxonomies and post type will not be recognized as connected when using filters such as parse_query or pre_get_posts. This can lead to unexpected results and failures

Not Problems

1.) The problem isn't a race condition.

Conditionals like is_admin() still work when run from functions.php directly. This contradicts some information on the web, but as of WordPress 4.4, these do work.

2.) Calling the registration from add_action() rather than directly from __construct()

Switching to calling the registration directly had zero change. To be clear, there is no difference between:

  • $this->create_ctp()

  • add_action('init', array( $this, 'create_ctp' ) );

3.) Order of registering taxonomy vs CTP

When I moved my registration of the taxonomy in front of the CTP, it had zero change in behavior.


The Problem

I was using a conditional check of is_admin() , which I'd added previous to wrap when I added the admin dashicon. This is why my CTP was appearing on the backend, but not on the front.

I had removed it from my simplified example, so there was no way to tell from looking at the code that I'd posted.

So all I needed to do was remove the is_admin() check. A silly mistake it turns out, but useful to find the information about what things aren't actually problems.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM