WordPress function in_category not working as expected

This is driving me crazy, and I have tried a variety of different things. Essentially, the desired effect is to target two different categories in WordPress using the built in in_category function.

Here is my code as it stands currently:

Read More
if(in_category( array("Snacks", "Other Nuts") )) :
 //do something
endif;

This will work with the category Snacks but not with the category Other Nuts. When I replace Other Nuts with another category name, like Confections, it works perfectly.

I am assuming this has something to do with the space in the category name Other Nuts. Though, I have tried using it’s category ID and category slug to no avail.

Any idea what’s going on here??

Related posts

Leave a Reply

2 comments

  1. Figured it out.

    Let’s say you have two categories, one is a parent of the other, like so:

    Other Nuts (Parent)
        Almonds (Child)
    

    If you make a post in WordPress and categorize it in Almonds and run a simple loop like

    if(have_posts()) :
      while(have_posts()) : the_post();
    
      // run your loop
    
      endwhile;
    endif;
    

    You would get the output of the Almonds post that belongs to the Other Nuts parent category that’s categorized in Almonds. Now, if you were to run this loop instead:

    if(have_posts()) :
      while(have_posts()) : the_post();
    
        if(in_category('Other Nuts')) :  
    
           // run your loop
    
        endif;
    
      endwhile;
    endif;
    

    You would get nothing. The reason is because you have only categorized the post in Almonds and not also in Other Nuts. WordPress doesn’t make the connection between the parent and child category in this case. Being categorized in the child doesn’t also categorize it in the parent.

  2. Essentially, this should check all current category IDs for the post against all of the ID’s that you’re expecting, then check all of the parent category IDs against what you’re expecting. You could compare the category names, instead, with a slight variation to this code.

    Step 1: Put this in your functions.php file:

    function check_category_family( $categories, $expected_ids ){
      foreach( $categories as $i ){
        if( in_array( intval( $i->category_parent ), $expected_ids ) ){
          return true;
        }
      }
    }
    

    Step 2: Put this psuedo-code into whatever category template(s) you’re building:

    $categories = get_the_category();
    $expected_ids = array( /*PUT YOUR CATEGORY IDS AS INTEGERS IN HERE*/ );
    
    if( in_category( $expected_ids ) || check_category_family( $categories, $expected_ids ) ){
      //run the loop
    } else {
      //redirect?
    }