GeoDirectory categories are normal WordPress taxonomy terms. Each post type has its own category taxonomy, named after the post type with category on the end: Places use gd_placecategory, and a post type called gd_event uses gd_eventcategory. That means a standard tax_query works and you don’t need a custom join.
To find a category ID, go to Places > Categories, hover over the category and look for tag_ID= in the edit link.
With WP_Query
$query = new WP_Query( array(
'post_type' => 'gd_place',
'post_status' => 'publish',
'posts_per_page' => 20, // -1 for all
'tax_query' => array(
array(
'taxonomy' => 'gd_placecategory',
'field' => 'term_id',
'terms' => array( 85 ),
'include_children' => true,
),
),
) );
if ( $query->have_posts() ) {
while ( $query->have_posts() ) {
$query->the_post();
echo '<a href="' . esc_url( get_permalink() ) . '">' . esc_html( get_the_title() ) . '</a><br>';
}
wp_reset_postdata();
}
To read a GeoDirectory field inside the loop, use geodir_get_post_meta( get_the_ID(), 'phone', true ), where the second argument is the field key.
With geodir_get_widget_listings()
This is the function behind GD > Listings. It reads from the GeoDirectory listing table, so every result already has the custom field values, and it accepts GeoDirectory sort values such as az and latest.
$listings = geodir_get_widget_listings( array(
'post_type' => 'gd_place',
'posts_per_page' => 20,
'order_by' => 'az',
'tax_query' => array(
array(
'taxonomy' => 'gd_placecategory',
'field' => 'id',
'terms' => array( 85 ),
),
),
) );
foreach ( $listings as $listing ) {
echo esc_html( $listing->post_title ) . '<br>';
}
With the REST API
https://example.com/wp-json/geodir/v2/places/?gd_placecategory=85
Here places is the post type’s slug. See Endpoints and Filter search results from the GeoDirectory REST API.
Without code
To display the listings rather than process them, the GD > Listings widget has a Categories filter: [gd_listings post_type="gd_place" category="85"].