Sylius: Expand product group model including API

Development, Technology

Oliver Burkhalter

October 10, 2022

Sylius: Expand product group model including API

The eCommerce software solution “Sylius” Can - thanks to its good basic structure - be expanded in a simple way.

In this blog we look at how to Product group or Product category adds an additional field.

The following instructions were with Sylius 1.10.x tested.

The use case and the starting point

The product group would like to describe the product group on a shop website.In Sylius there is already this “description” field as standard, but you want to design the product group with an additional teaser text “Peppiger”.This means that the teaser text should first appear with a highlighted style and then the closer description with a simpler style.In addition, this teaser text in the Sylius Admin-UI, along with the description, should be managed by the admin.

The shop website is also structured in such a way that a separate front end generates the views for the end user using Sylius’ shop data.The new one will Sylius APIv2 set.

In order to be able to display this teaser text data in the frontend, the respective Sylius must also API Model Serialization Configuration can be expanded.

Overview of the necessary steps

In order to be able to implement this use case, the following steps are necessary:

  1. Expand the corresponding model for the translation (taxon translation) including migration database

  2. Expand the product group model (taxon)

  3. Extend the corresponding form in the admin UI (form type extension)

  4. Add the necessary translation texts

  5. Add the corresponding API model serialization configuration

Let us take a closer look at these steps.

Expand the corresponding model for the translation (taxon translation) including migration database

This section is based on the official documentation here: Link

Since this teaser text field should be translatable, the translation model of the product group, i.e. Taxon, be expanded.

With a Sylius standard installation, this model has already been created here: src/Entity/Taxonomy/TaxonTranslation.php

This model is expanded to include the new teaser text field, we use the same Orm Column Type Text as for the field“ Description ”(to be found in the DB, for example):

/**
 * @ORM\Entity
 * @ORM\Table(name="sylius_taxon_translation")
 */
class TaxonTranslation extends BaseTaxonTranslation
{
    /** @ORM\Column(type="text", nullable=true) */
    private string $teaserText;

    public function getTeaserText(): ?string
    {
        return $this->teaserText;
    }

    public function setTeaserText(?string $teaserText): void
    {
        $this->teaserText = $teaserText;
    }
}

The database scheme must then be updated with this new field.

It is recommended via Doctrine Migrations to do so that these scripts may be in a car.Deployment pipeline can insert To roll out DB migration automatically.

Such a DB migration script generates the following command:

$> php bin/console doctrine:migrations:diff

This SQL script can then be found in the directory as standard src/Migrations.

With the following command, the migration can then be effectively executed:

$> php bin/console doctrine:migrations:migrate

Expand the product group model (taxon)

This section is based on the official documentation to find here: Link.

Next, you expand the taxon model so that you can also access this “teaser text” field.

The function createTranslation It is important because this is used in the background of Sylius to instance an object for the translation model. That will be over that TranslatableTrait Are defined.

/**
 * @ORM\Entity
 * @ORM\Table(name="sylius_taxon")
 */
class Taxon extends BaseTaxon
{
    ... some code before...

    public function getTeaserText(): ?string
    {
        /** @var TaxonTranslation $translation  */
        $translation = $this->getTranslation();
        return $translation->getTeaserText();
    }

    public function setTeaserText(?string $teaserText): void
    {
        /** @var TaxonTranslation $translation  */
        $translation = $this->getTranslation();
        $translation->setTeaserText($teaserText);
    }

    protected function createTranslation(): TaxonTranslationInterface
    {
        return new TaxonTranslation();
    }
    ...
}

Expand the corresponding form in the admin UI (form type extension)

So that the new “teaser text” field can also be filled with data by the admin user, You still need an expansion of the taxon form in the admin area.

For this there is a so -called Form Type Extension created.See the official documentation here: Link.

In our case for the expansion of the taxon model, we expand the existing Sylius Form Type TaxonTranslationType.

We call our form type extension CustomTaxonTranslationTypeExtension and add the “teaser text” field:

namespace App\Form\Extension;

use Sylius\Bundle\TaxonomyBundle\Form\Type\TaxonTranslationType;
use Symfony\Component\Form\AbstractTypeExtension;
use Symfony\Component\Form\Extension\Core\Type\TextareaType;
use Symfony\Component\Form\FormBuilderInterface;

final class CustomTaxonTranslationTypeExtension extends AbstractTypeExtension
{
    public function buildForm(
        FormBuilderInterface $builder,
        array $options
    ): void {
        $builder
            ->add('teaserText', TextareaType::class, [
                'required' => false,
                'label' => 'sylius.form.taxon.teaser.text',
            ]);
    }

    public static function getExtendedTypes(): iterable
    {
        return [TaxonTranslationType::class];
    }
}

Add the necessary translation texts

We still need corresponding translation texts for the admin UI. As to see the type extension above, we need the value as a label sylius.form.taxon.teaser.text.

We still add this value in our translation files translations/messages.* in addition.

Add the corresponding API model serialization configuration

So, with the above steps we are already finished and the admin user can already fill and use the new “Teaser Text” field.

But since our shop website has its own frontend and we Sylius im “Headless” Using fashion, we would like to expand the API accordingly so that this “teaser text” field is also released as API response.

Sylius sets “API Platform” as API framework.This enables us to have a simple and clean extension of the API in Sylius.

We write a new one for this API Serialization Konfiguration for the corresponding model.

This step can also be found in the official documentation here: Link.

In our case we add the following file: config/serialization/TaxonTranslation.xml with the following content:

<?xml version="1.0" ?>
<serializer xmlns="http://symfony.com/schema/dic/serializer-mapping"
            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            xsi:schemaLocation="http://symfony.com/schema/dic/serializer-mapping https://symfony.com/schema/dic/serializer-mapping/serializer-mapping-1.0.xsd"
>
    <class name="Sylius\Component\Taxonomy\Model\TaxonTranslation">
        <attribute name="teaserText">
            <group>admin:taxon:read</group>
            <group>shop:taxon:read</group>
            <group>admin:taxon_translation:read</group>
            <group>shop:taxon_translation:read</group>
        </attribute>
    </class>
</serializer>

Only the new “teaser text” field for the corresponding Serialization Groups, which Sylius has defined internally.

Done ✅

With the above steps we have Sylius’s Taxon-Modell to expand an additional field (teaser text) and can make this in the admin UI.

We also have that API Serialization Configuration expanded so that you can also use the Sylius APIv2 can call up the new field.

Pic Credit: Sylius

Another reading material