2

I'm using Stash for the first time and having a little trouble getting a list of channel entries relating to a Zoo Visitor Member.

The main issue seems to be with the set_list. If I hard-code the author_id, it works fine, but if I try and pass it the member_id, it fails. I'm sure it's something simple and parse order related, but I'm just not seeing it.

I have checked out a couple of other answers: here and here. They have got me this far, but I'm still missing the final piece of the jigsaw!

Also, if there is any improvements to the way I've laid things out, I'd be very receptive to any tips, like I said it's my first time using Stash and I'd like to be doing it properly and as DRY as possible. Should I move the markup which is in the stash:content into a partial for example?

Here is the code I'm using:

{stash:embed:layouts:site}

{exp:channel:entries status="not closed"}
{exp:zoo_visitor:details member_entry_id="{entry_id}"}
    {exp:stash:set name="team_member_id"}{visitor:member_id}{/exp:stash:set}
{/exp:zoo_visitor:details}
{exp:stash:set name="title"}{title}{/exp:stash:set}
{exp:stash:set name="h1"}{title}{/exp:stash:set}
{exp:stash:set name="team_member_photo"}{member_staff_photo}<img src="{url}" alt="{title}" title="{title}" />{/member_staff_photo}{/exp:stash:set}
{categories limit="1"}
    {exp:stash:set name="team_member_category"}{category_name}{/exp:stash:set}
{/categories}
{exp:stash:set name="team_member_biog"}{member_biography}{/exp:stash:set}
{exp:stash:set name="team_member_firstname"}{member_firstname}{/exp:stash:set}
{/exp:channel:entries}

{exp:stash:set_list name="jobs" parse_tags="yes"}
{exp:channel:entries channel="job" status="not closed" dynamic="no" author_id="{exp:stash:get name="team_member_id"}"}
    {stash:job_title}{title}{/stash:job_title}
{/exp:channel:entries}
{/exp:stash:set_list}

{exp:stash:set name="content"}
<div class="main">
<div class="banner">
    <div class="content">
        <h2 class="bb">Banner Title</h2>
        <div>
            <p>Banner Copy</p>
        </div>
    </div>
</div>
<div class="g2">
    <div class="item single team">
        <p>{exp:stash:get name="team_member_category"}</p>
    </div>

    <div class="item single">
        {exp:stash:get name="team_member_photo"}
    </div>

    <div class="jobs double team">
        <h3>{exp:stash:get name="team_member_firstname"}'s Jobs</h3>
        <ul>
        {exp:stash:get_list name="jobs"}
            <li>{job_title}</li>
        {/exp:stash:get_list}
        </ul>
    </div>
    <div class="biog quad">
        {exp:stash:get name="team_member_biog"}
    </div>
</div>
</div>
{/exp:stash:set}

EDIT: Updated code adding gets and sets to stash tags to make more readable.

EDIT 2: Thanks to Jérôme for the solution, it's a combination of his suggestions. Here is the new working code for reference (the content section was unchanged, so is not included here):

{exp:stash:set parse_tags="yes" parse_depth="2"}
{exp:channel:entries status="not closed"}
{exp:zoo_visitor:details member_entry_id="{entry_id}"}
    {stash:team_member_id}{visitor:member_id}{/stash:team_member_id}
{/exp:zoo_visitor:details}
{stash:title}{title}{/stash:title}
{stash:h1}{title}{/stash:h1}
{stash:team_member_photo}{member_staff_photo}<img src="{url}" alt="{title}" title="{title}" />{/member_staff_photo}{/stash:team_member_photo}
{categories limit="1"}
    {stash:team_member_category}{category_name}{/stash:team_member_category}
{/categories}
{stash:team_member_biog}{member_biography}{/stash:team_member_biog}
{stash:team_member_firstname}{member_firstname}{/stash:team_member_firstname}
{/exp:channel:entries}
{/exp:stash:set}

{exp:stash:set_list name="jobs" parse_tags="yes"}
{exp:channel:entries parse="inward" channel="job" status="not closed" dynamic="no" author_id="{exp:stash:team_member_id}"}
    {stash:job_title}{title}{/stash:job_title}
{/exp:channel:entries}
{/exp:stash:set_list}
3

I think this is indeed a parse order problem. IMHO {exp:stash:team_member_id} is not set yet when you call it. You can track it down if you read the template debugging.

Looks like the problem is that when you set team_member_id, you are in a channel entries loop, when you try to get it you are outside. Two different layer of the (now) proverbial oignon here, I think.

parse="inward" is needed in your channel entries tag so things are parsed in the right order

Proposed solution 1: use process="end"

EDIT: That one didn't work, because it does not solve the fact that the set is inside EE tags, while the get is outside.

You could also delay the parsing of that part of the template using {exp:stash:parse process="end"}

{exp:stash:parse process="end"}
    {exp:stash:set_list name="jobs" parse_tags="yes"}
        {exp:channel:entries parse="inward" channel="job" status="not closed" dynamic="no" author_id="{exp:stash:team_member_id}"}
            {stash:job_title}{title}{/stash:job_title}
        {/exp:channel:entries}
    {/exp:stash:set_list}
{/exp:stash:parse}

I always find those difficult to debug. The way I go about these is to break them down to simple components and test them one by one.

proposed solution 2: wrapping the first entries loop in a big stash set

Putting all EE tags in the same "oignon layer" by wrapping the channel entries loop in one big stash set did the trick (see Steve's code above). Now everything is using the same structure in terms of layers:

  1. stash tags
  2. ee tags
  3. stash set / get

template organisation

As far as your template organisation goes, that's pretty much how I work as well. I tend to use get and set, though. Its clearer to me when I read code down the line.

| improve this answer | |
  • I think you are right about the team_member_id not being set. Sadly I've tried adding parse=inward and that lists all the jobs and ignores the author_id altogether. I've also tried the parse process=end code you suggested above and that doesn't solve it either unfortunately. Thanks for you efforts though. – Steve Holland Feb 19 '13 at 18:21
  • Have you tried just outputting your yeam_member_id stash var outside of both the channel entry loop and the set list to see if you get something? – Jérôme Coupé Feb 19 '13 at 19:27
  • Have you tried wrapping a big stash set around your first entries loop and setting all your stash variables inside of that. I usually find that having all EE tags at the same "level" in your code helps solving problems like this one – Jérôme Coupé Feb 19 '13 at 19:28
  • Thanks Jérôme, wrapping the first entries loop in a stash set has done the trick, that combined with the parse=inward on the jobs channel. I've updated the question to show the final working code. – Steve Holland Feb 19 '13 at 20:29
  • Glad it worked. Edited my answer as well to be clearer. The more I use stash, the more I find ths oignon metaphor and Low's Parse Order Pro slide deck useful. Also, good catch on the parse_depth="2" there ;o) – Jérôme Coupé Feb 20 '13 at 6:54
2

You don't appear to have any {exp:stash:set} or {exp:stash:get} tags in your template. You can only do {stash:variable_name} inside a {exp:stash:set} or {exp:stash:set_list}.

| improve this answer | |
  • Are you talking about an older version of Stash? Using version 2.3.6 you are able to use short tags. This all works apart from the related list I mention. – Steve Holland Feb 19 '13 at 13:46
  • I've updated the code to add gets and sets back in. I think in hindsight, it is more readable. So thanks for the pointer. – Steve Holland Feb 19 '13 at 18:18
  • Oops, I did check out the docs before posting to see if I'd missed an update but didn't scroll all the way to the bottom where the short tags description is. – Tyssen Feb 19 '13 at 21:24

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.