如何通过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注入到全局模板上下文中:
- 创建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]); } }
- 注册为Twig运行时服务:
# config/services.yaml services: App\Context\CartContextProvider: arguments: - '@sylius.repository.order' - '@security.helper' tags: - { name: twig.runtime }
- 在模板中直接调用:
{# @App/Layout/Header/_search.html.twig #} {{ cartContextProvider.getCart().itemsTotal }}
也可以进一步封装成Twig函数,让调用更便捷。
方法二:在UI事件配置中通过服务获取Cart
在sylius_ui的事件配置里,直接调用Sylius自带服务获取Cart并传入上下文:
- 修改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()方法,将返回的购物车对象直接传入模板上下文。
- 在模板中直接使用变量:
{# @App/Layout/Header/_search.html.twig #} {{ cart.itemsTotal }}
注:sylius.context.cart服务已内置处理匿名用户与登录用户的购物车逻辑,无需重复开发。
内容的提问来源于stack exchange,提问作者gitrequests
相关产品推荐
相关产品推荐

