Perhaps you’ve been here before: you want to show all of the categories in a particular ExpressionEngine category group, while also highlighting only those categories to which a particular entry belongs.
This is not something EE’s category tags can do natively, so I set out to find a way. I’ll show you what I discovered in this short tutorial.
Last things first: the final result
In case the concept is still abstract, here is a screenshot of the final result:

A list of all categories, with active ones checked
What you see is a portion of a Safecracker form for editing a single entry. I wanted to let the end user see all of the category options, as well as which categories were already selected for the current entry. A checkbox field seemed like a logical choice.
You’ll notice that some of the checkboxes are checked, and that there are no duplicate categories. I know…like magic.
How it’s done
In this example, I’m using an embedded template, but that may not be necessary for everyone. In your parent template, place the following code:
<h2>Type of Venue</h2> <div class="cats">{embed="includes/fetch_cats" cat_group="1" entry_id="{entry_id}"}</div>
Then, in your embedded template (includes/fetch_cats in this example), place the following code:
<?php // get all categories in the specified group $all_cats = $this->EE->db->query ( "SELECT cat_id, cat_name FROM exp_categories WHERE group_id = '{embed:cat_group}' ORDER BY cat_name" ); // loop through each cat returned, marking a box checked if the current entry is in that cat foreach ( $all_cats->result() as $row ) { $venue_cats = $this->EE->db->query ( "SELECT cat_id AS venue_cat_id FROM exp_category_posts WHERE entry_id='{embed:entry_id}' AND cat_id = '" . $row->cat_id . "'" ); if ( $venue_cats->num_rows() ) { echo '<label><input checked="checked" type="checkbox" name="category[]" value="' . $row->cat_id . '" /> ' . $row->cat_name . '</label>'; } else { echo '<label><input type="checkbox" name="category[]" value="' . $row->cat_id . '" /> ' . $row->cat_name . '</label>'; } } ?>
Be sure that your embedded template has PHP enabled on Output.
That’s all there is to it. The nice thing about using an embedded template is that it’s very modular; you can pass any category group ID and entry ID to it and it will return the expected categories.
5 comments
David McCormick
May 3, 2012Amazing – thanks very much, Ryan; I’d never have got there on my own.
It might be worth explicitly wrapping the embed code with php tags (because slow-to-catch-on types like me could end up stroking their chin and wondering why there’s loads of code showing up on their site).
Ryan
May 3, 2012Hey David,
I’m glad the tutorial helped! Good suggestion — I wrapped the embed code in php tags as you suggested.
Olivier
December 4, 2012Hi,
I am glad I found this, your bits of code is exactly what I am desperatly trying to achieve.
Unfortunately, the categories appear, but all selected.
Any idea what might be wrong?
Thanks in advance
Olivier
December 4, 2012Nevermind, I found the problem: the {embed} was outside of the channel:entries so the {entry_id} wasn’t taken in consideration. Stupid.
Thanks a lot for the tutorial, it saved my day ^__^
Ryan
December 4, 2012Hey Olivier, I’m glad you found the problem and that you found the tutorial helpful. Awesome!