I found my answer to this query. Using a simplified version of my original code I can pass in a category to show just that category or if empty it shows all categories. A foreach conditional then runs through all the available categories and exhausts the posts in each during the query.
I hope this helps someone at some point 🙂
//MENU SHORTCODE
add_shortcode('himenu', 'create_menu_shortcode');
function create_menu_shortcode ($atts){
$atts = shortcode_atts(
array(
'category' => ''
), $atts, 'himenu' );
$category = $atts["category"];
?> <?php
var_dump ($atts);
var_dump ($category);
$args_cat = [
'orderby' => 'name',
'order' => 'ASC',
'hide_empty' => 0,
];
$menu_categories = get_categories($args_cat);
//print_r($categories);
if (!empty($menu_categories)):
foreach ($menu_categories as $menu_category):
$args = [
'post_type' => 'menu_item',
'posts_per_page' => -1,
'order' => 'ASC',
'orderby' => 'title',
'category_name' => $category,
'cat' => $menu_category->term_id
];
$query = new WP_Query($args);
while ($query->have_posts()) : $query->the_post(); ?>
<div class="indi-menu-item">
<div class="menu-item-column">
<h5> <?php the_category(); ?></h5>
<div class="menu-item-meta">
<h4> <?php the_title(); ?></h4>
<p><?php the_field('description')?></p>
</div>
</div>
<div class="menu-item-column">
<h2>£<?php the_field('price'); ?></h2>
</div>
</div>
<?php endwhile;
wp_reset_postdata();
endforeach;
endif;?>
</div>
<?php } ?>
<?php wp_reset_query();//reset the global variable related to post loop
?>