Extension, Module

Developer
Supported

Stash

ExpressionEngine 2, ExpressionEngine 3, ExpressionEngine 4, ExpressionEngine 5, ExpressionEngine 6

Back to this add-on's main page
View Other Add-ons From Mark Croxton

     

You must be logged in to post.

Dynamically populating Stash from Matrix field

General

Neal Hulme
Neal Hulme

I’m trying to mimic the NSM Transplant behaviour demonstrated by Etsur by dynamically populating a stash variable pulled from a custom field with dynamically created variables from a matrix field. I’ve got it working after playing around for a while, and getting my head around parse order again. The only limitation is that I have to do a find and replace so the user can use sensible place holders in the field contents.

Am I missing something that could make this easier? Ideally I would like to be able to use the straight tag per snippets but as you can’t use snippets in snippets it’s not a goer. Is there a way of assigning the values to a global variable type which gets parsed after the snippets? Any thoughts would be gratefully received as I would like to use Stash over NSM Transplant as it has other functionality I use, and of course it’s free which is greatly appreciated, thanks.

The model template looks something like this where {images} is a P&T Matrix field and the content field contains placeholders for the images that look like {image_1}

{embed="default/model"}

{exp
:channel:entries}
 {images}
  {exp
:stash:set name="image_{row_count}"}
   
<img src="{image_file:url}" width="{image_file:width}" height="{image_file:height}" alt="{image_title}">
  
{/exp:stash:set}
 {
/images}
 {exp
:stash:set name="content" type="snippet"}
  {exp
:low_replace find="/{image_[0-9]}/" replace="{exp:stash:get name='image_$1'}" regex="yes"}{content}{/exp:low_replace}
 {
/exp:stash:set}
{
/exp:channel:entries} 

The view template simply outputs the {content} variable

<!DOCTYPE html>

<
html lang="en" dir="ltr" class="no-js">

<
head>
 <
meta charset="UTF-8">
 <
title>Page Title</title>
</
head>

<
body>
 
{content}
</body>

</
html
Mark Croxton
# 1
Developer
Mark Croxton

Hi Neal

please try adding parse=“inward” to the channel entries tag, and then add parse_vars=“yes” to second stash tag.

That should do the trick, but if not there is another way to do it so let me know!

 

Neal Hulme
# 2
Neal Hulme

Hi Mark,

thanks for getting back to me although I think I am more confused now…

The code for the ‘model’ template is below with the two modifications you suggested, parse=“inward’ on the Channel Entries and parse_vars=“yes” on the second Stash tag. I have also removed the Low Replace tag as I assume this is not required. Testing this with a dummy entry that has three rows in the Matrix field {page_images} and the {page_body} field containing a string with three arbitrary placeholder strings {image_1}, {image_2} and {image_3} I simply get the string outputted through the view template. If I add the Low Replace back in which replaces /{image_([0-9])}/ with {exp:stash:get name=“image_$1”} in the {page_body} field it works and outputs the three image elements on the page.

Have I missed something? I was also a little confused as I could find no mention of the ‘parse_vars’ parameter so tried it anyway, and ‘parse_tags’, with no luck.

You also mentioned another way to do this?

{embed="views/default"}

{exp
:channel:entries
 channel
="pages"
 
disable="categories|category_fields|member_data|pagination"
 
dynamic="no"
 
parse="inward"
}
 {page_images}
  {exp
:stash:set name="image_{row_count}"}
   
<img src="{image_file:url}" width="{image_file:width}" height="{image_file:height}" alt="{image_caption}">
  
{/exp:stash:set}
 {
/page_images}
 {exp
:stash:set name="content" type="snippet" parse_vars="yes"}{page_body}{/exp:stash:set}
{
/exp:channel:entries} 

 

Mark Croxton
# 3
Developer
Mark Croxton

Sorry, parse_vars is in the latest version of Stash on the dev branch. You can download it here:

https://github.com/croxton/Stash/tree/dev/third_party/stash

Getting back to your problem, this is the alternative approach:

viewModel

{embed="views/default"}

{exp
:channel:entries
 channel
="pages"
 
disable="categories|category_fields|member_data|pagination"
 
dynamic="no"
 
parse="inward"
}
 {page_images}
  {exp
:stash:set name="image_{row_count}" type="snippet"}
   
<img src="{image_file:url}" width="{image_file:width}" height="{image_file:height}" alt="{image_caption}">
  
{/exp:stash:set}
 {
/page_images}
 {exp
:stash:set name="content"}{page_body}{/exp:stash:set}
{
/exp:channel:entries} 

view

<!DOCTYPE html>

<
html lang="en" dir="ltr" class="no-js">

<
head>
 <
meta charset="UTF-8">
 <
title>Page Title</title>
</
head>

<
body>
 
{exp:stash:get name="content" parse_vars="yes"}
</body>

</
html

 

Neal Hulme
# 4
Neal Hulme

This looks great! Should I be aware of anything if I am using the development branch or is it pretty stable?