Ask your WordPress questions! Pay money and get answers fast! (more info)

Related custom posts of a custom taxonomy WordPress

  • SOLVED

I'm coding a Wordpress theme that has a jobs board. The custom post type is "job" and the custom taxonomy in use is "sector". In single-job.php, after the single post information, I need to be able to query and display a few job posts that have the same sector taxonomy.

So if for example the single job has the sector of "accounting" then four more jobs with the sector of "accounting" will be displayed.

Answers (2)

2011-02-07

Michael Fields answers:

I would try something like this:
<?php
$jobs = get_posts( array(
'term' => 'accounting',
'taxonomy' => 'sector',
'post_type' => 'job',
'post_status' => 'publish',
) );

if ( $jobs ) {
$_post = $post;
print '<ul>';
foreach ( (array) $jobs as $post ) {
setup_postdata( $post );
the_title( '<li><a href="' . esc_url( get_permalink() ) . '">', '</a></li>' );
}
print '</ul>';
$post = $_post;
}
?>


James Beardmore comments:

Wow, nice, thats really close. The only difference being the sector of accounting up top is just an example, not a hard coded constant.

This needs to detect what term the single post is, and return say, 4 posts in that particular taxonomy term.

So if one job post has the sector "accounting", then it returns 4 job posts with the sector of "accounting". But if a job post has the sector of "pensions" then the 4 or however many posts returned will be from the sector of "pensions".

Simple enough for traditional posts but I can't get the same method to work with custom post types.



Michael Fields comments:

Opps, missed that on first glance. Please try this:
<?php
$sector = null;
$sectors = get_the_terms( get_the_ID(), 'mfields_bookmark_type' );
if ( ! is_wp_error( $sectors ) ) {
$term = array_shift( $sectors );

/* Query for jobs that are in the sector. */
$jobs = null;
if ( isset( $term->slug ) && isset( $term->taxonomy ) ) {
$jobs = get_posts( array(
'term' => $term->slug,
'taxonomy' => $term->taxonomy,
'post_type' => 'job',
'post_status' => 'publish',
) );
}

/* Loop over all jobs and display an unordered list. */
if ( $jobs ) {
$_post = $post;
print '<ul>';
foreach ( (array) $jobs as $post ) {
setup_postdata( $post );
the_title( '<li><a href="' . esc_url( get_permalink() ) . '">', '</a></li>' );
}
print '</ul>';
$post = $_post;
}
}
?>


Michael Fields comments:

This code will only use the first term returned by get_the_terms(). I have not found it possible to restrict taxonomies to one term-per-post completely. This is as close to a solution as I think is possible. Please let me know your thoughts.

Best wishes,
-Mike


James Beardmore comments:

Hmm, no, this isn't returning anything.


Michael Fields comments:

Opps, left in my own custom taxonomy from testing. You'll want to change mfields_bookmark_type to sector.
<?php
$sectors = get_the_terms( get_the_ID(), 'sector' );
if ( ! is_wp_error( $sectors ) ) {
$term = array_shift( $sectors );

/* Query for jobs that are in the sector. */
$jobs = null;
if ( isset( $term->slug ) && isset( $term->taxonomy ) ) {
$jobs = get_posts( array(
'term' => $term->slug,
'taxonomy' => $term->taxonomy,
'post_type' => 'job',
'post_status' => 'publish',
) );
}

/* Loop over all jobs and display an unordered list. */
if ( $jobs ) {
$_post = $post;
print '<ul>';
foreach ( (array) $jobs as $post ) {
setup_postdata( $post );
the_title( '<li><a href="' . esc_url( get_permalink() ) . '">', '</a></li>' );
}
print '</ul>';
$post = $_post;
}
}
?>


Michael Fields comments:

Could also be improved by adding another condition to this line:
if ( ! is_wp_error( $sectors ) && is_array( $sectors ) ) {


Michael Fields comments:

Please try the following in the arguments sent to get_posts():

'exclude' => get_the_ID()

This will remove the global job from the result set.

2011-02-07

Ivaylo Draganov answers:

Hello,

I'd suggest using a tax query. But it would work only in the upcoming Wordpress 3.1. It's due to be released very soon so I think it's a good idea to be used on sites under development. Here's what I've put up:

<?php

// get terms for current post under taxonomy 'sector'
$post_terms = wp_get_post_terms($post->ID, 'sector');

// if there are any terms
if ($post_terms) {

// pull their IDs and put them in an array
$term_ids = array();
foreach($post_terms as $individual_term) {
$term_ids[] = $individual_term->term_id;
}

// setup query args
$args=array(
'tax_query' => array(
'taxonomy' => 'sector',
'field' => 'id',
'terms' => $term_ids
),
'post__not_in' => array($post->ID),
'posts_per_page'=>5,
'ignore_sticky_posts'=>1
);

// run query (can also be done with query_posts)
$related_posts = get_posts($args);

// loop through query results if any
if ($related_posts) {

echo '<ul>';

foreach($related_posts as $post) {

// I think this one might not be necessary for a simple list of titles; try uncommenting if nothing shows up
// setup_postdata($post);

the_title( '<li><a href="' . esc_url( get_permalink() ) . '">', '</a></li>' );

}

echo '</ul>';

}

}
?>


And again: <strong>It will work only in Wordpress 3.1</strong>


James Beardmore comments:

@iv.draganov

This looks like an elegant solutions, but I've got the bleeding edge nightly of 3.1 installed and this is bringing me no results.

@Michael Fields, that works, I'm just trying to find a way so that it won't include the current post. If you or I find that I'll mark this finished.


James Beardmore comments:

@iv.draganov, From what I can see in your code, it looks like its to work with normal wordpress posts. I am needing something to retrieve custom posts with the post type job.


Ivaylo Draganov comments:

Yes, there was an error in the query args. And I've completely overlooked that you're using a custom post type. Try replacing the query args array with this:

// setup query args
$args=array(
'tax_query' => array(
'taxonomy' => 'sector',
'field' => 'id',
'terms' => $term_ids
),
'post__not_in' => array($post->ID),
'posts_per_page'=>5,
'ignore_sticky_posts'=>1
);