This is a lot simpler than you might believe, first, I must dispel some misconceptions:
post_type
is not a parameter ofget_categories
, isn’t listed in the documentation, and wouldn’t make sense. Categories are terms not posts, they don’t have a post type, and this API call retrieves terms, it has no business looking into the posts table- When the page just suddenly abruptly stops, it usually means there was a PHP fatal error. Check your PHP error logs for the reason, and look up debugging in WordPress
- Reusing the post categories is messy, things would be much better if you used a custom taxonomy instead. Additionally it makes the APIs more useful, as you don’t have to figure out how many of a term are one post type, and how many are of another.
- APIs such as
get_categories
are higher level helper functions, mostly there for backwards compatibility. As a result they tend to have “strings attached”. Use the terms API instead, it works the same for all taxonomies be they tags, categories, or something you registered yourself. - You never checked if what you were given was what you expected! What if no categories had been found! Or it returned a
WP_Error
object? get_template_part
is an amazing function, don’t ignore it and write super long files, break it up- There’s no escaping in your code example, this is a major security issue. Anybody can insert any HTML they want by putting it in a term title, use
esc_html
etc
So finally, you kind of had the answer to begin with:
grab the terms
for each term
display the terms title
grab the posts of type "attractions" that have that term
for each post
display it
So lets break that apart and fetch the terms:
$terms = get_terms([
'taxonomy' => 'category',
'order' => 'asc',
'orderby' => 'name',
]);
if ( !empty( $terms ) && !is_wp_error( $terms ) ) {
echo '<h3>'.esc_html( $term->name ).'</h3>';
foreach ( $terms as $term ) {
// .. display posts
}
}
Then for your post loop:
$args = [
'post_type' => 'attractions',
'cat' => $term->term_id,
];
$query = new WP_Query( $args );
// etc..