0

I have a products section where I give each product group a main category. Initially I had it setup where each product had a main category and a sub category. GWCode generated a side nav from the catgories that looks like this...

  • Shampoos ( /products/shampoos/ )
    • Brand1 ( /products/shampoos/brand1/ )
    • Brand2 ( /products/shampoos/brand2/ )
  • Soaps ( /products/soaps/ )
    • Brand3 ( /products/soaps/brand3/ )
    • Brand4 ( /products/soaps/brand4/ )

URL setup...

/products/shampoos(category)/ = list of all shampoo products /products/shampoos(category)/brand1(subcategory)/ = list of all shampoo products with the Brand1 category /products/shampoos(category)/brand1(subcategory)/flowers(url_title) = single entry displaying the "flowers" entry

In my template I use Switchee to show a list of products when segment_3 is blank. If segment_3 is not blank I use if statements to detect if segment 4 is blank or not. If it is I show a list of products. If it is not blank I show the single entry product details. This worked GREAT until the client informed me that the products won't always have a subcategory. Which means this url setup is possible as well...

/products/shavinggel(category)/ /products/shavinggel(category)/coolmint(url_title)

So now the switchee and if statements I have setup won't work in this situation. I'm trying to figure out if there is a way to detect if segment_3 is a url_title or a category_url_title and display the appropriate code. Or if you have any other ideas.

Simplified template setup...

{exp:switchee variable = "{segment_3}" parse="inward"}

{case value="''"}
    {exp:channel:entries channel="products" category="{segment_category_ids}" disable="member_data|pagination" sort="asc" dynamic="no"}
        <!-- display list of entries from main category --> 
    {/exp:channel:entries}
{/case}

{case value="" default="Yes"}
    {if segment_4 == ""}
        {exp:channel:entries channel="products" category="{segment_category_ids}" disable="member_data|pagination" sort="asc" dynamic="no"}
        <!-- display list of entries from sub category -->
        {/exp:channel:entries}
    {/if}
    {if segment_4 != ""}
        {exp:channel:entries channel="products" disable="member_data|pagination" sort="asc" url_title="{segment_4}" dynamic="no"}
        <!-- display single entry detail page -->       
        {/exp:channel:entries}
    {/if}
{/case}

{/exp:switchee} 
  • The only things I can think of currently is maybe adding a segment to my product urls, like "details" or something. Then use conditionsls to detect if "details" is in the third or fourth segment and display the appropriate template code. I just really don't want another segment in there though. – Mike Lohrman May 2 '13 at 21:53
  • 1
    If it's not to late to change approach a bit, the site would definitely benefit from storing the brands as entries in their own channel and then using relationships to link them to products. They are not really 'categories' in the way that the top level parent cats are and don't belong as such. Doing this would give you better scalability, along with the ability to easily show category lists by brand. Your product urls should not have any category info in them (because an entry can have multiple cats), so aim for a simple /products/product_url_title and /products/category/cat_url_title – James Smith May 2 '13 at 22:32
  • Thanks James, I get what you are saying about the urls. Having a strong debate with myself over whether the urls will be "seo friendly" enough. – Mike Lohrman May 3 '13 at 14:14
  • Strangely enough we're having the same discussion in this thread. (Apologies for hijacking your actual question a bit). expressionengine.stackexchange.com/questions/9966/… – James Smith May 3 '13 at 15:04
3

I always tend to identify the product details page as simply /details/ to avoid this problem, but to achieve what you're after, the following should work (in theory).

Note that your example doesn't take into consideration pagination which would change the last segment. Maybe the client doesn't want it, but may once they get bulk products in there. The approach below will be able to handle that.

Have the index template in the products template group handle the flow to delivery all pages within the products url structure...

Use this add-on: http://devot-ee.com/add-ons/bjorn-last-segment

In this index template get the last segment and test it for a valid entry:

{exp:channel:entries
    status="not Closed"
    channel="products"
    dynamic="no"
    url_title="{last_segment}"
    require_entry="yes"
    disable="member_data|pagination|trackbacks"}
    {if no_results}
            {embed=products/listing}
    {/if}

...Display your details page...

{/exp:channel:entries}

This will try to get the channel entry for the last segment, if it doesn't exist (i.e. it's not a product) it will ignore the product details page and load up the listing template. The only restriction here is that you can't have a category with the same URL as a product!

Looks like you could use entry_id="{last_segment_id}" instead of url_title based on the add-ons documentation, but doubt there's much difference.

Then in your listing template, do away with switchee:

{exp:channel:entries channel="products" category="{segment_category_ids}" disable="member_data|pagination" sort="asc" dynamic="no"}
    <!-- display list of entries from main category --> 
{/exp:channel:entries}

Remember to put in another {if no_results}{/if} conditional to display a 404 or some message that no products exist for the categories provided (let's say they make a URL up).

By this reference: {segment_category_ids}, I assume you're using Low Seg2cat add-on?

I notice from your category structure that you've opted to repeat the brands each time under each product type, you may want to consider giving greater flexibility and making the brands a separate category group so both product type and brand are selected for a product and impact on the listing URL in the same way. By keeping them as separate it will avoid duplication and allow for products listed by brand or by product type, or both. But that's another question ;)

| improve this answer | |
  • Peter, thanks for your help. I have 3 completely different options to try this morning and i think Im going to start with yours. I don't use embeds much, so this might be a dumb question, but if I embed a template with a channel entries tag in it, won't there be a channel entries tag within a channel entries tag? This isn't allowed is it? – Mike Lohrman May 3 '13 at 14:04
  • Peter, I gave this a shot, no issues with the embed. Everything seems to be working fine and my template is a LOT cleaner. Thanks! – Mike Lohrman May 3 '13 at 14:56
  • You can't use a channel:entries within another channel:entries, that's true. But it's fine via embeds - the way EE parses it is to complete the parent template first, once that's all complete and ready to be rendered, it then processes the child templates (embeds), once they're ready to be rendered EE replaces the embed tag in the parent with the rendered child template. Because it's already been parsed with the appropriate outcome, there can be no conflict. – Peter Lewis May 3 '13 at 15:04

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.