Take the 2-minute tour ×
WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. It's 100% free, no registration required.

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.

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      

}

share|improve this question
2  
Show us where you are attempting to use get_terms. init action should run before any properly hooked ajax requests. –  Milo Oct 17 '13 at 16:02
    
+1 for @Milo. init action is triggered before wp_ajax_* actions. After that, using functions.php earlier hook available is after_setup_theme. –  G. M. Oct 17 '13 at 16:05
    
I have a custom calendar page and an ajax call queries the database (wp_query). I use get_terms inside the custom query, inside my ajax-functions include. How can I show you this code? page-calendar.php > ajax call through admin-ajax.php > custom wp_query > get_terms inside the loop –  Nate Oct 17 '13 at 16:13
    
Just added the ajax call and the functions that get called. Yes, I include the files, only to keep my functions.php cleaner. –  Nate Oct 17 '13 at 16:24
    
What is odd, is I can manually call get_terms (passing a post ID) anywhere else on my page - it only fails when inside my calendar_search() function –  Nate Oct 17 '13 at 16:27

2 Answers 2

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 );
share|improve this answer
1  
how do you have things set up where you have to manually call do_action to fire ajax callbacks? you're doing something strange. –  Milo Oct 18 '13 at 0:03
    
Strange isn't good, so please let me know if you have a better suggestion. Basically, the do_action routes the ajax call to the different php functions in functions.php (using add_action). Tutorial was from here, under "Best Practices" –  Nate Oct 18 '13 at 14:33
    
I don't think they're telling you to add that code, that's the code that's in admin-ajax.php that fires your ajax callback, see it in source here. –  Milo Oct 18 '13 at 14:55

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
share|improve this answer
    
I wish it were that easy! Still getting the same error. object(WP_Error)#188 (2) { ["errors"]=> array(1) { ["invalid_taxonomy"]=> array(1) { [0]=> string(16) "Invalid taxonomy" } } ["error_data"]=> array(0) { } } –  Nate Oct 17 '13 at 16:45
    
Your code work for me (after adding global $post;), I've tested. Are you sure that the file with code that register taxonomy is included? Try to add a die on first line, what happen? @Nate –  G. M. Oct 17 '13 at 16:50
    
die() on the first line of calendar_search()? I will try right now. Yes, there might be another culprit involved. I have used this same code on another site and have never seen the particular error. –  Nate Oct 17 '13 at 16:59
    
Yes, die() kills the script both on calendar_search() and before I register my taxonomy. Again, get_terms works everywhere on the page/site except in this one function. –  Nate Oct 17 '13 at 17:03
    
Try to put if ( did_action('init') ) die('inited'); as 1st line of calendar_search() function. It will prove init is performed and problem is elsewhere, even if I can't see where... –  G. M. Oct 17 '13 at 17:23

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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