ExpressionEngine CMS
Open, Free, Amazing

Thread

This is an archived forum and the content is probably no longer relevant, but is provided here for posterity.

The active forums are here.

Displaying entries by category via segments

December 09, 2009 7:59am

Subscribe [3]
  • #1 / Dec 09, 2009 7:59am

    lithiumdave

    215 posts

    Moderator’s note: Moved to Howto.

    After several hours trying every trick I know, I’m now stumped and turn to you guys for help!

    I’m on an entry listing page. I have a couple of dropdown menus which are populated by 2 different category groups. I want the visitor to be able to to choose from either, or both, of the dropdown menus and the resulting entries be filtered by the categories they chose.

    I mostly have this down already. I’ve got the dropdown creating URL segments on the resulting page so I can reference them.

    I’ve also used the wonderful Low Seg2Cat extension to translate the category short names in the URL to category ids.

    I now need to use those category ids in the weblog:entries tag as a parameter, the basic idea being:

    {exp:weblog:entries weblog="weblog" category="{segment_3_category_id}&{segment_4_category_id}"}

    At this point, this works a treat. It pops the correct category ids in the parameter and displays the correct entries.

    Ok, here’s where it gets more complicated…

    The 2 category dropdowns I have populating segment_3 and segment_4 also both have an ‘all’ option at the top of the list. Here’s actually what they are so you know what I’m talking about (stripped down to bare bones):

    <!-- First dropdown -->
    <select>
        <option value="key">any key stage</option>
        {exp:weblog:categories category_group="3" weblog="weblog" style="linear"}
        <option value="{category_url_title}">{category_name}</option>
        {/exp:weblog:categories}
    </select>
    <!-- Second dropdown -->
    <select>
        <option value="theme">any theme</option>
        {exp:weblog:categories category_group="4" weblog="weblog" style="linear"}
        <option value="{category_url_title}">{category_name}</option>
        {/exp:weblog:categories}
    </select>

    As you can see, I can’t just have a simple weblog:entries parameter like this…

    category="{segment_3_category_id}&{segment_4_category_id}"}

    because if the first ‘segment_3’ dropdown has a value of “key” (i.e. ‘all’), and the second dropdown is a category, then I actually only want the category parameter to be this…

    category="{segment_4_category_id}"}

    And vice versa, if the second ‘segment_4’ dropdown has a value of “theme” (i.e. ‘all’), and the first dropdown is a category, then I only want the category parameter to be this…

    category="{segment_3_category_id}"}

    Further still, if both “key” and “theme” are chosen (i.e. no category) then there needs to be no parameter whatsoever!

    I’ve tried various permutations of both native EE and PHP conditionals but nothing is working. I’d post up the various attempts I’ve made but this post is long enough already.

    Am I over-complicating this? Any help or direction really appreciated. My head’s ready to pop.

    Many thanks,
    Dave

  • #2 / Dec 09, 2009 8:55am

    Stephen Lewis

    466 posts

    Hi Dave,

    EDIT: Just noticed you’re using the category_url_title, and have updated the code accordingly.

    In the course of your frustrations, did you try the following (parsing PHP on input)?

    Caveat: I haven’t tested this at all, and it may destroy the world.

    <?php
    
    $category_string = '';
    
    /**
     * Retrieves a category ID from a category URL title.
     *
     * @param        string         $url_title        The category URL title.
     * @return     string        The category ID.
     */
    function get_category_id_from_url_title($url_title = '')
    {
        global $DB;
    
        if ( ! $url_title)
        {
            return '';
        }
        
        $db_category = $DB->query("SELECT cat_id
            FROM exp_categories
            WHERE cat_url_title = '" .$DB->escape_str($url_title). "'");
            
        if ($db_category->num_rows != 1)
        {
            return '';
        }
        else
        {
            return $db_category->row['cat_id'];
        }
    }
    
    
    /**
     * Retrieves the category URL titles and sorts out the category
     * string.
     *
     * @return     string
     */
    function build_category_string()
    {
        global $IN;
    
        $categories = array();
    
        // Retrieve the key stage.
        if ($IN->fetch_uri_segment('3') != 'key')
        {
            $cat_id = get_category_id_from_url_title($IN->fetch_uri_segment('3'));
            
            if ($cat_id)
            {
                $categories[] = $cat_id;
            }
        }
    
        // Retrieve the theme.
        if ($IN->fetch_uri_segment('4') != 'theme')
        {
            $cat_id = get_category_id_from_url_title($IN->fetch_uri_segment('4'));
            
            if ($cat_id)
            {
                $categories[] = $cat_id;
            }
        }
    
        return implode('&', $categories);
    }
    
    $category_string = build_category_string();
    
    ?>
    
    {exp:weblog:entries category="<?=$category_string; ?>" weblog="weblog"} ... {/exp:weblog:entries}

    Cheers,
    Stephen

  • #3 / Dec 09, 2009 12:12pm

    lithiumdave

    215 posts

    Thanks so much for this Stephen, works exactly as desired. I’m absolutely thrilled, thanks hugely for your time.

  • #4 / Dec 09, 2009 12:20pm

    Stephen Lewis

    466 posts

    No worries Dave, glad I could help.

    Cheers,
    Stephen

  • #5 / Feb 01, 2010 5:06pm

    Low

    407 posts

    A bit late to the game, but I came across this post just now by coincidence (also known as my referrer stats) and wanted to share this tidbit.

    You’re already using Seg2Cat, so this could be done really easily, if these conditions apply:
    - Neither segment_1 and segment_2 are returning categories;
    - Neither ‘key’ and ‘theme’ are category url titles.

    In other words, the only categories in the URI are the ones in segment_3 and segment_4, coming from group 3 and 4. If this is true, you can use this code:

    category="{segment_category_ids}"}

    The variable {segment_category_ids} will return an inclusive stack of all found categories in the URI, and an empty string if none are found.

.(JavaScript must be enabled to view this email address)

ExpressionEngine News!

#eecms, #events, #releases