Pay money and get answers for your WordPress questions (more info)

Display custom post types within a specific category

  • SOLVED

Plugins being used: [[LINK href="http://www.advancedcustomfields.com/"]]Advanced Custom Fields[[/LINK]]

I have a custom post type named Tournaments. I assign categories based on the status of the Tournament: upcoming-tournament or finished-tournament.

I have a page made for each team in the Volleyball club, i.e. Team Blue. I created a Relationship Custom Field named "tournaments" that is available to each team page.

I'd like to display the 4 most recent Tournaments that are categorized as upcoming-tournament. I'd then like to display the 4 most recent Tournaments that are categorized as finished-tournament.

I've included the start of my code below. What I need help with is filling in the areas that are commented out. Basically, I need help writing the loop!


<!-- this will grab all the tournaments that the team is participating in -->
<?php $tournaments = get_field( 'tournament_selection' );

if( $tournaments ) { ?>

<h3>Upcoming Tournaments</h3>

<?php foreach( $tournaments as $tournament ) {

// if $tournament has taxonomy "upcoming-tournament"...

} ?>



<h3>Finished Tournaments</h3>

<?php foreach( $tournaments as $tournament ) {

// if $tournament has taxonomy "finished-tournament"...

} ?>

<?php } ?>

Answers (3)

2013-01-25

John Cotton answers:

I think you probably need to use [[LINK href="http://codex.wordpress.org/Function_Reference/wp_get_object_terms"]]wp_get_object_terms[[/LINK]].

I assuming that your $tournaments is an array of custom post ids? If so then


