croxton / Stash

Stash allows you to stash text and snippets of code for reuse throughout your templates.
GNU General Public License v3.0
198 stars 20 forks source link

Set and get stash within entry loop #152

Closed Third-Hyperion closed 7 years ago

Third-Hyperion commented 7 years ago

How can I set and get stash within the same entry loop.

Can't figure it out for the life of me.

`{exp:stash:parse process="end"} {exp:channel:entries channel="products" status="open" limit="10"}

New Arrival

{title}

{if product_original_price && product_original_price > product_price} {product_price:plus_tax} {product_original_price:plus_tax} {exp:stash:set name="sale_tag"}Sale{/exp:stash:set} {if:else} {product_price:plus_tax} {/if}
{exp:stash:get name="sale_tag" process="end"}
{/exp:channel:entries}

{/exp:stash:parse}`

croxton commented 7 years ago

That won't work because the value of 'sale_tag' will change with each iteration of the channel:entries loop, and by adding process="end" you are basically asking to get the last value the variable was set to. It doesn't make any sense because you are assuming that expressionengine tags are being parsed linearly (top to bottom in order on each iteration of the channel entries loop, like PHP or Javascript) but they are actually parsed recursively - from the outermost "shell" of tags inwards, one layer parsed on each pass of the parser.

Looking at that code I don't see why you need Stash at all, why not just use the channel:entries variables where you want them?

Third-Hyperion commented 7 years ago

It was to save having another if statement within the entry loop. I thought it would be cleaner? Is there a way with stash I can achieve this? stashing and getting a variable within same loop?

Thanks,

Wes

On 1 February 2017 at 10:11, Mark Croxton notifications@github.com wrote:

That won't work because the value of 'sale_tag' will change with each iteration of the channel:entries loop, and by adding process="end" you are basically asking to get the last value the variable was set to. It doesn't make any sense because you are assuming that expressionengine tags are being parsed linearly (top to bottom in order on each iteration of the channel entries loop, like PHP or Javascript) but they are are actually parsed recursively - from the outermost "shell" of tags inwards.

Looking at that code I don't see why you need Stash at all, why not just use the channel:entries variables where you want them?

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/croxton/Stash/issues/152#issuecomment-276619827, or mute the thread https://github.com/notifications/unsubscribe-auth/AFVG2rcsDuSbSjfIowYoVZoXuHPIMFuNks5rYFpqgaJpZM4LzN8s .

croxton commented 7 years ago

It will be far slower than just using a conditional. EE will parse conditionals in one go, but if you use a Stash tag to get a variable value then for each tag EE must instantiate a new Stash instance to return a value. Much more memory required, so not sensible.

But if you did need to do it you would do something like this:

{exp:channel:entries ...}
      {exp:stash:set name="my_variable"}{title}{/exp:stash:set}
      ...
      {exp:stash:get name="my_variable" random}
{/exp:channel:entries}

Note the 'random' on the stash:get. That's to stop EE caching the output of the tag the first time it encounters it.

But like I say, don't do this.

Third-Hyperion commented 7 years ago

Thank's Mark! So benefical for me to know, I'd never known it would be slower. I'm not very expereinced in that area, so everything is a learning curve! I just thought because it looked cleaner to me it would be more efficient, but that's not the case! Thank you again.

Wes

On Thu, 2 Feb 2017 at 11:46 am, Mark Croxton notifications@github.com wrote:

It will be far slower than just using a conditional. EE will parse conditionals in one go, but if you use a Stash tag to get a variable value then for each tag EE must instantiate a new Stash instance to return a value. Much more memory required, so not sensible.

But if you did need to do it you would do something like this:

{exp:channel:entries ...} {exp:stash:set name="my_variable"}{title}{/exp:stash:set} ... {exp:stash:get name="my_variable" random} {/exp:channel:entries}

Note the 'random' on the stash:get. That's to stop EE caching the output of the tag the first time it encounters it.

But like I say, don't do this.

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/croxton/Stash/issues/152#issuecomment-276936654, or mute the thread https://github.com/notifications/unsubscribe-auth/AFVG2tw-wgMjv1LkbX0T1hL5QEjPveIXks5rYcIlgaJpZM4LzN8s .