4

EE 2.5.5 Stash 2.1.0

I'm new to stash and am in the middle of integrating EE into existing html code.

The code I currently have is as follows:

{exp:stash:set parse_tags="yes"}
    {stash:content}
      {exp:channel:entries channel="photoblog" limit="15" orderby="" disable="member_data|pagination|categories"} 

          {stash:title}
            <div {if count=="1"}style="display:block;"{/if}>
              <h2>{title}</h2>
            </div>
          {/stash:title}

          {stash:photos}
            {photos}
            <img class="pg_thumb" {if count=="1"}style="display:block;"{/if} src="{image}" width="1000" height="714" alt="" />
            {/photos}
          {/stash:photos}

          {stash:description}
            <div {if count=="1"}style="display:block;"{/if}>        
              {description}
              <a href="#" class="more">Details</a> 
            </div>
          {/stash:description}

      {/exp:channel:entries}
    {/stash:content}
{/exp:stash:set}


    <div id="pg_preview">
      {exp:stash:get name="photos"}
    </div>

    <div id="pg_desc1" class="pg_description">
        {exp:stash:get name="title"}
    </div><!--pg_desc1-->

    <div id="pg_desc2" class="pg_description">
        {exp:stash:get name="description"}
    </div><!--pg_desc2-->

This is sort of working. When I check the front end code I see only one result for each of the get tags when I'm actually expecting to see 15 as per the limit parameter of the channel entries tag.

UPDATE

I just tried the following, but all it does is output about 30 blank lines

{exp:channel:entries channel="photoblog" limit="15" orderby="" disable="member_data|pagination|categories"}
    {exp:stash:set_list name="photos-list" parse_tags="yes"}
          {stash:entry_id}{entry_id}{/stash:entry_id}
          {stash:title}
            {title}
          {/stash:title}

          {stash:photos}
            {photos}
            <img class="pg_thumb" {if count=="1"}style="display:block;"{/if} src="{image}" width="1000" height="714" alt="" />
            {/photos}
          {/stash:photos}

          {stash:description}
            {description}
          {/stash:description}
    {/exp:stash:set_list}   
{/exp:channel:entries} 

{exp:stash:get_list name="photos-list" orderby="entry_id" sort="asc" limit="15"}
    <div id="pg_preview">
      {photos}
    </div>

    <div id="pg_desc1" class="pg_description">
      <div {if count=="1"}style="display:block;"{/if}>
        <h2>{title}</h2>
      </div>
    </div><!--pg_desc1-->

    <div id="pg_desc2" class="pg_description">
        <div {if count=="1"}style="display:block;"{/if}>        
          {description}
          <a href="#" class="more">Details</a> 
        </div>
    </div><!--pg_desc2-->
{/exp:stash:get_list}

UPDATE 2

I changed the code that was here just before reading dylans comment, which looks the same to me, but it isn't working.

{exp:stash:set_list name="photos-list" parse_tags="yes" output="no"}
  {exp:channel:entries channel="photoblog" limit="5" orderby="" disable="member_data|pagination|categories"}

      {stash:entry_id}{entry_id}{/stash:entry_id}
      {stash:title}
        {title}
      {/stash:title}

      {stash:photos}
        {photos}
        <img class="pg_thumb" {if count=="1"}style="display:block;"{/if} src="{image}" width="1000" height="714" alt="{title}" />
        {/photos}
      {/stash:photos}

      {stash:description}
        {description}
      {/stash:description}

  {/exp:channel:entries} 
{/exp:stash:set_list} 


{exp:stash:get_list name="photos-list" orderby="entry_id" sort="asc" limit="5" output="yes"}
    <div id="pg_preview">
      {photos}
    </div>

    <div id="pg_desc1" class="pg_description">
      <div {if count=="1"}style="display:block;"{/if}>
        <h2>{title}</h2>
      </div>
    </div><!--pg_desc1-->

    <div id="pg_desc2" class="pg_description">
        <div {if count=="1"}style="display:block;"{/if}>        
          {description}
          <a href="#" class="more">Details</a> 
        </div>
    </div><!--pg_desc2-->
{/exp:stash:get_list}

UPDATE 3

Newly revised code below based on Nate's comment to his own answer. Not working as expected. I still only see one entry worth of data, but the image is now not the correct one. Have created a stripped down template with only the following code for testing purposes which can be viewed here. That picture is from December but the copy is from Feb 8. Not sure why the photo is not pulling from the same entry as the copy.

--updated to stash 2.3.6 and multiple entries now working, but the same image is displaying for all of them.

{exp:stash:set_list name="photos-list" parse_tags="yes" output="no" parse_depth="2" parse_conditionals="yes" prefix="prefix"}
  {exp:channel:entries channel="photoblog" limit="5" orderby="" disable="member_data|pagination|categories" dynamic="no"}

      {stash:entry_id}{entry_id}{/stash:entry_id}
      {stash:title}
        {title}
      {/stash:title}


      {exp:stash:set_list:nested name="photos-image" parse_tags="yes" output="yes" parse_conditionals="yes" prefix="prefix"}
        {stash:picture}
          {photos}
          <img class="pg_thumb" {if prefix:count=="1"}style="display:block;"{/if} src="{image}" width="1000" height="714" alt="{title}" />
          {/photos}
        {/stash:picture}
      {/exp:stash:set_list:nested}    


      {stash:description}
        {description}
      {/stash:description}

  {/exp:channel:entries} 
{/exp:stash:set_list} 


{exp:stash:get_list name="photos-list" orderby="entry_id" sort="asc" limit="5" output="yes" parse_conditionals="yes" prefix="prefix"}

    <div id="pg_preview">
      {exp:stash:get_list:nested name="photos-image"}
        {picture}
      {/exp:stash:get_list:nested}
    </div>

    <div id="pg_desc1" class="pg_description">
      <div {if prefix:count=="1"}style="display:block;"{/if}>
        <h2>{title}</h2>
      </div>
    </div><!--pg_desc1-->

    <div id="pg_desc2" class="pg_description">
        <div {if prefix:count=="1"}style="display:block;"{/if}>        
          {description}
          <a href="#" class="more">Details</a> 
        </div>
    </div><!--pg_desc2-->

{/exp:stash:get_list}

Please advise.

UPDATE AGAIN

Am very flummoxed with this. I have pasted template code here that works perfectly, but is using 4 duplicate channel entries tags. If someone could help me get this working with stash I would be very grateful. It would also help if I can not just copy and paste, but fully understand what is happening.

  • Hi Sean, did you see my edited answer? – Dylan Feb 11 '13 at 3:11
2

There's two problems with your second example that I can see. The first is the EE parse order. To quote Mark Croxton:

Like the layers of an onion, EE parses module tags from the outwards > inwards - ‘peeling off’ the outer tags in a template to expose the ones nested inside.

So basically you're trying to display the stash variable before it's actually been set.

The second is that your stash list is being overwritten with every loop of the channel entries tag.

The easiest way to solve this would be to swap the order of your channel:entries and stash tags. Stash is smart enough to see that it's dealing with multiple entries and will add a new row for each one. The parse order issue is solved as you've included the parse_tags="yes" parameter, but now it's actually parsing the channel:entries tag because it's on the outside. Here's a simple example:

{exp:stash:set_list name="photos-list" parse_tags="yes"}
    {exp:channel:entries channel="photoblog" limit="15" orderby="" disable="member_data|pagination|categories"}
        {stash:entry_id}{entry_id}{/stash:entry_id}
        {stash:title}{title}{/stash:title}
        {stash:description}{description}{/stash:description}
    {/exp:channel:entries}
{/exp:stash:set_list} 

{exp:stash:get_list name="photos-list" orderby="entry_id" sort="asc" limit="15"}
   <h2>{title}</h2>
   {description}
{/exp:stash:get_list}

I'd highly recommend reading the following EE Insider article that describes the template partial approach using stash. Stash and the EE parse order can be a bit hard to get your head around at first but open up enormous possibilities once you get the hang of it.

Update 3 response

