How to Add New Properties to a Category

The Akeneo PIM allows the classification of products inside a customizable category tree.

Note

To implement this task you have to be comfortable with Symfony bundle overriding and Symfony services

Add Properties to your own Category

The first step is to create a class that extends PIM Category class.

Note

Class inheritance is implemented with a Doctrine discriminator map. Please be sure not to use Category as the name of your class so as to avoid unexpected problems.

For example, we can add a description property with a text field.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# /src/Acme/Bundle/CatalogBundle/Entity/MyCategory.php
<?php

namespace Acme\Bundle\CatalogBundle\Entity;

use Pim\Bundle\CatalogBundle\Entity\Category;

class MyCategory extends Category
{
    protected $description;

    public function getDescription()
    {
        return $this->description;
    }

    public function setDescription($description)
    {
        $this->description = $description;

        return $this;
    }
}
1
2
3
4
5
6
7
8
# /src/Acme/Bundle/CatalogBundle/Resources/config/doctrine/MyCategory.orm.yml
Acme\Bundle\CatalogBundle\Entity\MyCategory:
    type: entity
    repositoryClass: Pim\Bundle\CatalogBundle\Entity\Repository\CategoryRepository
    fields:
        description:
            type: string
            length: 255

Define the Category Class

You need to update your category entity parameter used in entities.yml file:

1
2
3
# /src/Acme/Bundle/CatalogBundle/Resources/config/entities.yml
parameters:
    pim_catalog.entity.category.class:      Acme\Bundle\CatalogBundle\Entity\MyCategory

Note

You don’t have to add a lot of code to resolve target entities doctrine configuration. We already have a resolve which inject the new value for your category.

The same procedure can be applied to redefine the product and product value entities.

Define the Category Form

Firstly you will have to create your custom type by inheriting the CategoryType class and then add your custom fields:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
# /src/Acme/Bundle/EnrichBundle/Form/Type/CategoryType.php
<?php

namespace Acme\Bundle\EnrichBundle\Form\Type;

use Symfony\Component\Form\FormBuilderInterface;

use Pim\Bundle\EnrichBundle\Form\Type\CategoryType as BaseCategoryType;

/**
 * Type for category properties
 */
class CategoryType extends BaseCategoryType
{
    /**
     * {@inheritdoc}
     */
    public function buildForm(FormBuilderInterface $builder, array $options)
    {

        $builder->add('description', 'text',
            [
                'required' => true
            ]
        );
        parent::buildForm($builder, $options);
    }
}

Then you have to override the service definition of your form:

1
2
3
# /src/Acme/Bundle/EnrichBundle/Resources/config/form_types.yml
parameters:
    pim_enrich.form.type.category.class: Acme\Bundle\EnrichBundle\Form\Type\CategoryType

Note

Don’t forget to add this new file in your dependency injection extension

Then don’t forget to add your new field in twig template:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
# /src/Acme/Bundle/EnrichBundle/Resources/views/CategoryTree/_tab-panes.html.twig
<div class="tab-pane active" id="properties">
    {% set generalProperties %}
        {{ form_row(form.code) }}
        {{ form_row(form.description) }}
    {% endset %}

    {% set nodeValues %}
        {{ form_row(form.label) }}
    {% endset %}

    {{ elements.accordion({ 'pane.accordion.general_properties': generalProperties, 'pane.accordion.node_values': nodeValues }) }}

</div>

{% if form.vars.value.id %}
    <div class="tab-pane" id="history">
        {% import 'PimDataGridBundle::macros.html.twig' as dataGrid %}
        {{ dataGrid.renderHistoryGrid(form.vars.value) }}
    </div>
{% endif %}

For the form validation you will have to add a new validation file:

1
2
3
4
5
# /src/Acme/Bundle/CatalogBundle/Resources/config/validation.yml
Acme\CatalogBundle\Entity\MyCategory:
    properties:
        description:
            - NotBlank: ~