Thanks so much Matt.
You're absolutely right. The extra $ symbols were the cause.
I was even able to split the Your name and Business name field into two separate text fields and add the necessary code into the CTFMW page.
It is working beautifully.
BTW
After adding the EXPIRES code to the .htaccess file and implementing our custom minified and combined CSS and JS resources / PHP removal, we've knocked our sitespeed down to under 3 seconds pretty consistently. Saved a consistent half a second across the board for all page templates.
I'm very happy with this, so thanks for posting up the fix even if it was more for security purposes.
And again thank you for all the help Matt!
Announcement
Collapse
No announcement yet.
PHP Removal Update for Suivant
Collapse
This is a sticky topic.
X
X
-
It looks like there was some errant code in your subject values. Try using this for the form processing page:
Code:<mvt:assign name="g.http_referer" value="s.http_referer" /> <mvt:if expr="'CTFMW' CIN g.http_referer OR 'wholesale-contact-form' CIN g.http_referer"> <mvt:exit> </mvt:if> <mvt:if expr="NOT ISNULL g.website"> <meta http-equiv="refresh" content="0;url=&mvte:urls:NTFD:auto;" /> <mvt:else> <mvt:assign name="g.eol" value="asciichar(13) $ asciichar(10)"/> <mvt:if expr="(ISNULL g.website) AND (NOT ISNULL g.human) AND (isdigit(g.human)) AND (g.human EQ crypto_base64_decode(g.verify))"> <mvt:comment> <!-- This will create the From address in proper format: "Store Name" <store_email@store_domain> --> </mvt:comment> <mvt:assign name="l.mail:from" value="asciichar(34) $ g.store:name $ asciichar(34) $ ' <' $ g.store:email $ '>'" /> <mvt:comment> <!-- This will create the Reply-To address in proper format: "Visitor Name" <visitor_email@visitor_domain> --> </mvt:comment> <mvt:assign name="l.mail:reply" value="asciichar(34) $ g.contactName $ asciichar(34) $ ' <' $ g.contactEmail $ '>'" /> <mvt:comment> <!-- By default, this form is designed to send to the store email address. You can change this by replacing g.store:email with 'my_email@my_domain.com'. --> </mvt:comment> <mvt:assign name="l.mail:to" value="g.store:email" /> <mvt:comment> <!-- If you would like to CC the form, you can add an address or a comma separated list to CC to multiple addresses. <mvt:assign name="l.mail:cc" value="'my_email@my_domain.com'" /> - OR - <mvt:assign name="l.mail:cc" value="'my_email@my_domain.com,my_other_email@my_domain.com'" /> --> </mvt:comment> <mvt:assign name="l.mail:cc" value="''" /> <mvt:comment> <!-- If you would like to BCC the form, you can add an address or a comma separated list to BCC to multiple addresses. <mvt:assign name="l.mail:bcc" value="'my_email@my_domain.com'" /> - OR - <mvt:assign name="l.mail:bcc" value="'my_email@my_domain.com,my_other_email@my_domain.com'" /> --> </mvt:comment> <mvt:assign name="l.mail:bcc" value="''" /> <mvt:comment> <!-- This will create a custom subject line for the email. --> </mvt:comment> <mvt:assign name="l.mail:subject" value="g.store:name $ 'Wholesale Inquiry: ' $ g.contactSubject" /> <mvt:comment> <!-- This will create the store message from user input. --> </mvt:comment> <mvt:assign name="l.mail:message" value="'Message from: ' $ g.contactName $ g.eol $ g.eol $ 'Email Address: ' $ g.contactEmail $ g.eol $ g.eol $ 'Phone Number: ' $ g.contactPhone $ g.eol $ g.eol $ 'Message:' $ g.eol $ g.contactMessage" /> <mvt:comment> <!-- If you would like to send any additional SMTP headers, you can do that here. --> </mvt:comment> <mvt:assign name="l.mail:headers" value="l.mail:headers $ 'Reply-To:' $ l.mail:reply $ g.eol" /> <mvt:assign name="l.mail:headers" value="l.mail:headers $ 'Return-Path:' $ l.mail:from $ g.eol" /> <mvt:assign name="l.mail:headers" value="l.mail:headers $ 'MIME-Version: 1.0' $ g.eol" /> <mvt:assign name="l.mail:headers" value="l.mail:headers $ 'Content-Type: text/plain; charset=utf-8' $ g.eol" /> <mvt:comment> <!-- This function will send an email to the store. --> </mvt:comment> <mvt:do file="g.Module_Library_Utilities" name="g.sent" value="v9_SendEmail(l.mail)" /> <mvt:comment> <!-- This function will send a confirmation email to the visitor. If you do not wish to send a confirmation email, you can either `mvt:comment` this section out or delete it all together. --> </mvt:comment> <mvt:assign name="l.visitor_mail:from" value="asciichar(34) $ g.store:name $ asciichar(34) $ ' <' $ g.store:email $ '>'" /> <mvt:assign name="l.visitor_mail:to" value="asciichar(34) $ g.contactName $ asciichar(34) $ ' <' $ g.contactEmail $ '>'" /> <mvt:assign name="l.visitor_mail:subject" value="g.store:name $ 'Wholesale Inquiry: ' $ g.contactSubject" /> <mvt:assign name="l.visitor_mail:message" value="'Dear ' $ g.contactName $ ',' $ g.eol $ g.eol $ 'Thank you for contacting ' $ g.store:name $ '; your message has been received.' $ g.eol $ g.eol $ 'Your Message:' $ g.eol $ g.contactMessage" /> <mvt:assign name="l.visitor_mail:headers" value="'Reply-To:' $ asciichar(34) $ g.store:name $ asciichar(34) $ ' <' $ g.store:email $ '>' $ g.eol" /> <mvt:do file="g.Module_Library_Utilities" name="g.visitor_sent" value="v9_SendEmail(l.visitor_mail)" /> <mvt:if expr="g.sent"> <meta http-equiv="refresh" content="0;url=&mvte:urls:GRWS:auto_sep;status=submitted" /> <mvt:else> <meta http-equiv="refresh" content="0;url=&mvte:urls:GRWS:auto_sep;status=error" /> </mvt:if> <mvt:else> <meta http-equiv="refresh" content="0;url=&mvte:urls:GRWS:auto_sep;status=error&contactName=&mvte:global:contactName;&contactEmail=&mvte:global:contactEmail;&contactPhone=&mvte:global:contactPhone;&contactSubject=&mvte:global:contactSubject;&contactMessage=&mvte:global:contactMessage;&fault=has-error" /> </mvt:if> </mvt:if>
Leave a comment:
-
found a dumb mistake on the form:
changed data-action="&mvte:urls:GRWS:auto;" to data-action="&mvte:urls:CTFMW:auto;" and now when I try the form it gives this error:
Fatal error in mm5/5.00/templates/s01/ctfmw.mvc @ [00000002:000002f0]: features/tui/tui_mgr.mv: Line 62: Stack underflow
Leave a comment:
-
-
Thank for sending that link but I'm still stumped as to why it will not work.
Here is the code for the Wholesale Contact Form on the GRWS page.
Code:<div class="column whole medium-half"> <h2 style="margin-bottom:0;font-size:1.5rem">Wholesale Contact Form:</h2> <noscript> <p class="message message-error" data-hook="contact-us__warning">You must javascript enabled to use this form.</p> </noscript> <form class="contact-form hide" data-hook="contact-form" data-action="&mvte:urls:GRWS:auto;" action="#" method="post" accept-charset="UTF-8"> <fieldset class="corners"> <legend><small>Bold fields are required.</small></legend> <mvt:comment> <!-- This field is a spam-bot honeypot, it should not have a value! --> </mvt:comment> <input class="all-hidden" type="text" name="website"> <mvt:if expr="g.status EQ 'submitted'"> <div class="message message-success">Thank you for your inquiry. A &mvte:global:store:name; representative will contact you shortly.</div> <mvt:elseif expr="g.status EQ 'error'"> <div class="message message-error">We're sorry, there was a problem processing your request.</div> </mvt:if> <div class="form-row"> <label class="required" for="contactName">Your name & Business name:</label> <input id="contactName" tabindex="1" type="text" name="contactName" value="&mvte:global:contactName;" required> </div> <div class="form-row"> <label class="required" for="contactEmail">Your email address:</label> <input id="contactEmail" tabindex="2" type="email" name="contactEmail" value="&mvte:global:contactEmail;" placeholder="[email protected]" required> </div> <div class="form-row"> <label class="required" for="contactPhone">Your phone:</label> <input id="contactPhone" tabindex="3" type="text" name="contactPhone" value="&mvte:global:contactPhone;" required> </div> <div class="form-row"> <label class="required" for="contactSubject">What can we help you with?</label> <mvt:comment> <!-- This field helps to set the subject of the email. Set as many options as you would like. --> </mvt:comment> <select id="contactSubject" style="height: 2.5em" class="c-form-select__dropdown" tabindex="4" name="contactSubject" required> <mvt:if expr="g.contactSubject EQ 'Questions'"> <option value="Questions" selected>General Wholesale Questions</option> <mvt:else> <option value="Questions">General Wholesale Questions</option> </mvt:if> <mvt:if expr="g.contactSubject EQ 'Pricing'"> <option value="Pricing" selected>Wholesale Pricing</option> <mvt:else> <option value="Pricing">Wholesale Pricing</option> </mvt:if> <mvt:if expr="g.contactSubject EQ 'Shipping'"> <option value="Shipping" selected>Shipping / Turnaround Time</option> <mvt:else> <option value="Shipping">Shipping / Turnaround Time</option> </mvt:if> </select> </div> <div class="form-row"> <label class="required" for="contactMessage">Questions:</label> <textarea id="contactMessage" tabindex="5" name="contactMessage" placeholder="Type your questions or message here...">&mvte:global:contactMessage;</textarea> </div> <div class="form-row &mvte:global:fault;"> <label class="column whole np required" for="contactHuman">Are you human?</label> <mvt:comment> <!-- This is a basic math challenge to confirm there is a person entering the information. The numbers are random and the answer key is passed to the process in Base64 for comparison. --> </mvt:comment> <mvt:assign name="l.settings:humanOne" value="random('25')" /> <mvt:assign name="l.settings:humanTwo" value="random('25')" /> <mvt:assign name="l.settings:verify" value="crypto_base64_encode(l.settings:humanOne + l.settings:humanTwo)" /> <div class="column half np"> <input class="align-center" type="text" value="&mvte:humanOne; + &mvte:humanTwo; =" disabled> </div> <div class="column half np"> <input id="contactHuman" tabindex="6" type="tel" name="human" value="" required> </div> <input type="hidden" name="verify" value="&mvte:verify;"> </div> <div class="form-row align-right"> <button class="button button-square bg-black corners" data-hook="contact-form__submit" type="submit" name="submit" disabled>Submit</button> </div> </fieldset> </form> </div> <script> (function () { 'use strict'; var contactForm = document.querySelector('[data-hook="contact-form"]'); if (contactForm) { var contactFormAction = contactForm.getAttribute('data-action'); var contactFormButton = document.querySelector('[data-hook="contact-form__submit"]'); var humanCheck = contactForm.querySelector('[type="text"][disabled]'); contactForm.classList.remove('hide'); humanCheck.style.color = '#000'; /** * Unlock the form if the user is utilizing a touch interface. */ window.addEventListener('touchstart', function touchedForm() { contactForm.setAttribute('action', contactFormAction); contactFormButton.removeAttribute('disabled'); window.removeEventListener('touchstart', touchedForm, false); }, false); /** * Unlock the form if the user can hover over elements. */ window.addEventListener('mouseover', function mouseForm() { contactForm.setAttribute('action', contactFormAction); contactFormButton.removeAttribute('disabled'); window.removeEventListener('mouseover', mouseForm, false); }, false); } })(); </script>
Code:<mvt:assign name="g.http_referer" value="s.http_referer" /> <mvt:if expr="'CTFMW' CIN g.http_referer OR 'wholesale-contact-form' CIN g.http_referer"> <mvt:exit> </mvt:if> <mvt:if expr="NOT ISNULL g.website"> <meta http-equiv="refresh" content="0;url=&mvte:urls:NTFD:auto;" /> <mvt:else> <mvt:assign name="g.eol" value="asciichar(13) $ asciichar(10)"/> <mvt:if expr="(ISNULL g.website) AND (NOT ISNULL g.human) AND (isdigit(g.human)) AND (g.human EQ crypto_base64_decode(g.verify))"> <mvt:comment> <!-- This will create the From address in proper format: "Store Name" <store_email@store_domain> --> </mvt:comment> <mvt:assign name="l.mail:from" value="asciichar(34) $ g.store:name $ asciichar(34) $ ' <' $ g.store:email $ '>'" /> <mvt:comment> <!-- This will create the Reply-To address in proper format: "Visitor Name" <visitor_email@visitor_domain> --> </mvt:comment> <mvt:assign name="l.mail:reply" value="asciichar(34) $ g.contactName $ asciichar(34) $ ' <' $ g.contactEmail $ '>'" /> <mvt:comment> <!-- By default, this form is designed to send to the store email address. You can change this by replacing g.store:email with 'my_email@my_domain.com'. --> </mvt:comment> <mvt:assign name="l.mail:to" value="g.store:email" /> <mvt:comment> <!-- If you would like to CC the form, you can add an address or a comma separated list to CC to multiple addresses. <mvt:assign name="l.mail:cc" value="'my_email@my_domain.com'" /> - OR - <mvt:assign name="l.mail:cc" value="'my_email@my_domain.com,my_other_email@my_domain.com'" /> --> </mvt:comment> <mvt:assign name="l.mail:cc" value="''" /> <mvt:comment> <!-- If you would like to BCC the form, you can add an address or a comma separated list to BCC to multiple addresses. <mvt:assign name="l.mail:bcc" value="'my_email@my_domain.com'" /> - OR - <mvt:assign name="l.mail:bcc" value="'my_email@my_domain.com,my_other_email@my_domain.com'" /> --> </mvt:comment> <mvt:assign name="l.mail:bcc" value="''" /> <mvt:comment> <!-- This will create a custom subject line for the email. --> </mvt:comment> <mvt:assign name="l.mail:subject" value=" $ g.store:name $ 'Wholesale Inquiry: ' $ g.contactSubject" /> <mvt:comment> <!-- This will create the store message from user input. --> </mvt:comment> <mvt:assign name="l.mail:message" value="'Message from: ' $ g.contactName $ g.eol $ g.eol $ 'Email Address: ' $ g.contactEmail $ g.eol $ g.eol $ 'Phone Number: ' $ g.contactPhone $ g.eol $ g.eol $ 'Message:' $ g.eol $ g.contactMessage" /> <mvt:comment> <!-- If you would like to send any additional SMTP headers, you can do that here. --> </mvt:comment> <mvt:assign name="l.mail:headers" value="l.mail:headers $ 'Reply-To:' $ l.mail:reply $ g.eol" /> <mvt:assign name="l.mail:headers" value="l.mail:headers $ 'Return-Path:' $ l.mail:from $ g.eol" /> <mvt:assign name="l.mail:headers" value="l.mail:headers $ 'MIME-Version: 1.0' $ g.eol" /> <mvt:assign name="l.mail:headers" value="l.mail:headers $ 'Content-Type: text/plain; charset=utf-8' $ g.eol" /> <mvt:comment> <!-- This function will send an email to the store. --> </mvt:comment> <mvt:do file="g.Module_Library_Utilities" name="g.sent" value="v9_SendEmail(l.mail)" /> <mvt:comment> <!-- This function will send a confirmation email to the visitor. If you do not wish to send a confirmation email, you can either `mvt:comment` this section out or delete it all together. --> </mvt:comment> <mvt:assign name="l.visitor_mail:from" value="asciichar(34) $ g.store:name $ asciichar(34) $ ' <' $ g.store:email $ '>'" /> <mvt:assign name="l.visitor_mail:to" value="asciichar(34) $ g.contactName $ asciichar(34) $ ' <' $ g.contactEmail $ '>'" /> <mvt:assign name="l.visitor_mail:subject" value=" $ g.store:name $ 'Wholesale Inquiry: ' $ g.contactSubject" /> <mvt:assign name="l.visitor_mail:message" value="'Dear ' $ g.contactName $ ',' $ g.eol $ g.eol $ 'Thank you for contacting ' $ g.store:name $ '; your message has been received.' $ g.eol $ g.eol $ 'Your Message:' $ g.eol $ g.contactMessage" /> <mvt:assign name="l.visitor_mail:headers" value="'Reply-To:' $ asciichar(34) $ g.store:name $ asciichar(34) $ ' <' $ g.store:email $ '>' $ g.eol" /> <mvt:do file="g.Module_Library_Utilities" name="g.visitor_sent" value="v9_SendEmail(l.visitor_mail)" /> <mvt:if expr="g.sent"> <meta http-equiv="refresh" content="0;url=&mvte:urls:GRWS:auto_sep;status=submitted" /> <mvt:else> <meta http-equiv="refresh" content="0;url=&mvte:urls:GRWS:auto_sep;status=error" /> </mvt:if> <mvt:else> <meta http-equiv="refresh" content="0;url=&mvte:urls:GRWS:auto_sep;status=error&contactName=&mvte:global:contactName;&contactEmail=&mvte:global:contactEmail;&contactPhone=&mvte:global:contactPhone;&contactSubject=&mvte:global:contactSubject;&contactMessage=&mvte:global:contactMessage;&fault=has-error" /> </mvt:if> </mvt:if>
Leave a comment:
-
Yes, you can have multiple forms on the site. The process you are following is correct. There was a discussion on this over here, you may have to scroll down a bit. https://www.miva.com/forums/forum/de...adows-template
Leave a comment:
-
Can the Contact us Form be duplicated?
We have another wholesale inquiry form that has one extra field for their phone number.
I've already made a duplicate version of the CTFM page with a code of CTFMW and URI of /wholesale-contact-form.html
Made all other Changes that I thought were needed.
Code:<mvt:assign name="g.http_referer" value="s.http_referer" /> <mvt:if expr="'CTFMW' CIN g.http_referer OR 'wholesale-contact-form' CIN g.http_referer"> <mvt:exit> </mvt:if>
Code:<mvt:assign name="l.mail:message" value="'Message from: ' $ g.contactName $ g.eol $ g.eol $ 'Email Address: ' $ g.contactEmail $ g.eol $ g.eol $ 'Phone Number: ' $ g.contactPhone $ g.eol $ g.eol $ 'Message:' $ g.eol $ g.contactMessage" />
Code:<mvt:if expr="g.sent"> <meta http-equiv="refresh" content="0;url=&mvte:urls:GRWS:auto_sep;status=submitted" /> <mvt:else> <meta http-equiv="refresh" content="0;url=&mvte:urls:GRWS:auto_sep;status=error" /> </mvt:if>
Code:<meta http-equiv="refresh" content="0;url=&mvte:urls:GRWS:auto_sep;status=error&contactName=&mvte:global:contactName;&contactEmail=&mvte:global:contactEmail;&contactPhone=&mvte:global:contactPhone;&contactSubject=&mvte:global:contactSubject;&contactMessage=&mvte:global:contactMessage;&fault=has-error" />
Code:<div class="form-row"> <label class="required" for="contactName">Your name & Business name:</label> <input id="contactName" tabindex="1" type="text" name="contactName" value="&mvte:global:contactName;" required> </div>
Code:<div class="form-row"> <label class="required" for="contactPhone">Your phone:</label> <input id="contactPhone" tabindex="3" type="text" name="contactPhone" value="&mvte:global:contactPhone;" required> </div>
Any help would be greatly appreciated.
Thanks.
Leave a comment:
-
Hi Nick,
Yes, optimizing your htaccess file is a great idea.
Leave a comment:
-
Is it okay to add Expires headers to these files on our .htaccess file once finished with the update?
ex.
<IfModule mod_expires.c>
ExpiresActive On
ExpiresByType text/css "access plus 1 year"
ExpiresByType text/javascript "access plus 1 year"
ExpiresByType image/gif "access plus 1 year"
ExpiresByType image/png "access plus 1 year"
ExpiresByType image/jpg "access plus 1 year"
ExpiresByType image/jpeg "access plus 1 year"
ExpiresByType application/pdf "access plus 1 year"
ExpiresByType image/vnd.microsoft.icon "access plus 1 year"
ExpiresByType image/x-icon "access plus 1 year"
ExpiresByType application/x-icon "access plus 1 year"
ExpiresByType application/x-font-opentype "access plus 1 year"
ExpiresByType application/x-font-woff "access plus 1 year"
ExpiresByType application/x-font-woff2 "access plus 1 year"
ExpiresByType application/x-font-ttf "access plus 1 year"
ExpiresByType application/vnd.ms-fontobject "access plus 1 year"
ExpiresByType image/svg+xml "access plus 1 year"
</IfModule>
Thought I would ask before I break something...
Thanks!
Also I was thinking it might be a good idea delete my previous questions and any related responses since they kind of dilute the scope of this thread.
Don't want to send anyone down the wrong path as well.
Didn't even end up doing what I was asking about.
Leave a comment:
-
Okay thanks for the input Matt.
I will also look into a cdn.
Any particular cdn provider you would recommend that is cost efficient and works well performance wise?
Thanks
Leave a comment:
-
Hi Nick,
You should be able to do that without a big performance hit. Another item that may help your performance would be to utilize a CDN for asset delivery.
Leave a comment:
-
Had another question in regards to performance.
I currently have custom versions of the pages.css files.
pagessfnt.min.css for SFNT
pagesctgy.min.css for CTGY, PLST, and SRCH
pagesprod.min.css for PROD
pages.min.css for everything else
I also have Custom versions of the scaffolding/typography/buttons/forms/helpers/etc. that are served for SFNT, CTGY, PLST, SRCH, and PROD.
This allowed me to get rid of a bunch of unused css on our image heavy pages. Mostly eliminated unneeded responsive scaffolding, colors, buttons, etc.
When I have time I will scale all of the original files back as well so I can just have 1 version of these files for all pages.
Anyways, question is:
Could I unassign the different pages.css from the json combined css resources I've created and then serve each version of pages.css as an additional css link?
HTML Code:<mvt:if expr="l.settings:page:code EQ 'CTGY' OR l.settings:page:code EQ 'PLST' OR l.settings:page:code EQ 'SRCH'"> <link rel="canonical" href="&mvte:category:link;" /> <mvt:item name="prodctgy_meta" param="combined" /> <mvt:item name="head" param="css_list_csp_min" /> (created a minified version instead of trying to figure out minifying on the fly) <link href="&mvte:global:theme_path;/css/pagesctgy.min.css" rel="stylesheet" /> <mvt:elseif expr="l.settings:page:code EQ 'SFNT'"> <link rel="canonical" href="https://&mvt:global:domain:name;/" /> <mvt:item name="prodctgy_meta" param="combined" /> <mvt:item name="head" param="css_list_csp_min" /> <link href="&mvte:global:theme_path;/css/pagessfnt.min.css" rel="stylesheet" /> <mvt:elseif expr="l.settings:page:code EQ 'PROD' OR l.settings:page:code EQ 'PATR'"> <link rel="canonical" href="&mvte:product:link;" /> <mvt:item name="prodctgy_meta" param="combined" /> <mvt:item name="head" param="css_list_csp_min" /> <link href="&mvte:global:theme_path;/css/pagesprod.min.css" rel="stylesheet" /> <mvt:else> <link rel="canonical" href="&mvte:urls:_self:auto;" /> <mvt:item name="prodctgy_meta" param="combined" /> <mvt:item name="head" param="css_list_min" /> (created a minified version instead of trying to figure out minifying on the fly) <link href="&mvte:global:theme_path;/css/pages.min.css" rel="stylesheet" /> </mvt:if>
I was hoping it might help since the <mvt:item name="head" param="css_list_csp_min" /> will be cached on first load.
It is an additional request but each version of the pages.min.css file is much smaller (especially with gzip compression) and can download in parallel.
My goal is to create the best scenario of balancing performance with maintainability.
Once I have the time to clean up all unused css in the files with selectors that we simply do not use I can serve the same <mvt:item name="head" param="css_list_min" /> for all pages and only dynamically serve the different pages.min.css files.
Sorry for the long winded post but hopefully someone can help confirm that my idea is valid or not.
Leave a comment:
Leave a comment: