Extension, Module

Archived
Forum
(read-only)

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

     

Stash and CT Inline Errors

Support Request

jdaalder
jdaalder

Hi Mark

I am trying to use Cartthrob inline error handling with Stash (all my template layouts are done via stash).

My default interior layout just has a slot for page_body.

If I do the error handling on a straight template, it works, but when I try and stash a page_body I simply don’t get any of the errors coming up.  I notice someone else on the solspace forum having issues with inline errors with stash involved.

After form submission, if I am missing required fields, the code below will print errors on a normal template…but not when I stash into a page_body var. I presume there is some very late in parse order stuff going on with these errors, and I am wondering on best strategy to get around this.  I have tried an exp:stash:parse around the form to force inline processing and increasing parse_depth etc.

{errors}
    
<class="error">{error}</p>
    
{/errors}
     
    {errors}
    {
!-- contains these variables--}
    {error}
    {field}
    {error
:count}
    {error
:total_results}
    {if global_error}1{
/if}
    {if field_error}2{
/if}
    {if first_error}3{
/if}
    {if last_error}4{
/if}
    {
/errors} 

Full template code at:
http://pastebin.com/f4Pj5PCh

I could build a straight template but I have almost everything working without needing to do this anywhere, so I am trying to avoid adding another approach.

I have noticed CT doing some very late in the day stuff with shipping and worked around it by ajax loading a shipping chunk after document.ready, but that seems absurb to have to do really.

Any ideas on this one?  Thanks as ever!

Mark Croxton
# 1
Developer
Mark Croxton

It looks like Solspace Freeform saves inline form errors to the session flash data and then does a redirect. CT is probably the same. I’ll test that one later, but please try this first:

Please try changing this:

