You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过Sylius模板事件将Cart传递至Twig模板?

问题

默认的Context Provider未提供Cart对象,仅包含channelContext、currencyContext、localeContext和customerContext。请问能否通过Sylius模板事件在Twig模板中直接获取Cart?

比如我想通过如下配置传递Cart到模板上下文:

sylius_ui:
    events:
        sylius.shop.layout.header.content:
            blocks:
                search:
                    enabled: true
                    template: "@App/Layout/Header/_search.html.twig"
                    priority: 10
                    context:
                        cart: how_to_pass_cart? # <-- 这里如何传入Cart

之后在模板中直接使用:

{# @App/Layout/Header/_search.html.twig #}
{{ cart.itemsTotal }}

目前Sylius标准模板中,是通过渲染订单控制器的方式显示购物车:

<div class="right aligned column">
    {{ render(url('sylius_shop_partial_cart_summary', {'template': '@SyliusShop/Cart/_widget.html.twig'})) }}
</div>

我认为这种方案不够理想,想知道是否可以通过上下文参数或自定义Context Provider在Twig模板中直接获取Cart?

解决方案

当然可以,有两种常用方式实现:

方法一:自定义Context Provider

创建一个自定义的Context Provider,将Cart注入到全局模板上下文中:

  1. 创建Provider类:
<?php

namespace App\Context;

use Sylius\Component\Core\Model\OrderInterface;
use Sylius\Component\Core\Repository\OrderRepositoryInterface;
use Sylius\Component\User\Model\UserInterface;
use Symfony\Component\Security\Core\Security;
use Twig\Extension\RuntimeExtensionInterface;

class CartContextProvider implements RuntimeExtensionInterface
{
    public function __construct(
        private readonly OrderRepositoryInterface $orderRepository,
        private readonly Security $security
    ) {}

    public function getCart(): ?OrderInterface
    {
        $user = $this->security->getUser();
        
        if (!$user instanceof UserInterface) {
            // 处理匿名用户的购物车,从session获取
            $sessionCartId = $this->security->getToken()?->getAttribute('cart_id');
            return $sessionCartId ? $this->orderRepository->find($sessionCartId) : null;
        }

        return $this->orderRepository->findOneBy(['customer' => $user->getCustomer(), 'state' => OrderInterface::STATE_CART]);
    }
}
  1. 注册为Twig运行时服务:
# config/services.yaml
services:
    App\Context\CartContextProvider:
        arguments:
            - '@sylius.repository.order'
            - '@security.helper'
        tags:
            - { name: twig.runtime }
  1. 在模板中直接调用:
{# @App/Layout/Header/_search.html.twig #}
{{ cartContextProvider.getCart().itemsTotal }}

也可以进一步封装成Twig函数,让调用更便捷。

方法二:在UI事件配置中通过服务获取Cart

在sylius_ui的事件配置里,直接调用Sylius自带服务获取Cart并传入上下文:

  1. 修改UI事件配置:
sylius_ui:
    events:
        sylius.shop.layout.header.content:
            blocks:
                search:
                    enabled: true
                    template: "@App/Layout/Header/_search.html.twig"
                    priority: 10
                    context:
                        cart: "@=service('sylius.context.cart').getCart()"

这里使用Symfony表达式语言,通过@=service('...')调用Sylius内置的sylius.context.cart服务的getCart()方法,将返回的购物车对象直接传入模板上下文。

  1. 在模板中直接使用变量:
{# @App/Layout/Header/_search.html.twig #}
{{ cart.itemsTotal }}

注:sylius.context.cart服务已内置处理匿名用户与登录用户的购物车逻辑,无需重复开发。

内容的提问来源于stack exchange,提问作者gitrequests

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 00:34:58