We use cookies to improve your experience. No personal information is gathered and we don't serve ads. Cookies Policy.

ExpressionEngine Logo ExpressionEngine
Features Pricing Support Find A Developer
Partners Upgrades
Blog Add-Ons Learn
Docs Forums University
Log In or Sign Up
Log In Sign Up
ExpressionEngine Logo
Features Pro new Support Find A Developer
Partners Upgrades
Blog Add-Ons Learn
Docs Forums University Blog
  • Home
  • Forums

Grouping Entries with Headers for each Group Based on Field

How Do I?

tacuster's avatar
tacuster
10 posts
10 years ago
tacuster's avatar tacuster

Hi. I have a site with store locations across the country. Several in each of several states. I’m just wanting to list all of the store locations and details about each, grouped by the state they are in. It would look like this:

ARIZONA

Store #100 54321 Arizona Street Phoenix, AZ 12345 (123) 456-7890

Store #120 54321 Tempe Road Tempe, AZ 12345 (123) 456-7890

CALIFORNIA

Store #115 54321 Sacramento Street Sacramento, CA 12345 (123) 456-7890

Store #202 54321 LA Road Los Angeles, CA 12345 (123) 456-7890

…etc.

I’d like to loop through all of my store entries and by using my {state} custom field both organize stores by state and grab the header from the {state} custom field.

I could build a monster of a page with conditionals for every state, but that seems terribly inefficient. Am I missing something here? Can you help a somewhat inexperienced coder to find the best solution?

Thanks, Troy

       
jay_turley's avatar
jay_turley
46 posts
10 years ago
jay_turley's avatar jay_turley

It feels like what you need is a “Stores” channel.

Then, when you select the entries from that channel, you will use the sort functionality of the channel entries tag.

Probably something like this:

{exp:channel:entries channel="stores" orderby="state|store_number" sort="asc|asc"}
    <h2>{state}</h2>
    <h3>{store_number}</h3>
{/exp:channel:entries}

However this doesn’t get your nice grouping by state with only one state at that top. If this is good enough, stop here. However, if you want that single state/multiple store listing,I’d use relationships.

I’d set up a states channel, populate it, then set up a relationship between states and stores so that each store belongs to one state, and then use the relationships tags to select the states channel entries and then the related stores for each state. There’s examples on that page that should get you started.

       
tacuster's avatar
tacuster
10 posts
10 years ago
tacuster's avatar tacuster

Thanks, Jay.

That’s a start. I actually worked it out to that point, but it’s really the headers I’m having trouble with. How can I loop through the entries and only repeat the state (used as the header) once for each group of returned entries? Of course, I could do it if I just repeat the channel entries tag over and over for each state, but that’s a lot of extra work and it seems like there must be a better way.

Is the relationships tag the answer? I can figure out the relationships tag in general, but could you do a quick sample in the context of what I’m trying to achieve?

Appreciated!

       
jay_turley's avatar
jay_turley
46 posts
10 years ago
jay_turley's avatar jay_turley

Once you get the channels (states and stores) and relationships (states - relationship (to stores, multiple)) set up, it’ll look something like this:

{exp:channel:entries channel="states"}
        <h2>{state}</h2>
        {parents field="stores"}
                <strong>{parents:store_name}</strong>: {parents:store_number} 

                {parents:address}
        {/parents}
{/exp:channel:entries}
       
tacuster's avatar
tacuster
10 posts
10 years ago
tacuster's avatar tacuster

Nice idea, but I think this approach might create additional work when it comes to adding new stores. Maintaining not only the addition of the store (which is expected, of course) but adding the maintenance of the relationship of each state to its stores. If I understand correctly, after I add a new store, I then need to go to the state channel and add the state’s relationship to that store. Ideally, I’d like to reverse the relationship so that when I create a new store, I can just select the state that it is related to as part of entering the store address. That way I only need to maintain one channel and its entries instead of 50 entries for states and 200+ entries for stores. Any thoughts? Did I misread your suggestion? Thanks again for the help!

       
jay_turley's avatar
jay_turley
46 posts
10 years ago
jay_turley's avatar jay_turley

