Node.js+Express中SendGrid邮件模板Handlebars {{#each}}遍历失效问题
解决SendGrid中Handlebars {{#each}}遍历失效的问题
我一眼就看出问题所在了——你现在把ES6模板字符串的变量替换和SendGrid的Handlebars模板语法混在一起用,但没有把order_items作为模板数据传递给SendGrid,所以SendGrid根本不知道这个变量存在,遍历自然就不生效。
下面是具体的修复步骤:
1. 集中整理所有模板需要的动态数据
先把邮件里要用到的所有动态值(订单信息、订单项、订单号)集中到一个对象里,确保SendGrid能拿到所有渲染需要的数据:
// 假设addedOrder是你生成的订单号 const templateData = { addedOrder: addedOrder, order: req.body, // 直接传入整个订单对象,方便Handlebars调用属性 order_items: req.body.order_items };
2. 重构HTML模板,纯用Handlebars语法
把原来HTML里的ES6模板字符串${}全部替换成Handlebars的{{}},同时去掉不必要的HTML标签转义,直接写正常的HTML结构:
const msg = { to: [req.body.customer_email], bcc: 'test@test.com', from: 'test@test.com', subject: `Test`, // 用纯Handlebars语法编写模板,不再混合ES6模板字符串 html: ` <head> <title></title> </head> <body> <div data-role="module-unsubscribe" class="module" role="module" data-type="unsubscribe" style="color:#444444; font-size:12px; line-height:20px; padding:16px 16px 16px 16px; text-align:left;" data-muid="4e838cf3-9892-4a6d-94d6-170e474d21e5"> <p>This is a confirmation that your order has been processed. You will receive a delivery time within the next 24 hours. Thanks for being a valued customer. Please see order below. If any part of this order is incorrect please reach out to us at test@mail.com</p> <h3 style="margin-top:4rem;">Order #{{addedOrder}}</h3> <p style="font-size:12px; line-height:20px;"> Name on order: {{order.customer_first_name}} {{order.customer_last_name}}</p> <p style="text-transform:capitalize">Address: {{order.customer_address}} {{order.customer_city}} {{order.customer_state}}, {{order.customer_zip}}</p> <p>Phone Number: {{order.customer_phone}}</p> <p>Order Status: {{order.status}}</p> {{#each order_items}} <div> <img style="width:100%;" src="{{this.image_url}}"/> </div> <p style="font-size:1.3rem">{{this.title}}</p> <p style="font-size:1.5rem">${{this.price}}</p> <p>Total: ${{this.price * this.quantity}}</p> {{/each}} </div> </body> `, // 关键!把整理好的模板数据传给SendGrid,让它处理渲染 dynamicTemplateData: templateData };
3. 发送逻辑保持不变
最后发送邮件的代码无需修改,SendGrid会自动用dynamicTemplateData里的数据解析HTML中的Handlebars语法:
sgMail.send(msg) .then(() => { console.log('Message sent') }) .catch((error) => { console.log(error.response.body) console.log(error.response.body.errors[0].message) });
为什么原来的写法不行?
你之前的代码里,${addedOrder}这类是Node在发送邮件前就替换成了具体值,但{{#each order_items}}是SendGrid的Handlebars语法,而你根本没把order_items传给SendGrid——SendGrid解析模板时找不到这个变量,遍历自然就不生效了。把所有动态数据统一放到dynamicTemplateData里,让SendGrid来处理所有模板渲染,就能解决这个问题。
内容的提问来源于stack exchange,提问作者cosmicChocolate
相关产品推荐
相关产品推荐

