Inaktive Menüs via Twig listen

Hallo,

wir haben Tausende von Kategorien. Davon haben wir nur die obersten Ebenen auf sichtbar („In der Navigation ausblenden“ deaktiviert) gesetzt, weil sonst das Menü total unübersichtlich wäre.

Jetzt wollen wir den Kunden natürlich auf den einzelnen Kategorie-Seiten schon die entsprechenden Unterkategorien dieser einen Seite anzeigen, auch wenn sie auf „In der Navigation ausblenden“ (nicht sichtbar/visible) eingestellt sind.

Beispiel:

  • Essen
    • Obst
      • rotes Obst („In der Navigation ausblenden“)
      • grünes Obst („In der Navigation ausblenden“)
      • gelbes Obst („In der Navigation ausblenden“)
    • Gemüse

Im Menü will ich nur Essen, Obst und Gemüse anzeigen.
Wenn jemand auf Obst klickt, will ich aber auf der Seite im Content-Bereich die Unterkategorien rotes, grünes und gelbes Obst anzeigen. Ich müsste hier also nur die Unterkategorien von Obst laden, nicht die von Gemüse.

Habe ich eine Chance, an diese inaktiven Unter-Kategorien im Twig ranzukommen?

In /views/storefront/layout/sidebar/category-navigation.html.twig ist nur die Variable navigationTree verfügbar, aber da sind nur die sichtbaren Kategorien vorhanden. Und das ist auch der gesamte Tree beginnend von der root-Ebene.

Auch in der page-Variable habe ich nur die sichtbaren Kategorien gefunden. Gibt es da sowas wie eine ChildrenCategories Variable?

Bin für jeden Tipp dankbar!

Alternativ müsste ich wohl alle Kategorien auf sichtbar setzen und dann im Twig filtern. Aber das geht vermutlich auf die Performance, wenn immer alle Kategorien geladen werden.

Oder wie könnte ich das sonst lösen?

Viele Grüße

Du könntest evtl. eine benutzerdefinierte Methode in deinem CategoryRepository erstellen, die die inaktiven Unterkategorien abruft. Nachdem du die benutzerdefinierte Methode erstellt hast, kannst du sie im Twig-Template verwenden, um die inaktiven Unterkategorien abzurufen. Natürlich musst du aber auch sicherstellen, dass dein CategoryRepository im Twig-Template verfügbar ist. Das kann je nach deiner Shopware-Konfiguration unterschiedlich sein…

Hallo Murmeltier,

vielen Dank für Deine Antwort.

Bisher habe ich nur mit Twig gearbeitet und nicht mit dem PHP-Code selbst.
Aber Deiner Antwort entnehme ich, dass es so eine Funktion, die die Children der aktuellen Kategorie in Twig zur Verfügung stellt, wohl nicht out-of-the-box gibt. :frowning:

Hast Du für mich evtl. einen Einstiegspunkt in der Doku, wie ich eine „benutzerdefinierte Methode“ in meinem „CategoryRepository“ erstelle? Oder Beispiel-Code? Muss ich dazu ein Plugin erstellen?

Vielen Dank :slight_smile:

Ich bin leider noch nicht all zu fit mit SW6, von daher kann ich momentan auch nur vermuten… :wink:

// src/Repository/CategoryRepository.php

namespace App\Repository;

use Doctrine\ORM\EntityManagerInterface;
use Shopware\Core\Content\Category\CategoryCollection;
use Shopware\Core\Content\Category\CategoryEntity;
use Shopware\Core\Framework\DataAbstractionLayer\EntityRepositoryInterface;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsFilter;

class CategoryRepository extends EntityRepositoryInterface
{
    public function __construct(EntityManagerInterface $entityManager)
    {
        parent::__construct($entityManager, $entityManager->getClassMetadata(CategoryEntity::class));
    }

