使用kalimatas/php-liquid库时自定义Liquid标签无法正常工作
解决kalimatas/php-liquid实现Shopify专属Liquid标签的错误
问题1:Unknown tag 'liquid'
你的代码里先实例化Template,再注册自定义标签,这会导致已创建的Template实例无法识别后续注册的标签。必须在创建Template对象前完成标签注册。
另外,Shopify的{% liquid %}标签是用来包裹多行Liquid代码的块级标签,你当前的LiquidTag实现只是返回原始markup,没有执行内部的Liquid逻辑,完全不符合预期。
修正后的代码实现:
// LiquidRenderer.php class LiquidRenderer { private $template; public function __construct($templatePath) { // 先注册所有自定义标签,再实例化Template Template::registerTag('liquid', LiquidTag::class); Template::registerTag('section', SectionTag::class); Template::registerTag('javascript', JavascriptTag::class); $this->template = new Template(); // 设置模板路径(用于加载外部section等模板文件) $this->template->setTemplatePath($templatePath); } // 补充渲染方法示例 public function render($data) { return $this->template->parseAndRender($data); } }
class LiquidTag extends \Liquid\Tag { public function render($context) { // 解析并执行{% liquid %}内部的Liquid代码 $subTemplate = new \Liquid\Template(); // 继承当前上下文的标签与过滤器 $subTemplate->tags = $this->template->tags; $subTemplate->filters = $this->template->filters; return $subTemplate->parseAndRender($this->markup, $context); } }
问题2:Cannot parse 'section' tag arguments
Shopify的{% section 'header' %}语法需要自定义标签正确解析引号包裹的参数,默认Tag基类的参数解析逻辑不匹配该格式,需要重写parse方法提取section名称。
实现SectionTag:
class SectionTag extends \Liquid\Tag { private $sectionName; public function parse(\Liquid\TokenStream $tokens) { // 提取参数:匹配单引号或双引号包裹的内容 $argument = $tokens->shift()->getTrimmedValue(); preg_match('/[\'\"](.*?)[\'\"]/', $argument, $matches); if (isset($matches[1])) { $this->sectionName = $matches[1]; } else { throw new \Liquid\LiquidException("Invalid section tag syntax. Use {% section 'section-name' %}"); } // 处理块结束标签(若section无需内容块,可直接跳过) $tokens->expectTag('endsection'); $tokens->shift(); } public function render($context) { // 根据section名称加载对应模板文件(示例路径:sections/header.liquid) $sectionPath = $this->template->getTemplatePath() . '/sections/' . $this->sectionName . '.liquid'; if (!file_exists($sectionPath)) { return "<!-- Section '{$this->sectionName}' not found -->"; } $sectionContent = file_get_contents($sectionPath); $subTemplate = new \Liquid\Template(); $subTemplate->tags = $this->template->tags; $subTemplate->filters = $this->template->filters; return $subTemplate->parseAndRender($sectionContent, $context); } }
验证测试
使用你的测试模板:
{% liquid assign product_title = product.title echo product_title %} {% section 'header' %}
调用渲染示例:
$renderer = new LiquidRenderer(__DIR__ . '/templates'); echo $renderer->render(['product' => ['title' => 'Test Product']]);
这样就能正确识别liquid标签并执行内部代码,同时正确解析section标签的参数并加载对应模板。
内容的提问来源于stack exchange,提问作者inanc eroglu
相关产品推荐
相关产品推荐

