0

I am using this code to retrieve category:

$post_id = get_the_ID();
  $countries = get_the_terms( $post_id, 'country' );
  $fcountry = $countries[0]->slug;

However this sometimes retrieves the parent category of the countries (in our scenario the continent). How could I make this to always output the child category (i.e. the country)?

4
  • In the cases where it is wrong, did you do something like var_dump($countries); to see if the correct one is in there? Because you've hardcoded it to always take the first category from the result set, this may be wrong
    – kero
    Dec 16, 2020 at 13:48
  • Yes this is my question, ideally I would like to define parent and child in separate variables. There is always going to be 1 parent for each child.
    – JoaMika
    Dec 16, 2020 at 13:54
  • Can a post have multiple parent & child categories? Or will there always be only 1 child ever (and 1 parent)?
    – kero
    Dec 16, 2020 at 14:12
  • only 1 child and 1 parent (continent/country) - this is a custom taxonomy as well
    – JoaMika
    Dec 16, 2020 at 14:23

1 Answer 1

1

So if I understand correctly, the problem here is that get_the_terms(..) returns both the parent and child category. As you said in the comment, there will only ever be 1 parent and 1 child in it, we can use that information to get the correct term.

Basically we need to filter the results, we know that one will have parent not set while the other has it, so just get the latter one.

function joamika_get_country_from_post(int $postId): ?string {
    $countries = get_the_terms($postId, 'country');
    if (!is_array($countries)) {
        return null;
    }
    array_filter($countries, function(\WP_Term $term): bool {
        return $term->parent !== 0;
    });
    if (empty($countries)) {
        return null;
    }
    return $countries[0]->slug;
}

$fcountry = joamika_get_country_from_post($post_id);
if ($fcountry === null) {
    // something went wrong
}

// continue with your logic

If this is your first time seeing something like foo(int $postId): ?string {, don't worry. You can remove them or keep them. I prefer my PHP code to be as strictly typed as possible - you can read more about the topic here.

You still need to think about handling the case when no country is found.

7
  • I will give this a shot but are the if functions nested correctly? seems that if sth goes wrong $fcountry will still get defined
    – JoaMika
    Dec 16, 2020 at 14:51
  • @JoaMika they are correct in the sense that this should give you a base to work with. You'd probably want to put all of this in a function that returns a string, and work your application's logic around that. So the // something went wrong blocks would return ''; and a success returns the slug. Then $my_slug = get_fcountry_slug( $post_id ); and use that as needed. You'll have to figure out what to do in the case of getting an empty string, since you can't always 100% be sure you'll get something useful back.
    – phatskat
    Dec 16, 2020 at 14:58
  • thank you for your help, I will try to create this custom function, though I am not this good :(
    – JoaMika
    Dec 16, 2020 at 15:05
  • @JoaMika I've put it inside a function. Will add a short description now.
    – kero
    Dec 16, 2020 at 15:12
  • ok this is very helpful, many thanks :)
    – JoaMika
    Dec 16, 2020 at 17:32

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.