Take the 2-minute tour ×
ExpressionEngine® Answers is a question and answer site for administrators, end users, developers and designers for ExpressionEngine® CMS. It's 100% free, no registration required.

I'm having an odd issue with Stash and a 404 redirect. When an entry isn't found the "layout" template is getting rendered twice around the main Stash content. Anyone seen this before? I can kinda see why it is happening, but can see any way around it. Thoughts?

The page template

{!-- Layout --}
{embed="shared/_layout"}

{!-- Set main content --}
{exp:stash:set 
    name="main_content" 
    parse_tags="yes" 
    parse_depth="2" 
    no_results_prefix="nested"}

  {exp:channel:entries limit="1" url_title="{segment_3}"}
    {if nested:no_results}{redirect="404"}{/if} 
  {/exp:channel:entries}

{/exp:stash:set}

The 404 template

{!-- Layout --}
{embed="shared/_layout"}

{!-- Set main content --}
{exp:stash:set name="main_content"}
  <h1>Page not found</h1>
{/exp:stash:set}

The layout template

<body>
  HEADER GOES HERE!!!
  {exp:stash:get name='main_content'}
  FOOTER GOES HERE!!!
</body>

The resulting output to browser

<body>
  HEADER GOES HERE!!!
<body>
  HEADER GOES HERE!!!

  <h1>Page not found</h1>

  FOOTER GOES HERE!!!
</body>
  FOOTER GOES HERE!!!
</body>

EDIT: Seems I can get around the issue by removing the Stash/layout stuff from the 404 template and just having it as...

<h1>Page not found</h1>

But then a 404 generated by some means other than no_results won't get the layout. Hmm. Ideas?

share|improve this question

5 Answers 5

If you look at function no_results() in ./system/expressionengine/libraries/Template.php you will see that when a 404 template is defined as simply "404" within a redirect tag, then the 404 template referenced by the config value site_404 is fetched and parsed. The template is not returned by the function but my guess is that it populates the property $EE->template->tagdata with the 404 template tagdata, which Stash will subsequently capture. Hence the apparent recursion.

The solution to this rather odd problem is to simply reference the 404 template by template_group/template, e.g. "site/404" in which case the no_results functions will send a redirect header via $EE->functions->redirect.

share|improve this answer
    
I'm having the same problem but in my case it's happening not only with redirects in templates (which adding site/404 fixes), it's also occurring when EE applies the default 404 template for a non-existent first segment. –  Tyssen yesterday
    
Also, do you know if redirecting to a 404 template rather than displaying the broken URL with a 404 header still reports the URL as being 404 to the search engines? –  Tyssen yesterday
    
I've just spent a few hours looking again at 404 handling in EE, and now have a new tag {exp:stash:not_found} that will allow you to reliably display the 404 template in all situations, set the 404 header (without needing another add-on/php) and maintain the URL being viewed. Will push to the repo tomorrow. –  Mark Croxton 19 hours ago
    
Excellent news :) –  Tyssen 16 hours ago

OK. I think I have a solution. Anyone know a better way?

The Page Template

{!-- Layout --}
{embed="shared/_layout"}

{!-- Set main content --}
{exp:stash:set 
    name="main_content" 
    parse_tags="yes" 
    parse_depth="2" 
    no_results_prefix="nested"}

  {exp:channel:entries limit="1" url_title="{segment_3}"}
    {if nested:no_results}
      {exp:stash:set_value name="no_results" value="true"}
    {/if}  
  {/exp:channel:entries}

{/exp:stash:set}

Inside of the layout template

{if {exp:stash:not_empty name="no_results"}}
  {exp:stash:unset name="no_results"}
  {redirect="404"}
{/if}
share|improve this answer

You should turn on your template debug and look for:

Stash: SET or Stash: RETRIEVED

Figuring out if Stash is being called twice is probably where I'd start. If it's a duplicitous call to Stash vs. some Stash internal thing that would be good to know. I have a feeling it's an internal thing that doesn't play nice with the 'redirect' global. I'd have to start commenting out code in Stash to try and nail it down.

share|improve this answer

Just looked a little more. I'm betting it's a parse order thing (http://ellislab.com/expressionengine/user-guide/templates/template_engine.html). Likely the simple conditional is parsing the redirect before Stash is parsed causing some sort of double loop. You're solution is certainly a functional work around.

You might want to try using parse="inward" in the Stash tag, that would probably change the order Stash and the nested elements are parsing and might fix the issue.

share|improve this answer

This could be a documented EE bug which causes the home page template to be rendered after the 404 content. It can be fixed with a small change to a core file.

https://support.ellislab.com/bugs/detail/20471/site-index-template-is-rendered-after-the-404-template

I do note that it says this is fixed in the released version but it was present up to 2.9.0

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.