6

I am having so much trouble wrapping my head around Stash and the parse order. I'm trying to clean up my code and work with the DRY principle.

I have my layout and view working and pulling in my main content.

I'm stuck on the nested entries aspect of Stash and was hoping that someone would be able to help me out or point me in the right direction.

I know Stash doesn't not allow embeds but I don't know how to work within the system to accomplish what I did previously with only embeds.

Necessarily there will be more than one blog entry and almost always more than one related author id.

My view:

{embed="_layouts/_index"}

{exp:stash:set name="content"}
{exp:channel:entries channel="blog" limit="5" disable="categories|category_fields|member_data|pagination|trackbacks"}
<h3 id="{url_title}" class="article-title"><a href="{page_url}">{title}</a></h3>
{blog_entries_body}
<div class="related-author clearfix">
    <ul>
            {embed="_widgets/_related_author" entry_ids="{blog_entries_author:child_ids}"}
            <li class="pub-date">{blog_entries_publish_date format="%F %j, %Y"}</li>
        </ul>
    </div>
</div>
{/if}
{/exp:channel:entries}
{/exp:stash:set}

My Embed:

{exp:channel:entries channel="contributors" fixed_order="0|{embed:entry_ids}" disable="categories|category_fields|member_data|pagination|trackbacks"}
    <li class="bio-name"><a href="{page_url}">{title}</a></li>
{/exp:channel:entries}

Any help would be greatly appreciated.

2
  • I actually to have almost everything disabled and updated the code in the original post to reflect. – Allan Kukral Dec 19 '12 at 21:44
  • Is {blog_entries_author:child_ids} a Playa relationship field? – Alex Roper Feb 25 '13 at 9:32
7

Tom is right that performance will be a problem regardless of how you approach this, so what you could do is cache the list of entries and related contributers.

{!-- set the entries into a list, since we need to iterate over it twice. Prefix with 'p' to identify the 'parent' --}
{exp:stash:set_list 
    name="blog_entries" 
    parse_tags="yes"
    scope="site" 
    save="yes" 
    refresh="10" 
    replace="no"
}
    {exp:channel:entries channel="blog" limit="5" disable="categories|category_fields|member_data|pagination|trackbacks"}
        {stash:p_entry_id}{entry_id}{/stash:p_entry_id}
        {stash:p_url_title}{url_title}{/stash:p_url_title}
        {stash:p_page_url}{page_url}{/stash:p_page_url}
        {stash:p_title}{title}{/stash:p_title}
        {stash:p_body}{blog_entries_body}{/stash:p_body}
        {stash:p_contributer_ids}{blog_entries_author:child_ids}{/stash:p_contributer_ids}
        {stash:p_publish_date}{blog_entries_publish_date format="%F %j, %Y"}{/stash:p_publish_date}
    {/exp:channel:entries}
{/exp:stash:set_list}

{!-- generate a list of contributers for each parent entry and cache for 10 minutes --}
{exp:stash:get_list name="blog_entries" scope="site"}
    {exp:stash:set 
        name="contributors_for_{p_entry_id}" 
        parse_tags="yes" 
        scope="site" 
        save="yes" 
        refresh="10" 
        replace="no"
    }
        {exp:channel:entries channel="contributors" fixed_order="0|{p_contributer_ids}" disable="categories|category_fields|member_data|pagination|trackbacks"}
            <li class="bio-name"><a href="{page_url}">{title}</a></li>
        {/exp:channel:entries}
    {/exp:stash:set}
{/exp:stash:get_list}

{!-- stitch it all together --}
{exp:stash:set name="content"}
    {exp:stash:get_list name="blog_entries" scope="site"}
    <h3 id="{p_url_title}" class="article-title"><a href="{p_page_url}">{p_title}</a></h3>
    {p_body}
    <div class="related-author clearfix">
        <ul>
            {exp:stash:get name="contributors_for_{p_entry_id}" scope="site"}
            <li class="pub-date">{p_publish_date}</li>
        </ul>
    </div>
    {/exp:stash:get_list}
{/exp:stash:set}
1
  • Got this working! Thanks for the help. Do you have any suggestions for performance on this? Or adding pagination on blog entries? – Allan Kukral Dec 21 '12 at 21:56
3

So the first thing to note is that if you do this sort of thing you need to be really careful about performance. You're not only running the templating engine 6 times (main template + 5 embeds), but also 6 loops of {channel:entries} as well, which can be very expensive/intensive. Be sure to use the disable parameter aggressively as this can dramatically improve performance.

That proviso aside, if you do find you need to do nest channel:entries tags like this, have you considered using one of the (recently released) Entries or More Entries plugins rather than an embed?

NB neither of these are production releases just yet - Entries is in public beta and seems more mature (see comments) so may be the best choice right now.

This would get around your stash issue, improve performance by not requiring additional passes of the template engine, and you can still use the disable param as per {channel:entries}. If you really only need access to the entry title and page_url in your nested loop, you may well be able to do a full on disable="categories|category_fields|custom_fields|member_data|pagination" for maximum reduction in unnecessary queries.

3
  • The More Entries plugin doesn't really work. It doesn't have prefixes and number of other needed features. Take a look at my new free add-on (to be released soon). objectivehtml.com/entries Coincidently I was working on this at the same times as @airways, he just released his first. Entries will be officially available within the next week, just FYI. (Since this is still beta, this is a comment, not an answer.) – Justin Kimbrell Dec 19 '12 at 22:42
  • Will your plugin be free license as well? Looks like a great option. How is it on the performance aspect of things? – Allan Kukral Dec 20 '12 at 14:45
  • Justin, I've updated my post with a link to your plugin instead, with a note that it is currently in beta - hope that's okay. – Tom Davies Dec 20 '12 at 15:32

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.