setono/sylius-variant-link-plugin

Sylius 插件,可实现直接链接到变体

安装次数: 33,853

依赖项: 0

建议者: 0

安全性: 0

星标: 9

关注者: 2

分支: 5

公开问题: 8

类型:sylius-plugin


README

Latest Version Software License Build Status Code Coverage

在标准的 Sylius 商店中,无法直接链接到变体。本插件解决了这个问题。

屏幕截图

点击查看

Screenshot showing products list with variants links

Screenshot showing product show page with variant selected

安装

步骤 1:下载插件

打开命令行,进入项目目录并执行以下命令以下载此包的最新稳定版本

$ composer require setono/sylius-variant-link-plugin

此命令要求您全局安装 Composer,如 Composer 文档的 安装章节 中所述。

步骤 2:启用插件

然后,通过将其添加到项目中 config/bundles.php 文件中注册的插件/包列表中,启用插件

<?php

# config/bundles.php

return [
    // ...
    Setono\SyliusVariantLinkPlugin\SetonoSyliusVariantLinkPlugin::class => ['all' => true],
    // ...
];

步骤 3:导入路由

# config/routes/setono_sylius_variant_link.yaml
setono_sylius_variant_link:
    resource: "@SetonoSyliusVariantLinkPlugin/Resources/config/routes.yaml"

步骤 4:安装资产

$ php bin/console assets:install

步骤 5:覆盖产品显示模板

首先,将文件 vendor/sylius/sylius/src/Sylius/Bundle/ShopBundle/Resources/views/Product/show.html.twig 复制到 templates/bundles/SyliusShopBundle/Product/show.html.twig

以下是两个执行此操作的命令(仅在尚未覆盖此模板的情况下执行)

$ mkdir -p templates/bundles/SyliusShopBundle/Product
$ cp vendor/sylius/sylius/src/Sylius/Bundle/ShopBundle/Resources/views/Product/show.html.twig templates/bundles/SyliusShopBundle/Product

在模板中,我们需要三件事

  1. 包含一个模板
  2. 包含一个 JavaScript 文件
  3. 运行一个 JavaScript 函数

1. 包含变体链接模板

content 块中添加以下 twig 行: {% include '@SetonoSyliusVariantLinkPlugin/_variantLinks.html.twig' with {'variants': product.variants} %}

2 和 3. 包含 JavaScript 文件并运行函数

javascripts 块中追加以下内容

{% include 'SyliusUiBundle::_javascripts.html.twig' with {'path': 'bundles/setonosyliusvariantlinkplugin/js/setono-variant-links.js'} %}

<script>
    $(function() {
        $(document).variantLinks();
    });
</script>

请参阅 此文件 了解这三个更改的示例。

用法

链接到变体

{# @var \Sylius\Component\Product\Model\ProductVariantInterface variant #}

{{ setono_variant_path(variant) }} {# Works as Symfonys path() function a returns an absolute path #}
{{ setono_variant_url(variant) }} {# Works as Symfonys url() function a returns an absolute url #}

请参阅 示例

查看产品

如果您有一个具有 slug product-1 的产品,其中有一个代码为 variant-code-1 的变体,则上述 twig 语句将在默认 Sylius 安装中返回 /en_US/products/product-1/variant-code-1

所以尝试访问那个 URL,您将看到相应的变体被选中,并且价格是相应变体的正确价格。

输出变体值而不是产品值

在产品显示页面(/en_US/products/slug)中输出产品代码,但假设您想输出变体代码。那么您只需这样做

{{ (product|sylius_resolve_variant).code }}

如果您想在多个地方做这件事,您当然可以设置产品变体如下

{% set variant = product|sylius_resolve_variant %}

{{ variant.code }}

简单易懂!

扩展

我想使用比变体代码更其他的东西作为 URL

假设您有一个拥有服装的商店,您想使用服装的大小作为 URL 来确定变体。您希望得到类似 /en_US/products/product-1/medium 的 URL。

为此,您需要实现两个接口

实现 ProductVariantFromIdentifierResolverInterface

<?php
namespace App\Resolver;

use Setono\SyliusVariantLinkPlugin\Resolver\ProductVariantFromIdentifierResolverInterface;
use Sylius\Component\Core\Model\ProductInterface;
use Sylius\Component\Core\Model\ProductVariantInterface;

final class ProductVariantFromSizeResolver implements ProductVariantFromIdentifierResolverInterface
{
    public function resolve(ProductInterface $product, string $identifier) : ?ProductVariantInterface
    {
        foreach ($product->getVariants() as $variant) {
            foreach ($variant->getOptionValues() as $optionValue) {
                if(strtolower($optionValue->getValue()) === $identifier) {
                    return $variant;
                }
            }
        }
        
        return null;
    }
}

现在定义服务

<?xml version="1.0" encoding="UTF-8" ?>

<container xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="https://symfony.com.cn/schema/dic/services"
           xsi:schemaLocation="https://symfony.com.cn/schema/dic/services https://symfony.com.cn/schema/dic/services/services-1.0.xsd">
    <services>
        <service id="Setono\SyliusVariantLinkPlugin\Resolver\ProductVariantFromIdentifierResolverInterface"
                 alias="app.resolver.product_variant_from_size"/>

        <service id="app.resolver.product_variant_from_size" class="App\Resolver\ProductVariantFromSizeResolver"/>
    </services>
</container>

实现 ProductVariantUrlGeneratorInterface

<?php
namespace App\UrlGenerator;

use Setono\SyliusVariantLinkPlugin\UrlGenerator\ProductVariantUrlGeneratorInterface;
use Sylius\Component\Product\Model\ProductVariantInterface;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;

final class ProductVariantFromSizeUrlGenerator implements ProductVariantUrlGeneratorInterface
{
    /** @var UrlGeneratorInterface */
    private $urlGenerator;

    public function __construct(UrlGeneratorInterface $urlGenerator)
    {
        $this->urlGenerator = $urlGenerator;
    }
    
    public function generate(
        ProductVariantInterface $productVariant,
        array $parameters = [],
        int $referenceType = UrlGeneratorInterface::ABSOLUTE_PATH
    ) : string{
        $parameters = array_merge($parameters, [
            'slug' => $productVariant->getProduct()->getSlug(),
            'variant_identifier' => $productVariant->getOptionValues()->first()->getCode(),
        ]);

        return $this->urlGenerator->generate(
            'setono_sylius_variant_link_shop_product_variant_show', $parameters, $referenceType
        );
    }
}

现在定义服务

<?xml version="1.0" encoding="UTF-8" ?>

<container xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="https://symfony.com.cn/schema/dic/services"
           xsi:schemaLocation="https://symfony.com.cn/schema/dic/services https://symfony.com.cn/schema/dic/services/services-1.0.xsd">
    <services>
        <service id="Setono\SyliusVariantLinkPlugin\UrlGenerator\ProductVariantUrlGeneratorInterface"
                 alias="app.url_generator.product_variant_from_size"/>

        <service id="app.url_generator.product_variant_from_size" class="App\UrlGenerator\ProductVariantFromSizeUrlGenerator"/>
    </services>
</container>

注意,如果您使用自动注入,则只需要别名。