{exp:stash:set name='page_body' parse="yes" parse_depth="10"

To:

{exp:stash:set name='page_body'

 

jdaalder
# 2
jdaalder

Thanks Mark

That’s where I started, same issue I am afraid.  I was trying to force it to parse that bit earlier basically.  Yes, I a guessing you’re right re the session data.  Unfortunately the CT debugging only shows the cart stuff from the session.

Mark Croxton
# 3
Developer
Mark Croxton

I’ve tried replicating what you’re doing, only using a Solspace Freeform as I don’t have CT - but it all works as expected.

So CT must be doing something different than just setting errors as flashdata (the session). If CT are using the template_post_parse hook it might be an extension order issue. Perhaps try changing the priority value in the `exp_extensions` table for extensions on this hook for CT (try lower then higher values than Stash, which is set to 10 by default).

If that doesn’t help then it might be best to try to reduce your template code to the absolute minimum for the problem to still exist. Basically nothing but the stash set around the form, and the layout embed with just the {stash:content} in it. You may find that removing other tags from the template fixes the issue, which might point to the problem.

Incidently, another way of ‘filling the hole’ in a layout is to extend it with another template. Let’s say you create a stash embed partials/checkout containing your CT form. You can then do this to populate {stash:page_body}

{exp:stash:extend name="page_body" with="partials:checkout"

You can also use blocks in your layout, which work just like a stash:get but allow you to provide default content.

{exp:stash:block name="page_body"}
   {
!-- default contentmaybe your checkout form --}
{
/exp:stash:block} 

Might be worth trying these too.

 

 

jdaalder
# 4
jdaalder

Hmm, can’t find (grep) template_post_parse anywhere in CT, also for tempalte_post_parse in exp_extensions I have only two things, Mo variables and stash (both set to 10).

However, a re-direct is definitely being used, and is flashdata…basically, this seems to to be the error handling bit in CTs form builder:

public function action_complete($validate FALSE$secure_forms TRUE)
 
{
  $this
->EE->load->library('javascript');
  
  
//dumb stuff for ee2.1.3
  
if ( ! isset($this->EE->security) || get_class($this->EE->security) !== 'EE_Security')
  
{
   
require_once APPPATH.'core/EE_Security.php';
   
   
$this->EE->security = new EE_Security;
  
}
  
  
if ( ! $this->return)
  
{
   $this
->return = ($this->EE->input->get_post('return')) ? $this->EE->input->get_post('return'TRUE) : $this->EE->uri->uri_string();
  
}
  
  $url 
$this->parse_path($this->return);
  
  if (
$this->is_secure() || $this->bool_string($this->EE->input->post('secure_return')))
  
{
   $url 
$this->secure_url($url);
  
}
  
  $flashdata 
= array(
   
'success' => ! $this->errors(),
   
'errors' => $this->errors(),
   
'return' => $url,
  );
  
  if (
AJAX_REQUEST && $this->EE->config->item('secure_forms') === 'y')
  
{
   $flashdata[
'CSRF_TOKEN'$this->EE->functions->add_form_security_hash('{CSRF_TOKEN}');
  
}
  
  
//temp. store the current value of end_script, in case this call is nested inside another hook's call
  
$end_script $this->EE->extensions->end_script;
  
  foreach (
$flashdata as $key => $value)
  
{
   $this
->EE->session->set_flashdata($key$value);
  
}
  
  
if ($this->EE->input->post('ERR'))
  
{
   $this
->set_show_errors($this->bool_string($this->EE->encrypt->decode($this->EE->input->post('ERR')), TRUE));
  
}
  
  
if ($this->errors())
  
{
   $this
->callback($this->error_callback);
   
   if (
$this->show_errors && ! AJAX_REQUEST)
   
{
    
if ($this->EE->input->post('error_handling') === 'inline')
    
{
     
foreach ($this->values as $key)
     
{
      $value 
$this->EE->input->post($key);
      
      
//custom_data[foo] => custom_data:foo
      
if (is_array($value))
      
{
       
foreach ($value as $k => $v)
       
{
        $this
->add_form_variable($key.':'.$k$v);
       
}
      }
      
else
      
{
       $this
->add_form_variable($key$value);
      
}
     }
     
     $method 
= (version_compare(APP_VER'2.1.3''>')) ? 'generate_page' '_generate_page';
     
     
$this->EE->load->add_package_path(PATH_THIRD.'cartthrob/');
     
     
$this->EE->core->$method();
     
     
$this->EE->extensions->end_script $end_script;
     
     return;
    
}

    
// if this is not loaded.... then the user_message template can not be output as part of show_error 2.6x
    // basically the exception class's show_error looks to see if TMPL is set... if not it outputs the general_error.php file... which we don't want. 
    
if ( ! isset($this->EE->TMPL))
    
{
     $this
->EE->load->library('template'NULL'TMPL');
    
}
    
// since we'll be removing post in a minute, I'm creating temporary variables to store some stuff that would otherwise rely on post's existance
    
$errors $this->errors(); 
    
$error_header $this->error_header
    if (!empty(
$_POST))
    
{
     
unset($_POST); // we're unsetting post because show_error... a near useless function that is intended to replace show_user_error will otherwise insert a javascript back link which will then be replaced with [removed] link and will show some effed up code. show_message function of EE's output class basically has a bug. If that gets fixed, we can undo this so that the back link will be shown correctly. FOr now, removing $_POST will remove the bad back link. 
     
$_POST = array(); 
    
}   
      
return show_error$errors$status_code 500,  $error_header);    

   
}
  }
  
  
/*
  if ($secure_forms &&  ! $this->EE->security->secure_forms_check($this->EE->input->post('csrf_token')))
  {
   if($this->EE->input->post('RET'))
   {
    $this->EE->functions->redirect(stripslashes($this->EE->input->post('RET')));
   }
  }
  */ 
  
  
if ( ! $this->errors())
  
{
   $this
->callback($this->success_callback);
  
}
  
  
//$url = $this->EE->functions->create_url($this->return);
  
  
$this->EE->functions->redirect($url);
 


I’ll try with the alternative methods of injecting the content etc, and simplifying, but thought I’d get this going as it might be a clue.

 

jdaalder
# 5
jdaalder

hmm, actually no, there’s a return in the inline errors but before the re-direct isn’t there?  Commenting that out means I get standard EE errrors.

 

jdaalder
# 6
jdaalder

Hmm, ok, seems that it’s a conflict with two forms on one page (the login form being above the other one).  The top one not having errors appears to overwrite those vars or something.

var prefixing doesn’t apply to the returned errors either it seems.  Drat.

Thanks again, and for the alternate approach with extends.  Interesting!

 

 

 

Mark Croxton
# 7
Developer
Mark Croxton

No problem! Glad you worked out what the problem was at least.