在客户端使用LiquidJS的include标签时如何解决模板找不到问题
解决客户端LiquidJS中{% include %}标签找不到模板的问题
客户端使用LiquidJS时,{% include %}标签报错RenderError: Not Found是因为客户端无法像服务器端那样直接从文件系统读取模板文件,必须手动将需要引入的模板注册到Liquid实例中。以下是两种可行的解决方法:
方法一:使用registerTemplate注册模板
直接将子模板内容注册到Liquid实例,指定include时使用的名称:
// 定义子模板内容 const summaryGroupBlock = ` <tr> <td>{{group.bookingGroupLabel}}</td> <td class="text-end">{{group.unitTotal}}</td> <td class="text-end">{{group.subtotal | price}}</td> <td class="text-end">{{group.discount | percentage}}</td> <td class="text-end">{{group.savings | price}}</td> <td class="text-end">{{group.total | price}}</td> </tr> `; // 定义主模板内容 const summaryBlock = ` <table id="bookingSummary" class="table table-striped table-bordered"> <thead> <tr> <th>Price Group</th> <th>Unit Total</th> <th>Subtotal</th> <th>Discount</th> <th>Savings</th> <th>Total</th> </tr> </thead> <tbody> {% for group in summary.summaryGroups %} {% include 'summary-group-block' %} {% endfor %} </tbody> <tfoot> <tr> <td></td> <td class="text-end">{{summary.summaryGroups | sum: "unitTotal" | default:0}}</td> <td class="text-end">{{summary.summaryGroups | sum: "subtotal" | default:0 | price}}</td> <td class="text-end">{{summary.summaryGroups | avgSkipZero: "discount" | default: 0 | percentage}}</td> <td class="text-end">{{summary.summaryGroups | sum: "savings" | default: 0 | price}}</td> <td class="text-end">{{summary.summaryGroups | sum: "total" | default: 0 | price}}</td> </tr> </tfoot> </table> `; // 初始化Liquid实例并注册模板 import { Liquid } from 'liquidjs'; const liquid = new Liquid(); liquid.registerTemplate('summary-group-block', summaryGroupBlock); // 渲染模板 async function renderTemplate() { const data = { summary: { summaryGroups: [ // 替换为你的实际数据 { bookingGroupLabel: "成人组", unitTotal: 3, subtotal: 900, discount: 0.15, savings: 135, total: 765 } ] } }; const html = await liquid.parseAndRender(summaryBlock, data); document.getElementById('target-element').innerHTML = html; } renderTemplate();
方法二:自定义Loader加载模板
通过配置loader选项,让Liquid在需要加载模板时从你定义的数据源中获取内容:
import { Liquid } from 'liquidjs'; // 定义所有模板的映射 const templates = { 'summary-group-block': ` <tr> <td>{{group.bookingGroupLabel}}</td> <td class="text-end">{{group.unitTotal}}</td> <td class="text-end">{{group.subtotal | price}}</td> <td class="text-end">{{group.discount | percentage}}</td> <td class="text-end">{{group.savings | price}}</td> <td class="text-end">{{group.total | price}}</td> </tr> `, 'summary-block': ` <table id="bookingSummary" class="table table-striped table-bordered"> <thead> <tr> <th>Price Group</th> <th>Unit Total</th> <th>Subtotal</th> <th>Discount</th> <th>Savings</th> <th>Total</th> </tr> </thead> <tbody> {% for group in summary.summaryGroups %} {% include 'summary-group-block' %} {% endfor %} </tbody> <tfoot> <tr> <td></td> <td class="text-end">{{summary.summaryGroups | sum: "unitTotal" | default:0}}</td> <td class="text-end">{{summary.summaryGroups | sum: "subtotal" | default:0 | price}}</td> <td class="text-end">{{summary.summaryGroups | avgSkipZero: "discount" | default: 0 | percentage}}</td> <td class="text-end">{{summary.summaryGroups | sum: "savings" | default: 0 | price}}</td> <td class="text-end">{{summary.summaryGroups | sum: "total" | default: 0 | price}}</td> </tr> </tfoot> </table> ` }; // 初始化带自定义loader的Liquid实例 const liquid = new Liquid({ loader: { load: async (templateName) => { if (templates[templateName]) { return templates[templateName]; } throw new Error(`模板 ${templateName} 未找到`); } } }); // 渲染主模板 async function renderTemplate() { const data = { summary: { summaryGroups: [ // 替换为你的实际数据 { bookingGroupLabel: "儿童组", unitTotal: 2, subtotal: 400, discount: 0.2, savings: 80, total: 320 } ] } }; const html = await liquid.parseAndRender(templates['summary-block'], data); document.getElementById('target-element').innerHTML = html; } renderTemplate();
核心逻辑:客户端环境没有文件系统访问能力,必须提前将所有需要的模板内容以字符串形式提供给Liquid实例,通过注册或自定义loader的方式让Liquid能根据include标签中的名称找到对应的模板内容。
内容的提问来源于stack exchange,提问作者Daniel Black
相关产品推荐
相关产品推荐