    public function findInactiveChildren(string $parentId): CategoryCollection
    {
        $criteria = new Criteria();
        $criteria->addFilter(new EqualsFilter('parentId', $parentId));
        $criteria->addFilter(new EqualsFilter('visible', false)); // Inaktive Kategorien
        return $this->search($criteria, \Shopware\Core\Framework\Context::createDefaultContext())->getEntities();
    }
}
{# views/storefront/layout/sidebar/category-navigation.html.twig #}

{% block category_sidebar_navigation %}
    {% for topLevelCategory in navigationTree %}
        <ul>
            <li>{{ topLevelCategory.translated.name }}</li>
            {% set inactiveChildren = categoryRepository.findInactiveChildren(topLevelCategory.id) %}
            {% for inactiveChild in inactiveChildren %}
                <li>{{ inactiveChild.translated.name }}</li>
            {% endfor %}
        </ul>
    {% endfor %}
{% endblock %}

etc.pp.

Aber wie gesagt, alles nur reine Spekulation…

Schau vielelicht auch mal hier: https://developer.shopware.com/docs/guides/plugins/plugins/framework/data-handling/reading-data.html

Ich denke aber, dass Du um die Plugin Erstellung nicht drum herum kommst…

1 „Gefällt mir“

Super, vielen Dank :slight_smile:

Das werde ich mir morgen mal anschauen. :+1:

Schönen Abend

Hallo,

hab mich jetzt durch die Dokus durchgekämpft. Alles hab ich zwar nicht verstanden, aber es funktioniert :slight_smile:
Danke nochmal an @Murmeltier für den Schubs in die richtige Richtung :+1:

Falls es jemanden interessiert, ich habe über ein Plugin eine custom twig function erstellt und hole darin die Daten aus der category-Tabelle:

Meine src/Resources/config/services.xml:

<?xml version="1.0" ?>

<container xmlns="http://symfony.com/schema/dic/services"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">

    <services>

        <service id="Phs\Custom\Twig\CustomFunctions" public="true">
            <argument type="service" id="category.repository"/>
            <tag name="twig.extension"/> <!--Required-->
        </service>

    </services>
</container>

Meine Custom-Klasse src/Twig/CustomFunctions.php:

<?php declare(strict_types=1);

namespace Phs\Custom\Twig;

use Shopware\Core\Framework\DataAbstractionLayer\EntityRepository;

use Twig\Extension\AbstractExtension;
use Twig\TwigFunction;

use Doctrine\ORM\EntityManagerInterface;
use Shopware\Core\Content\Category\CategoryCollection;
use Shopware\Core\Content\Category\CategoryEntity;
use Shopware\Core\Framework\DataAbstractionLayer\EntityRepositoryInterface;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsFilter;


class CustomFunctions extends AbstractExtension
{
    private EntityRepository $categoryRepository;

    public function __construct(EntityRepository $categoryRepository)
    {
        // über config/services.xml werden die Parameter-Daten definiert
        $this->categoryRepository = $categoryRepository;
    }

    public function getFunctions()
    {
        // hier werden die Twig-Funktionen definiert
        return [
            new TwigFunction('getSubCategories', [$this, 'getSubCategories'])
        ];
    }


    /**
     * Die Funktion liefert die Unterkategorien der übergebenen parentId
     * @param string $parentId
     * @return mixed
     */
    public function getSubCategories(string $parentId)
    {

        $criteria = new Criteria();
        $criteria->addFilter(new EqualsFilter('parentId', $parentId));
        
        return $this->categoryRepository->search($criteria, \Shopware\Core\Framework\Context::createDefaultContext())->getEntities();
    }

}

Hier kann man dann ggf. die Suchkriterien noch erweitern.

Im twig kann man es dann so aufrufen und weiterverarbeiten:

{{ dump(getSubCategories('018e5b908e73714a99b7f9759844daa2')) }}

Vielleicht hilft das ja dem einen oder anderen.

Viele Grüße

1 „Gefällt mir“

Dieses Thema wurde automatisch 30 Tage nach der letzten Antwort geschlossen. Es sind keine neuen Antworten mehr erlaubt.