Register Taxonomy earlier so it can be used in functions.php and admin-ajax.php

This is a follow up to this post, outlining why I can not use the get_terms function while in functions.php (actually calling via ajax/admin_ajax.php).

I can grab the terms (custom tax) on any post, on any page, except when in my ajax function. I receive the dreaded ‘taxonomy does not exist’ error when dumping the value of get_terms.

Read More

The problem is, the taxonomy is registered after I call the function to find the terms.

The question is, how do I register the tax early enough so I can use this function? My code to register the custom post type and taxonomy is first in my functions.php (included via an external php to keep functions.php clean)

/************************************************ 
*
* 1.0 ------------------ Events ----------------
*
************************************************/


// 1. Custom Post Type Registration (Events)
add_action( 'init', 'create_event_postype', 0 );

function create_event_postype() {
  $labels = array(
    'name' => _x('Events', 'post type general name'),
    'singular_name' => _x('Event', 'post type singular name'),
    'add_new' => _x('Add New', 'events'),
    'add_new_item' => __('Add New Event'),
    'edit_item' => __('Edit Event'),
    'new_item' => __('New Event'),
    'view_item' => __('View Event'),
    'search_items' => __('Search Events'),
    'not_found' =>  __('No events found'),
    'not_found_in_trash' => __('No events found in Trash'),
    'parent_item_colon' => '',
);

$args = array(
    'label' => __('Events'),
    'labels' => $labels,
    'public' => true,
    'can_export' => true,
    'show_ui' => true,
    '_builtin' => false,
    '_edit_link' => 'post.php?post=%d', // ?
    'capability_type' => 'post',
    'menu_icon' => get_bloginfo('template_url').'/images/icons/events.png',
    'hierarchical' => false,
    'rewrite' => array( "slug" => "events" ),
    'supports'=> array('title', 'thumbnail', 'excerpt', 'editor', 'custom-fields') ,
    'show_in_nav_menus' => true,
    'taxonomies' => array('post_tag', 'tf_eventtype')
);

register_post_type( 'tf_events', $args);

}

// 2. Custom Taxonomy Registration (Event Types)
add_action( 'init', 'create_eventtype_taxonomy', 0 );
function create_eventtype_taxonomy() {

  $labels = array(
    'name' => _x( 'Event Type', 'taxonomy general name' ),
    'singular_name' => _x( 'Event Type', 'taxonomy singular name' ),
    'search_items' =>  __( 'Search Event Types' ),
    'popular_items' => __( 'Popular Event Types' ),
    'all_items' => __( 'All Event Types' ),
    'parent_item' => null,
    'parent_item_colon' => null,
    'edit_item' => __( 'Edit Event Type' ),
    'update_item' => __( 'Update Event Type' ),
    'add_new_item' => __( 'Add New Event Type' ),
    'new_item_name' => __( 'New Event Type Name' ),
    'separate_items_with_commas' => __( 'Separate event types with commas' ),
    'add_or_remove_items' => __( 'Add or remove event types' ),
    'choose_from_most_used' => __( 'Choose from the most used event types' ),
);

register_taxonomy('tf_eventtype','tf_events', array(
    'label' => __('Event Type'),
    'labels' => $labels,
    'hierarchical' => true,
    'show_ui' => true,
    'query_var' => true,
    'rewrite' => array( 'slug' => 'event-type' ),
));
}

Here is some pseudo code to show how I’m calling this function

from a custom page, I call a function via AJAX (ajax-admin.php)

$.ajax({  
            type: "POST",  
            url: "<? bloginfo('url'); ?>/wp-admin/admin-ajax.php", //Built in WP AJAX
            data: data, 
            success:  function(data){
                         //console.log('search complete');
                         $("#event-list").html(data)                                                         
                         }  
    });

Here is the function that calls a custom query, and where get_terms fails.

/****************************************************************
*
* 1.0 Calendar AJAX Queries
*
****************************************************************/
// if both logged in and not logged in users can send this AJAX request,
// add both of these actions, otherwise add only the appropriate one
add_action( 'wp_ajax_nopriv_calendar_search', 'calendar_search' );
add_action( 'wp_ajax_calendar_search', 'calendar_search' );

function calendar_search() {        
        $args = array(
            'post_type' => 'tf_events',         
            'post_status' => 'publish',
            'order' => 'ASC'
        );

        $query = new WP_Query( $args ); 

        // - loop start -
        if ( $query->have_posts() ) {

         while ($query->have_posts()) : $query->the_post(); /*Shows the posts that are available. */

                //Event Type
                $cats = get_the_terms($post->ID , 'tf_eventtype'); //the function that fails. All other custom data works fine 

                echo 
                '<article class="post" id="post-'. $post->ID . '"  itemscope itemtype="http://schema.org/Event">                       
                   <time></time>
                   <h2  itemprop="name" class="entry-title"><a href="' . get_permalink() .'">'. get_the_title() . '</a></h2>                
                   <div class="entry">
                     <p itemprop="location">';
                       if($cats) foreach($cats as $cat){ 
                            echo " | " . $cat->name;
                       }
                       echo 
                     "</p>  
                   </div><!--#entry-->
                 </article>";

            endwhile; 
         } else {
            echo "<h2 class='month'>Sorry, no events found!</h2>";            
          } 
        die(); // this is required to return a proper result      

}

Related posts

3 comments

  1. So, thanks to G. M.’s help I was able to debug the problem more efficiently, now that I knew init was indeed not being called. I started stripping out all extraneous functions from my functions.php file and I realized I called do_action twice, as I have many functions run through admin-ajax.php. The do_action calls must only be used once! Odd how the bug presented itself!

    $action = isset($_POST['action']) ? $_POST['action'] : null;
    
    //These functions take an ajax call and then call the appropriate PHP function
    // this hook is fired if the current viewer is not logged in
    do_action( 'wp_ajax_nopriv_' . $action );
    do_action( 'wp_ajax_' . $action );
    
  2. Just add global $post; before use $post variable:

    while ($query->have_posts()) : $query->the_post();
      global $post;
      $cats = get_the_terms($post->ID , 'tf_eventtype');
      //... and so on
    
  3. The “invalid taxonomy” message occurs because when the ajax call is made, not all the taxonomies have been registered because all the plugins have not been initialized.

    the solution is to launch the hook ajax after the initialization and so it works ok

    ex.

            add_action( 'init', function() {
    
                //add the ajax hook only when all the taxonomies have been registered
                add_action('wp_ajax_my_action',  function() {
    
                    $result = get_terms( 'my_taxonomy_name' );
                }
    
            }, 99);
    

Comments are closed.