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

Shopware 6模板间变量传递问题:快速视图中无法灰化缺货商品

问题根源

你遇到的核心问题是:商品详情页的page.unavailable变量是由商品详情页路由(ProductDetailRoute)生成并传递的,但快速视图的加载逻辑完全独立,默认不会包含这个缺货变体ID集合。你在模板里通过sw_include传递变量的尝试无效,因为父模板里的page.unavailable本身在快速视图上下文里就不存在。

解决方案

要解决这个问题,需要从后端补充快速视图的缺货数据,再在模板中适配使用,具体步骤如下:

1. 后端:给快速视图添加缺货变体ID集合

Shopware提供了专门的事件来扩展快速视图的数据,我们可以通过监听ProductQuickViewLoaderEvent来添加缺货变体的ID集合。

步骤1:创建事件订阅器

在你的自定义插件中创建一个订阅器类,用来处理快速视图的数据扩展:

<?php

namespace YourPluginNamespace\Subscriber;

use Shopware\Core\Content\Product\SalesChannel\QuickView\ProductQuickViewLoaderEvent;
use Shopware\Core\System\SalesChannel\SalesChannelContext;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;

class ProductQuickViewUnavailableSubscriber implements EventSubscriberInterface
{
    public static function getSubscribedEvents(): array
    {
        return [
            ProductQuickViewLoaderEvent::class => 'addUnavailableVariantsToQuickView',
        ];
    }

    public function addUnavailableVariantsToQuickView(ProductQuickViewLoaderEvent $event): void
    {
        $product = $event->getProduct();
        $salesChannelContext = $event->getSalesChannelContext();
        $page = $event->getResult();

        // 生成缺货变体ID集合(逻辑和详情页保持一致)
        $unavailableVariantIds = $this->collectUnavailableVariantIds($product, $salesChannelContext);

        // 将数据添加到page对象,让模板可以访问
        $page->setExtension('unavailable', $unavailableVariantIds);
    }

    private function collectUnavailableVariantIds($product, SalesChannelContext $context): array
    {
        $unavailableIds = [];

        // 仅处理有变体的父商品
        if (!$product->getChildren() || !$product->getParentId()) {
            return $unavailableIds;
        }

        foreach ($product->getChildren() as $variant) {
            // 根据Shopware的库存规则判断是否缺货
            $stock = $variant->getStock();
            $allowOutOfStock = $variant->getAllowOutOfStock();
            $isActive = $variant->isActive();

            // 变体未激活 或 库存为0且不允许缺货购买,视为不可用
            if (!$isActive || ($stock <= 0 && !$allowOutOfStock)) {
                $unavailableIds[] = $variant->getId();
            }
        }

        return $unavailableIds;
    }
}

步骤2:注册订阅器

在插件的services.xml(或services.yaml)中注册这个订阅器:

<service id="YourPluginNamespace\Subscriber\ProductQuickViewUnavailableSubscriber">
    <tag name="kernel.event_subscriber"/>
</service>

2. 模板:适配快速视图的变量

现在快速视图的page对象已经有了page.extensions.unavailable数据,需要修改configurator.html.twig中的判断逻辑,同时兼容详情页和快速视图的上下文:

{# 先统一获取缺货ID集合,兼容详情页和快速视图 #}
{% set unavailableVariantIds = page.unavailable ?? page.extensions.unavailable ?? [] %}

<div class="product-detail-configurator-option {% if option.id in unavailableVariantIds %}grau-labels{% endif %}">
{% block page_product_detail_configurator_option_radio %}
<input type="radio" name="{{ group.id }}" value="{{ option.id }}" class="product-detail-configurator-option-input{% if isCombinableCls %} {{ isCombinableCls }}{% endif %}" title="{{ optionIdentifier }}" id="{{ optionIdentifier }}" {% if isActive %} checked="checked" {% endif %}>
</div>
{% endblock %}

3. 移除无效的变量传递

现在不需要在sw_include中手动传递notinhere变量了,因为我们已经通过后端统一了数据来源,可以删除之前添加的with {notinhere : page.unavailable}代码。

为什么之前的尝试无效?

你之前在模板中传递变量的思路没问题,但前提是父模板里的page.unavailable必须存在。而快速视图的加载逻辑默认不会生成这个变量,所以传递的是null,自然无法触发置灰效果。只有通过后端扩展快速视图的数据,才能从根源解决问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.28 12:38:13