<?php
if( $tournaments ) {
$upcoming = '';
$finished = '';

foreach( $tournaments as $tournament ) {
// You could get more info back by changing the fields param, but that would make the in_array compare different...
$terms = wp_get_object_terms( $tournament, array('orderby' => 'name', 'order' => 'ASC', 'fields' => 'slug') );

if( in_array( 'upcoming-tournament', $terms ) ) {
$upcoming .= 'Upcoming!' // edit to whatever it is you want to say
}

if( in_array( 'finished-tournament', $terms ) ) {
$upcoming .= 'Finished!' // edit to whatever it is you want to say
}
}
?>

<h3>Upcoming Tournaments</h3>
<?php echo $upcoming; ?>

<h3>Finished Tournaments</h3>
<?php echo $finished; ?>


Dave Schmidt comments:

Hi John,

I'm getting an error on the page. [[LINK href="http://vitalvolleyball.com/teams/test/"]]http://vitalvolleyball.com/teams/test/[[/LINK]]

Your syntax looks fine though. Any ideas? Here's the code I'm adding:


<?php

$tournaments = get_field( 'tournament_selection' );

if( $tournaments ) {

$upcoming = '';

$finished = '';

foreach( $tournaments as $tournament ) {

// You could get more info back by changing the fields param, but that would make the in_array compare different...

$terms = wp_get_object_terms( $tournament, array('orderby' => 'name', 'order' => 'ASC', 'fields' => 'slug') );



if( in_array( 'upcoming-tournament', $terms ) ) {

$upcoming .= 'Upcoming!' // edit to whatever it is you want to say

}



if( in_array( 'finished-tournament', $terms ) ) {

$finished .= 'Finished!' // edit to whatever it is you want to say

}

}

?>



<h3>Upcoming Tournaments</h3>

<?php echo $upcoming; ?>



<h3>Finished Tournaments</h3>

<?php echo $finished; ?>



Any thoughts?


John Cotton comments:

It's missing a } before the last ?><h3>Upcoming Tournaments</h3>


John Cotton comments:

Actually, it should be like this in case there are no tournaments:




<?php



$tournaments = get_field( 'tournament_selection' );



if( $tournaments ) {



$upcoming = '';



$finished = '';



foreach( $tournaments as $tournament ) {



// You could get more info back by changing the fields param, but that would make the in_array compare different...



$terms = wp_get_object_terms( $tournament, array('orderby' => 'name', 'order' => 'ASC', 'fields' => 'slug') );







if( in_array( 'upcoming-tournament', $terms ) ) {



$upcoming .= 'Upcoming!' // edit to whatever it is you want to say



}







if( in_array( 'finished-tournament', $terms ) ) {



$finished .= 'Finished!' // edit to whatever it is you want to say



}



}



?>

<h3>Upcoming Tournaments</h3>
<?php echo $upcoming; ?>

<h3>Finished Tournaments</h3>
<?php echo $finished; ?>
<?php
}
?>


Dave Schmidt comments:

Hmm, still getting a page error. I deleted everything else in the template and still get the error. Your idea looks promising though!


John Cotton comments:

Have you copied my last code?

Can you pastebin your template so that I can see the whole context?

You're just missing a closing bracket somewhere I think


Dave Schmidt comments:

[[LINK href="http://pastebin.com/f8tjpF4S"]]http://pastebin.com/f8tjpF4S[[/LINK]]


John Cotton comments:

These two lines are missing semi-colons:



$upcoming .= 'Upcoming!'


$finished .= 'Finished!'


Dave Schmidt comments:

Believe it or not they're actually in there. I selected PHP as the syntax on Pastebin and it stripped them out. But in my WP template they're there. Hmmm...


Dave Schmidt comments:

Hang on, I see what you were referring to. Those two calls were missing the semi-colons at the top of the query. Sorry!


Dave Schmidt comments:

John, looks like we're getting closer. The page is spitting out some array() errors. Check it out: [[LINK href="http://vitalvolleyball.com/teams/test/"]]http://vitalvolleyball.com/teams/test/[[/LINK]]


John Cotton comments:

Soory, also, this line needs editing to add the taxonomies:


$terms = wp_get_object_terms( $tournament, array('orderby' => 'name', 'order' => 'ASC', 'fields' => 'slug') );

should be


$terms = wp_get_object_terms( $tournament, 'category', array('orderby' => 'name', 'order' => 'ASC', 'fields' => 'slug') );
or whatever taxonomy you are using (you can pass an array if it's more than one)


Dave Schmidt comments:

OK, so I don't have a custom taxonomy set up for the custom post type. I'm just using global categories. Any ideas how I set that up in the 'category' section of the $terms?


John Cotton comments:

<blockquote> Any ideas how I set that up in the 'category' section of the $terms?</blockquote>

That's what my code does. Just copy the corrected line in place of the incorrect one.


Dave Schmidt comments:

So if I'm passing in the possible two categories, is this how the array should look like? Because it's giving me an error. I'm really terrible at this stuff, sorry John!


$terms = wp_get_object_terms( $tournament, array('upcoming-tournament', 'finished-tournament'), array('orderby' => 'meta_value', 'meta_key' => 'tournament_date', 'order' => 'ASC', 'fields' => 'slug') );


John Cotton comments:

The line is just

$terms = wp_get_object_terms( $tournament, 'category', array('orderby' => 'name', 'order' => 'ASC', 'fields' => 'slug') );

The middle param is the <em>taxonomy</em> <strong>NOT</strong> the <em>terms</em>.


Dave Schmidt comments:

OK cool. By the way, I'm going to increase the payout on this John! So stick with me until it's sorted out. :)

The errors disappeared. That's good!

So here's what I want to display for any posts that match the criteria:


<ul>
<li>
<a href="<?php echo get_permalink(); ?>"><?php the_field('tournament_name', $tournament->ID); ?></a>

<span>
<?php $date = DateTime::createFromFormat('Ymd', get_field('tournament_date', $tournament->ID));
echo $date->format('F d, Y'); ?>
</span>
</li>
</ul>


John Cotton comments:

<blockquote>So here's what I want to display for any posts that match the criteria:</blockquote>

Stick this somewhere near the top (having a function makes the code neater and saves repeating...)

function format_tournament( $id ) {
$date = DateTime::createFromFormat( 'Ymd', get_field('tournament_date', $id) );

return sprintf( '<li><a href="%s">%s</a><span>%s</span></li>', get_permalink($id), get_field('tournament_name', $id), $date->format('F d, Y') );

}



And mod the loop as follows:


foreach( $tournaments as $tournament ) {

$terms = wp_get_object_terms( $tournament, array('orderby' => 'name', 'order' => 'ASC', 'fields' => 'slug') );

if( in_array( 'upcoming-tournament', $terms ) ) {
$upcoming .= format_tournament( $tournament->ID );
}


if( in_array( 'finished-tournament', $terms ) ) {
$finished .= format_tournament( $tournament->ID );
}
}


Finally, change the output to


<h3>Upcoming Tournaments</h3>
<ul><?php echo $upcoming; ?></ul>


<h3>Finished Tournaments</h3>
<ul><?php echo $finished; ?></ul>


Dave Schmidt comments:

OK, code looks great! Unfortunately nothing is displaying on the page. I verified that there are Tournaments categorized as both "upcoming-tournament" and "finished-tournament." Here is the code I have in the template. Sorry to be a pain, but I feel we're so close!


<?php

$tournaments = get_field( 'tournament_selection' );


function format_tournament( $id ) {
$date = DateTime::createFromFormat( 'Ymd', get_field('tournament_date', $id) );
return sprintf( '<li><a href="%s">%s</a><span>%s</span></li>', get_permalink($id), get_field('tournament_name', $id), $date->format('F d, Y') );
}


if( $tournaments ) {

$upcoming = '';
$finished = '';


foreach( $tournaments as $tournament ) {

$terms = wp_get_object_terms( $tournament, 'category', array('orderby' => 'name', 'order' => 'ASC', 'fields' => 'slug') );

if( in_array( 'upcoming-tournament', $terms ) ) {
$upcoming .= format_tournament( $tournament->ID );
}

if( in_array( 'finished-tournament', $terms ) ) {
$finished .= format_tournament( $tournament->ID );
}
}

?>


<h3>Upcoming Tournaments</h3>
<ul><?php echo $upcoming; ?></ul>

<h3>Finished Tournaments</h3>
<ul><?php echo $finished; ?></ul>


<?php

}

?>


John Cotton comments:

This

format_tournament( $tournament->ID );

should be

format_tournament( $tournament );


Dave Schmidt comments:

I still don't get anything to display. :(

Here's a pastebin: [[LINK href="http://pastebin.com/ivuprSrr"]]http://pastebin.com/ivuprSrr[[/LINK]]

And if you take a look at the test page I did a variable dump. So I can tell that the tournaments are being pulled in correctly.


John Cotton comments:

OK my mistake - try this:


foreach( $tournaments as $tournament ) {
print_r( $tournament->ID );
$terms = wp_get_object_terms( $tournament->ID, 'category', array('orderby' => 'name', 'order' => 'ASC', 'fields' => 'slug') );

if( in_array( 'upcoming-tournament', $terms ) ) {
$upcoming .= format_tournament( $tournament->ID );
}

if( in_array( 'finished-tournament', $terms ) ) {
$finished .= format_tournament( $tournament->ID );
}
}


If that works, then the print_r line can be removed. If not, it might tell us something.


Dave Schmidt comments:

So nothing displays, but the print_r does display the 3 ID's of the tournaments that are supposed to be visible. So at least it can pull in the ID's.


John Cotton comments:

So just so we know completely what's going on try

print_r( $tournament->ID ); echo '<br/>';
$terms = wp_get_object_terms( $tournament->ID, 'category', array('orderby' => 'name', 'order' => 'ASC', 'fields' => 'slug') );
print_r( $terms ); echo '<br/>';


Dave Schmidt comments:

John, you have an honest face. Would it help if I messaged you some FTP creds?


Dave Schmidt comments:

Done. Nothing is showing up in the array.


John Cotton comments:

<blockquote>John, you have an honest face. Would it help if I messaged you some FTP creds?</blockquote>
:) It would probably be quicker...

2013-01-25

Francisco Javier Carazo Gil answers:

You can use has_term: http://codex.wordpress.org/Function_Reference/has_term


Francisco Javier Carazo Gil comments:

Make the loop and change the foreach for the loop.

Then, with the post object loaded, you can do directly it: if( has_term( 'your-taxonomy', 'finished-tournament' ) ) {
// do something
}


Dave Schmidt comments:

Any ideas on how to put that all together? Consider me a novice multiple loops kind of guy.

2013-01-25

Dylan Kuhn answers:

I think even without loading the post object, this may work:


if ( has_term( 'your-taxonomy', 'finished-tournament', $tournament ) ) {
// do something
}