Okay in regard to your third update with only one image showing. It sounds like it's just showing the first image that's been stashed in the nested list. You should be able to use the match parameter to sort this out. Stash the current entry_id in your nested list:

{stash:entry_id}{entry_id}{/stash:entry_id}

and then match against it when you get the list:

{exp:stash:get_list:nested name="photos-image" match="#^{entry_id}$#" against="entry_id"}
| improve this answer | |
  • Dylan, I updated my second example with what I reached just before checking your asnwer - too me it looks the same but it's only outputting one image. – CreateSean Feb 9 '13 at 4:47
  • Assuming photos is another module, you may need to add parse_depth="2" (or 3) to the exp:stash:set_list tag to actually parse the tag properly. I would also make sure you're using Stash 2.3.6 as Natetronn suggested. Definitely take some time to read the EE Insider article. I think using an embed that contains all of your layout and gets your stashed content will help to solve some of your issues. – Dylan Feb 9 '13 at 5:27
  • Does my example work for you without the photos tag? I setup a quick test before posting and it worked okay. – Dylan Feb 9 '13 at 5:47
  • Dylan, only outputs one entry worth of copy, no image. – CreateSean Feb 9 '13 at 13:13
  • Hi Dylan, when I add the regex code no images get rendered at all. – CreateSean Feb 11 '13 at 11:22
1

Give this a try (see EE comments in the code itself)

Note: this is based on Stash 2.3.6

{exp:channel:entries channel="photoblog" limit="15" disable="member_data|pagination|categories"}

    {exp:stash:set_list name="photos-list" parse_tags="yes"}

        {!-- I set up my variables with this_ or stash_ so when people look at {title} var they know it's a stash variable 
            vs not a normal title var like you had.
        --}

        {stash:this_entry_id}{entry_id}{/stash:this_entry_id}

        {stash:this_title}{title}{/stash:this_title}

        {stash:this_description}{description}{/stash:this_description}

        {!-- What is photos here? If matrix you MAY need to put photos on the outside of stash:this_photos 
        I try and name space like so: channel_fieldtype_name so this might be photoblog_matrix_photos (if it fits.)
        This syntax makes it nice for the next dev for what ever it's worth. Also if you can help it try and keep your viewModel html free and put that in the view itself (this get_list in this case.)
        --}
        {photos}
        {stash:this_photos}{image}{/stash:this_photos}
        {/photos}

    {/exp:stash:set_list}

{/exp:channel:entries}