As I understand it, relationships can be entered at either end. So you should be able to select a state when entering a store, instead of having to manage from the state end of things.

       
tacuster's avatar
tacuster
10 posts
10 years ago
tacuster's avatar tacuster

Is there any way to do this without creating a bunch of state channels? I can’t be the first person needing to group content this way and outputting headers for each group – can I? Anybody else have an idea? Thanks.

       
jay_turley's avatar
jay_turley
46 posts
10 years ago
jay_turley's avatar jay_turley

One state channel. Not a bunch. With fifty entries; one for each state. Then, each store (entry in the stores channel) is related to a state (entry in the states channel). This gives you your relationship.

You could use custom PHP coding to store the fact that the state had been written out and then not write it again unless it changes, but this seems like overkill when EE has built-in features to do what you want.

Lets be clear:

Here is your states channel:

States state_abbreviation: text input size 2 state_name: text input

Fill this up with the fifty states

Stores store_name: text input store_phone: text input store_state: relationship field (linked to States channel) (don’t allow multiple relations; each store can only be in one state)

Enter a couple of stores

Then, to display those stores:

{exp:channel:entries channel="states"}
        <h1>{state_name}</h1>
        {parents field="store_state"}
                <h3>{parents:store_name}</h3>
                {parents:store_phone}
        {/parents}
{/exp:channel:entries}

It’s literally that easy.

Edit: not that easy, used the wrong relationship in my first cut at this. The above code is the corrected version.

Edit 2: %#&*@%! relationships. Re-edited because of namespacing collisions due to EE’s handling of field names.

       
tacuster's avatar
tacuster
10 posts
10 years ago
tacuster's avatar tacuster

Thanks. However, your solution outputs the state names, but not any of the store info. In your example, how does the states channel know about the stores channel? If I’m understanding the relationship created here, states is the parent to stores. But in fact, the opposite is true.

       
tacuster's avatar
tacuster
10 posts
10 years ago
tacuster's avatar tacuster
One state channel. Not a bunch. With fifty entries; one for each state. Then, each store (entry in the stores channel) is related to a state (entry in the states channel). This gives you your relationship. You could use custom PHP coding to store the fact that the state had been written out and then not write it again unless it changes, but this seems like overkill when EE has built-in features to do what you want. Lets be clear: Here is your states channel: States state_abbreviation: text input size 2 state_name: text input Fill this up with the fifty states Stores store_name: text input store_phone: text input store_state: relationship field (linked to States channel) (don’t allow multiple relations; each store can only be in one state) Enter a couple of stores Then, to display those stores:
{exp:channel:entries channel="states"}
        <h1>{state_name}</h1>
        {parents field="store_state"}
                <h3>{parents:store_name}</h3>
                {parents:store_phone}
        {/parents}
{/exp:channel:entries}
It’s literally that easy. Edit: not *that* easy, used the wrong relationship in my first cut at this. The above code is the corrected version. Edit 2: %#&*@%! relationships. Re-edited because of namespacing collisions due to EE’s handling of field names.

Okay, looks like you may have a working solution here (with your edits). I’m giving it a try. Hold tight. Thanks!

       
jay_turley's avatar
jay_turley
46 posts
10 years ago
jay_turley's avatar jay_turley
Thanks. However, your solution outputs the state names, but not any of the store info. In your example, how does the states channel know about the stores channel? If I’m understanding the relationship created here, states is the parent to stores. But in fact, the opposite is true.

I’m assuming you typed this before I did Edits 1 & 2.

If so, please review the most recent code; it’s taken from a working implementation I just whipped up in the last few minutes.

It does show the store information properly. I had the inverted relationship code. I guess it’s because I hadn’t used relationships before today, just read about them.

       

Reply

Sign In To Reply

ExpressionEngine Home Features Pro Contact Version Support
Learn Docs University Forums
Resources Support Add-Ons Partners Blog
Privacy Terms Trademark Use License

Packet Tide owns and develops ExpressionEngine. © Packet Tide, All Rights Reserved.