Search code examples
twigshopware6

Get subcategories with twig on listing page


I'm trying to get the subcategories on a listing page in Shopware 6. However i can't seem to find the functionality to get an array with the subcategories with the template variables.

My goal is to loop over the children and make some kind of fastlinks in a CMS-element.

Is there a standard functionality build in shopware to get the children by id or name in TWIG?

I've tried to find anything relevant in

page.header.navigation.active

But the child data isn't available.

Thanks!


Solution

  • I don't think there is a build-in function to fetch this, but if you're doing it in a new CMS-Element you can take advantage of it by adding a new DataResolver for your new element and pass the subcategories to your CMS-element.

    // myPlugin/src/DataResolver/SubcategoryListCmsElementResolver.php
    <?php
    
    namespace MyPlugin\DataResolver;
    
    use Shopware\Core\Content\Category\CategoryDefinition;
    use Shopware\Core\Content\Category\CategoryEntity;
    use Shopware\Core\Content\Cms\Aggregate\CmsSlot\CmsSlotEntity;
    use Shopware\Core\Content\Cms\DataResolver\CriteriaCollection;
    use Shopware\Core\Content\Cms\DataResolver\Element\AbstractCmsElementResolver;
    use Shopware\Core\Content\Cms\DataResolver\Element\ElementDataCollection;
    use Shopware\Core\Content\Cms\DataResolver\ResolverContext\ResolverContext;
    use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
    use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsFilter;
    
    class SubcategoryListCmsElementResolver extends AbstractCmsElementResolver
    {
    
        public function getType(): string
        {
            return 'my-subcategory-list';
        }
    
        public function collect(CmsSlotEntity $slot, ResolverContext $resolverContext): ?CriteriaCollection
        {
            /** @var CategoryEntity $categoryEntity */
            $categoryEntity = $resolverContext->getEntity();
            $criteria = new Criteria([$categoryEntity->getId()]);
            $criteria->addAssociation('children');
    
            $criteriaCollection = new CriteriaCollection();
            $criteriaCollection->add('category_' . $slot->getUniqueIdentifier(), CategoryDefinition::class, $criteria);
            return $criteriaCollection;
        }
    
        public function enrich(CmsSlotEntity $slot, ResolverContext $resolverContext, ElementDataCollection $result): void
        {
            /** @var CategoryEntity $categoryEntity */
            $categoryEntity = $result->get('category_' . $slot->getUniqueIdentifier())?->getEntities()->first();
            $slot->setData($categoryEntity->getChildren()?->sortByPosition()->filter(static function ($child) {
                /** @var CategoryEntity $child */
                return $child->getActive();
            }));
        }
    }
    

    services.xml

    <service id="MyPlugin\DataResolver\SubcategoryListCmsElementResolver">
        <tag name="shopware.cms.data_resolver"/>
    </service>
    

    You then provide a new template, e.g.

    {% block element_my_subcategory_list %}
        {% set subcategories = element.data.elements %}
        {% set activeCategory = page.header.navigation.active %}
        
        <ul>
            {% for category in subcategories %}
                <li>do something with your category</li>
            {% endfor %}
        </ul>
    {% endblock %}
    
    

    You can read more about data resolvers here in the docs: https://developer.shopware.com/docs/guides/plugins/plugins/content/cms/add-data-to-cms-elements#create-a-data-resolver