{!-- You need to use parse_conditionals for your IFs and it's a good idea to prefix your count vars --}
{exp:stash:get_list name="photos-list" orderby="this_entry_id" sort="asc" prefix="prefix" parse_conditionals="yes"}
    <div id="pg_preview">
        <img class="pg_thumb" {if prefix:count=="1"}style="display:block;"{/if} src="{this_photo}" width="1000" height="714" alt="" />
    </div>

    <div id="pg_desc1" class="pg_description">
        <div {if prefix:count=="1"}style="display:block;"{/if}>
            <h2>{this_title}</h2>
        </div>
    </div><!--pg_desc1-->

    <div id="pg_desc2" class="pg_description">
        <div {if prefix:count=="1"}style="display:block;"{/if}>        
            {this_description}
            <a href="#" class="more">Details</a> 
        </div>
    </div><!--pg_desc2-->
{/exp:stash:get_list}

Update

{exp:stash:set_list name="photos-list" parse_tags="yes" parse_depth="2"}

    {exp:channel:entries channel="photoblog" limit="15" disable="member_data|pagination|categories"}

        {stash:entry_id}{entry_id}{/stash:entry_id}

        {stash:title}{title}{/stash:title}

        {stash:description}{description}{/stash:description}

        {!-- try append list here instead if set list doesn't work --}
        {stash:append_list:nested name="photos-matrix" parse_tags="yes"}
            {photos}
                {stash:photos}{image}{/stash:photos}
            {/photos}
        {/stash:append_list:nested}

    {/exp:channel:entries}

{/exp:stash:set_list}


{!-- You need to use parse_conditionals for your IFs and it's a good idea to prefix your count vars - note that you might get away with leaving off :nested on the end of the get list here because, well, it's not nested. --}
<div id="pg_preview">    
    {exp:stash:get_list:nested name="photos-matrix" orderby="entry_id" sort="asc" prefix="prefix" parse_conditionals="yes"}
        <img class="pg_thumb" {if prefix:count=="1"}style="display:block;"{/if} src="{photo}" width="1000" height="714" alt="" />
    {/exp:stash:get_list:nested}
</div>

{exp:stash:get_list name="photos-list" orderby="entry_id" sort="asc" prefix="prefix" parse_conditionals="yes"}
    <div id="pg_desc1" class="pg_description">
        <div {if prefix:count=="1"}style="display:block;"{/if}>
            <h2>{title}</h2>
        </div>
    </div><!--pg_desc1-->

    <div id="pg_desc2" class="pg_description">
        <div {if prefix:count=="1"}style="display:block;"{/if}>        
            {description}
            <a href="#" class="more">Details</a> 
        </div>
    </div><!--pg_desc2-->
{/exp:stash:get_list}
| improve this answer | |
  • Nate, I updated the second code example just now, which is only outputting one image. I also tried putting the photos tags outside of of stash but that didn't change a thing. Will take a look at the second half of your answer tomorrow morning. Need sleep now. – CreateSean Feb 9 '13 at 4:49
  • You may need to have the set_list inside the channel entries tag actually now that I think about it for that Matrix field. Try both ways and see what you get. – Natetronn Feb 9 '13 at 4:56
  • You can see an example here where the set_list is in fact inside of the entries tag. – Natetronn Feb 9 '13 at 5:04
  • Nate, have updated original post with new code that is still not working as expected. thanks for your help so far. – CreateSean Feb 9 '13 at 13:14
  • Nate, I tried the gist that you sent me on twitter. When using that no images are rendered. – CreateSean Feb 11 '13 at 11:23
1

Try this, if it works I'll attempt to explain it!!

Main template (the template that's called by the URL)

{!-- ====================================
FETCH AND CACHE THE RAW DATASET
========================================= --}

{exp:stash:set_list name="data" parse_tags="yes" parse_conditionals="yes" parse_depth="2"}
    {exp:channel:entries channel="photoblog" limit="14" dynamic="no"}
        {stash:titles}{title}{/stash:titles}
        {stash:descriptions}{description}{/stash:descriptions}
        {exp:stash:set_list:2 name="photo_urls" parse_tags="yes" context="cx{count}"}{photos}{stash:url}{image}{/stash:url}{/photos}{/exp:stash:set_list:2}
    {/exp:channel:entries}
{/exp:stash:set_list}

{!-- ====================================
ASSEMBLE MARKUP AROUND THE DATA, ready for 
use in the View.
========================================= --}

{exp:stash:get_list name="data"}  

    {exp:stash:append name="desc1"}
        <div {if count=='1'}style="display:block;"{/if}>
            <h2>{titles}</h2>
        </div>
    {/exp:stash:append}

    {exp:stash:append name="desc2"}
    <div {if count=='1'}style="display:block;"{/if}>        
        {descriptions}
        <a href="#" class="more">Details</a> 
    </div>
    {/exp:stash:append}

    {exp:stash:get_list:2 name="photo_urls" context="cx{count}"}

        {exp:stash:append name="preview_photos"}
            <img class="pg_thumb" {if count=='1'}style="display:block;"{/if} src="{url}" width="900" height="550" alt="" />
        {/exp:stash:append}

        {exp:stash:append name="slider"}
            <div class="content {if count=='1'}first{/if}{if count=='14'}last{/if}">    
                <div><a class="slide-h act" href="#">{exp:ce_img:pair src="{url}" width="120" height="90" crop="yes"}<img src="{made}" alt="" width="{width}" height="{height}" class="thumb" />{/exp:ce_img:pair}<i></i></a></div>
            </div>
        {/exp:stash:append}

    {/exp:stash:get_list:2}

{/exp:stash:get_list}

{!-- ====================================
EMBED the VIEW
========================================= --}

{embed=site/view}

Embedded View template:

<div id="holder" class="h">
  <div class="pg_content"> 

    <div id="pg_preview">
      {exp:stash:preview_photos}
    </div>

    <div id="pg_desc1" class="pg_description">
      {exp:stash:desc1}
    </div><!--pg_desc1-->

    <div id="pg_desc2" class="pg_description">
      {exp:stash:desc2}
    </div><!--pg_desc2-->

  </div>

  <div id="big-mask"></div>

  <div id="thumbContainter">
    <div id="thumbScroller">
      <div class="container">    
        {exp:stash:slider}        
        <div class="marker"></div>    
      </div>

    </div>
  </div><!--thumbContainter-->

</div> <!--holder-->
| improve this answer | |
  • James, I tried your code, but didn't embed the view just pasted it at the end of the first template. That didn't work. Curious as to why the embed? Marks Code above worked as is. – CreateSean Feb 12 '13 at 23:05
  • 1
    It's because of parse order - my main template is setting new variables using stash:append - these will only be available later in the parse order. Mark's example works the same way as mine, but instead of setting the final variables for use later he is outputting directly with get_list. An approach I really like is to refrain from outputting anything in the 'called' template - I just use it to fetch and assemble data for use later. Mark goes a step further and separates the fetching and assembly again (using stash embeds), but for me I usually find that a step too far. – James Smith Feb 12 '13 at 23:22
1
+200

Well I think you're nearly there; first you need the name given to the inner list to be linked to the outer list row item - at the moment you are overwriting it with each iteration of the outer list when you set the lists. You can use {entry_id} as the namespace for that, either as a suffix appended to the inner list name or as the specified context for the inner list (with the context="" parameter). Secondly, you have multiple images to capture so those wrapping tags need to be inside the custom field tag pair. Thirdly, it's good practice to try to capture only values - not markup - when setting variables and lists. Decoupling the capturing/presentation of a set of data like that makes it much easier to change the way that data is presented, permits reuse and aids legibility.

{exp:stash:set_list name="photos-list" parse_tags="yes" parse_depth="2"}
  {exp:channel:entries channel="photoblog" limit="5" orderby="" disable="member_data|pagination|categories" dynamic="no"}

      {stash:entry_id}{entry_id}{/stash:entry_id}
      {stash:title}{title}{/stash:title}
      {stash:description}{description}{/stash:description}

      {exp:stash:set_list:nested name="photos-image_{entry_id}" parse_tags="yes"}     
          {photos}
             {stash:image}{image}{/stash:image}
          {/photos}
      {/exp:stash:set_list:nested}    

  {/exp:channel:entries} 
{/exp:stash:set_list} 


{exp:stash:get_list 
  name="photos-list" 
  orderby="entry_id" 
  sort="asc" 
  limit="5"
  prefix="outer"
}
    <div id="pg_preview">
      {exp:stash:get_list:nested name="photos-image_{entry_id}" prefix="inner"}
          <img class="pg_thumb" {if inner:count==1}style="display:block;"{/if} src="{image}" width="1000" height="714" alt="{title}" />
      {/exp:stash:get_list:nested}
    </div>

    <div id="pg_desc1" class="pg_description">
      <div {if outer:count=="1"}style="display:block;"{/if}>
        <h2>{title}</h2>
      </div>
    </div><!--pg_desc1-->

    <div id="pg_desc2" class="pg_description">
        <div {if outer:count=="1"}style="display:block;"{/if}>        
          {description}
          <a href="#" class="more">Details</a> 
        </div>
    </div><!--pg_desc2-->

{/exp:stash:get_list}

There is an example of nesting lists in the docs too: https://github.com/croxton/Stash#example-usage-5-nesting-yep-you-really-can-do-this

| improve this answer | |
  • Mark, Thank you that worked on my testing template. I had looked at the nesting docs, but I guess I misunderstood them. In any case your code above has clarified things for me and I'll be trying out stash again on other sites as needed. – CreateSean Feb 12 '13 at 23:06

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.