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

Shopware 6技术咨询:如何在自定义插件中添加并渲染产品/产品列表

Shopware 6 自定义插件传递并渲染产品/产品列表步骤

1. 通过服务层封装产品数据获取逻辑

Shopware 6 内置了产品仓库接口,我们可以通过依赖注入来复用它,先在插件的 src/Resources/config/services.xml 中定义服务:

<service id="YourPluginName\Service\ProductService">
    <argument type="service" id="product.repository"/>
</service>

然后创建对应的服务类 src/Service/ProductService.php,封装单个产品和列表的获取方法:

<?php
namespace YourPluginName\Service;

use Shopware\Core\Content\Product\ProductRepositoryInterface;
use Shopware\Core\Framework\Context;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsFilter;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Sorting\FieldSorting;

class ProductService
{
    private ProductRepositoryInterface $productRepository;

    public function __construct(ProductRepositoryInterface $productRepository)
    {
        $this->productRepository = $productRepository;
    }

    // 获取单个产品(支持关联价格、媒体等字段)
    public function getSingleProduct(string $productId, Context $context)
    {
        $criteria = new Criteria([$productId]);
        $criteria->addAssociation('price');
        $criteria->addAssociation('media');
        
        return $this->productRepository->search($criteria, $context)->first();
    }

    // 获取上架产品列表(可自定义数量、排序、过滤条件)
    public function getProductList(Context $context, int $limit = 10)
    {
        $criteria = new Criteria();
        $criteria->setLimit($limit);
        $criteria->addFilter(new EqualsFilter('active', true));
        $criteria->addSorting(new FieldSorting('createdAt', 'DESC'));
        
        return $this->productRepository->search($criteria, $context)->getEntities();
    }
}

2. 控制器中传递数据到模板

创建自定义控制器 src/Controller/CustomProductController.php,注入上面的服务并定义路由,将产品数据传递给模板:

<?php
namespace YourPluginName\Controller;

use YourPluginName\Service\ProductService;
use Shopware\Core\Framework\Context;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;

#[Route(defaults: ['_routeScope' => ['storefront']])]
class CustomProductController extends AbstractController
{
    private ProductService $productService;

    public function __construct(ProductService $productService)
    {
        $this->productService = $productService;
    }

    // 单个产品页面路由
    #[Route(path: '/custom-product/{productId}', name: 'frontend.custom.single.product', methods: ['GET'])]
    public function singleProduct(string $productId, Context $context): Response
    {
        $product = $this->productService->getSingleProduct($productId, $context);
        
        return $this->render('@YourPluginName/storefront/page/custom-product/single.html.twig', [
            'product' => $product
        ]);
    }

    // 产品列表页面路由
    #[Route(path: '/custom-products', name: 'frontend.custom.product.list', methods: ['GET'])]
    public function productList(Context $context): Response
    {
        $products = $this->productService->getProductList($context);
        
        return $this->render('@YourPluginName/storefront/page/custom-product/list.html.twig', [
            'products' => $products
        ]);
    }
}

3. Twig模板渲染数据

单个产品模板 src/Resources/views/storefront/page/custom-product/single.html.twig

{% extends '@Storefront/storefront/base.html.twig' %}

{% block page_content %}
    <div class="custom-product-container">
        {% if product %}
            <h2 class="product-title">{{ product.translated.name }}</h2>
            <div class="product-description">{{ product.translated.description|raw }}</div>
            <div class="product-price">
                {{ product.price.first.gross|currency(product.price.first.currencyId) }}
            </div>
            {% if product.media.first %}
                <img 
                    src="{{ product.media.first.url }}" 
                    alt="{{ product.media.first.translated.alt ?: product.translated.name }}"
                    class="product-image"
                >
            {% endif %}
        {% else %}
            <div class="alert alert-warning">该产品不存在或已下架</div>
        {% endif %}
    </div>
{% endblock %}

产品列表模板 src/Resources/views/storefront/page/custom-product/list.html.twig

{% extends '@Storefront/storefront/base.html.twig' %}

{% block page_content %}
    <div class="custom-product-list">
        <h2 class="list-title">自定义产品列表</h2>
        <div class="row">
            {% for product in products %}
                <div class="col-md-4 col-sm-6 mb-4">
                    <div class="product-card">
                        {% if product.media.first %}
                            <img 
                                src="{{ product.media.first.url }}" 
                                alt="{{ product.media.first.translated.alt ?: product.translated.name }}"
                                class="card-img-top"
                            >
                        {% endif %}
                        <div class="card-body">
                            <h5 class="card-title">{{ product.translated.name }}</h5>
                            <p class="card-text">{{ product.translated.description|slice(0, 120) }}...</p>
                            <div class="card-price">
                                {{ product.price.first.gross|currency(product.price.first.currencyId) }}
                            </div>
                            <a 
                                href="{{ path('frontend.detail.page', { productId: product.id }) }}" 
                                class="btn btn-primary"
                            >
                                查看详情
                            </a>
                        </div>
                    </div>
                </div>
            {% else %}
                <div class="col-12">
                    <div class="alert alert-info">暂无上架产品</div>
                </div>
            {% endfor %}
        </div>
    </div>
{% endblock %}

4. 验证测试

  1. 清除Shopware缓存:在项目根目录执行 bin/console cache:clear
  2. 激活插件(若未激活):bin/console plugin:refresh → bin/console plugin:activate YourPluginName
  3. 访问单个产品页面:替换实际产品ID后访问 https://你的店铺域名/custom-product/xxxxxx
  4. 访问产品列表页面:https://你的店铺域名/custom-products

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 13:30:28