1

I'm working on a template that outputs large tables of stockists. At the moment they're quite slow so I've reworked it a bit to use Stash set & get_list but they're still quite slow.

For instance, the template I'm testing has come down from ~9 seconds to ~6.5. I'd like to get that down further and wondering what I can do with the below to achieve that.

{exp:stash:set_list
    name="stockists"
    parse_tags="yes"
}

    {exp:channel:entries
        category="{segment_3_category_id}"
        channel="stockists"
        disable="member_data|pagination|trackbacks"
        dynamic="no"
        orderby="title"
        sort="asc"
    }
        {stash:stockist_cat}{categories backspace="1"}{category_name}|{/categories}{/stash:stockist_cat}

        {stash:stockist_row}
        <td>
            {title} <br/>
            {if stock_address_1}{stock_address_1} <br />{/if}
            {if stock_address_2}{stock_address_2} <br />{/if}
            {if stock_address_3}{stock_address_3} <br />{/if}
            {if stock_city}{stock_city}{/if} {if stock_state}<span>{stock_state}</span>{if:else}<span>{segment_3_category_name}</span>{/if} {if stock_pcode}{stock_pcode}{/if}
        </td>
        <td>
            <p>p {if stock_phone}{stock_phone}<br/>{/if}
            {if stock_url}<a href="http://{stock_url}" target="_blank">{stock_url}</a>{/if}</p>
        </td>
        {/stash:stockist_row}

    {/exp:channel:entries}

{/exp:stash:set_list}

<table class="stockists">
    <tbody>

        {exp:gwcode_categories
            cat_id="{segment_3_category_id}"
            depth="2|3"
            parse="inward"
            show_empty="yes"
            style="linear"
        }
            {if depth=="2"}
            <tr>
                <th colspan="3" id="{cat_url_title}" class="location-hd">{cat_name}</th>
            </tr>
            {/if}
            {if cat_description}<tr>
                <td colspan="3"><p>{cat_description}</p></td>
            </tr>
            {/if}

            {if depth=="3"}
                {exp:stash:get_list
                    name="stockists"
                    match="#\b{cat_name}\b#"
                    against="stockist_cat"
                    save="yes"
                    scope="site"
                    refresh="60"
                    replace="no"
                }
                <tr>
                    <th scope="row" class="location-name">{cat_name}</th>
                    {stockist_row}
                </tr>
                {/exp:stash:get_list}
            {/if}

        {/exp:gwcode_categories}

    </tbody>
</table>
  • Maybe start by caching the list when you set it? If it gives you the performance you need, then cache it forever and use Mustash to break the cache on updates? – Jérôme Coupé Mar 31 '14 at 9:06
  • I would also stash / cache your GW code list and then nest both lists when you get them. A bit like in this example gist.github.com/croxton/6219973 – Jérôme Coupé Mar 31 '14 at 9:10
3

I think that by caching both lists, you could reduce queries a little bit further. Easier to add Stash caching / Mustash to the mix too.

Something along the lines of:

{!-- set stockists list (consider caching with bundles and mustash forever) --}
{exp:stash:set_list
    name="stockists"
    parse_tags="yes"
    parse_conditionals="yes"
    save="yes" 
    scope="site"   
    refresh="60"   
    replace="no"
}

    {exp:channel:entries
        category="{segment_3_category_id}"
        channel="stockists"
        disable="member_data|pagination|trackbacks"
        dynamic="no"
        orderby="title"
        sort="asc"
    }
        {stash:stockist_cat}{categories backspace="1"}{category_name}|{/categories}{/stash:stockist_cat}
        {stash:stockist_title}{title}{/stash:stockist_title}
        {stash:stock_address_1}{stock_address_1}{/stash:stock_address_1}
        {stash:stock_city}{stock_city}{/stash:stock_city}
        {if stock_state}
            {stash:stock_state}{stock_state}{/stash:stock_state}
        {if:else}
            {stash:stock_state}{segment_3_category_name}{/stash:stock_state}
        {/if}

    {/exp:channel:entries}

{/exp:stash:set_list}

{!-- set categories list (consider caching with bundles and mustash forever) --}
{exp:stash:set_list
    name="categories"
    parse_tags="yes"
    parse_conditionals="yes"
    save="yes" 
    scope="site"   
    refresh="60"   
    replace="no"
}

    {exp:gwcode_categories
            cat_id="{segment_3_category_id}"
            depth="2|3"
            parse="inward"
            show_empty="yes"
            style="linear"
        }
            {stash:cat_depth}{depth}{/stash:cat_depth}
            {stash:cat_url_title}{cat_url_title}{/stash:cat_url_title}
            {stash:cat_name}{cat_name}{/stash:cat_name}
            {stash:cat_description}{cat_description}{/stash:cat_description}

    {/exp:gwcode_categories}

{/exp:stash:set_list}


{!-- creating the list using stash nested lists --}
{exp:stash:get_list:categories
    name="categories"
    scope="site"
}
    {if cat_depth == "2"}
        ... do table stuff ...
    {/if}

    {if cat_depth == "3"}
        {exp:stash:get_list:stockists
                name="stockists"
                match="#^{cat_name}$#"
                against="stockist_cat"
                scope="site"
            }
            <tr>
                <th scope="row" class="location-name">{cat_name}</th>
                <td>
                    {title} <br/>
                    {if "{exp:stash:not_empty name='stock_address_1'}"}{stock_address_1} <br />{/if}
                    [...]
                </td>
                <td>
                    [...]
                </td>
            </tr>
        {/exp:stash:get_list:stockists}
    {/if}
{/exp:stash:get_list:categories}

Let me know if that helps.

EDIT: added contexts (exp:stash:get_list:categories and exp:stash:get_list:stockist) for nested get_lists to work properly

| improve this answer | |
  • Only thing I'd suggest for the nested get_list match/against is to use the category id instead of the name, so that reserved characters in the name don't break the regex. Of course that means saving the category id too when the list is set. – Mark Croxton Mar 31 '14 at 18:25
  • Yep! ID would be a Safer option indeed. The Croxton strikes again ;o) – Jérôme Coupé Mar 31 '14 at 20:01
  • Thanks Jérôme, that's made a huge improvement. I've had to remove the save params because it's only working for the first template I test with, i.e. when I view pages for other states, I get no output. But even without saving those lists, the biggest pages is still coming in at just over 2s which is a big improvement. The reason I'm using #\b{cat_name}\b# instead of #^{cat_name}$# is because stockist_cat can be a pipe delimited string of more than one category. But even doing it that way I am having trouble with some entries being output twice under the parent and child category. – Tyssen Apr 1 '14 at 1:13
  • Did you try Mark's suggestion of working with categories IDs rather than names? Also, have a look at this technique for complex filtering of lists github.com/croxton/Stash/wiki/… – Jérôme Coupé Apr 1 '14 at 4:31
  • Sorry, I meant instead of {cat_id}. I forgot to mention that when I tried that, I got no output. Not really following that page from the wiki. :? – Tyssen Apr 1 '14 at 10:37

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.