Programmieren lernen | Codebeispiele | Jobbörse | Webentwicklung

Eine eigene TYPO3 Extension (Extbase/Fluid) mit System Kategorien erstellen (Teil 2)

In diesem Teil verknüpfen wir unsere TYPO3 Extension, die wir in Teil 1 der Reihe erstellt haben, mit den System Kategorien von TYPO3.

Der Extension Builder hat unsere Extension, die wir in Teil 1 erstellt haben, in dem Verzeichnis
„typo3conf -> ext“
abgespeichert. In unserem Fall ist der Ordnername der Extension „ha_kategorieext“ analog zu unserem angegebenen Extension Key. Folgende Struktur hat uns der Extension Builder darin angelegt:

  • Classes
  • Configuration
  • Documentation.tmpl (kann gelöscht werden)
  • Resources
  • Tests (kann gelöscht werden)
  • ext_emconf.php
  • ext_icon.gif
  • ext_localconf.php
  • ext_tables.php
  • ext_tables.sql
  • ExtensionBuilder.json (kann gelöscht werden)

TYPO3 System Kategorien integrieren

Jetzt wird es Zeit unsere TYPO3 Extension zu bearbeiten.

NeuerInhaltController.php (Classes -> Controller)

Aktueller Code:

public function listAction() {
        $neuerInhalts = $this->neuerInhaltRepository->findAll();
        $this->view->assign('neuerInhalts', $neuerInhalts);
    }

Ersetzen durch:

public function listAction() {
        $demand = $this -> createDemandObjectFromSettings($this -> settings);
        $entries = $this -> neuerInhaltRepository -> findDemanded($demand);
        $this -> view -> assign('neuerInhalts', $entries);
    }

Und zusätzlich hinzufügen:

protected function createDemandObjectFromSettings($settings) {
        $demand = $this->objectManager->get('Vekategorieext\\HaKategorieext\\Domain\\Model\\NeuerInhalt'); // Neuer Inhalt ist der Dateiname vom Domain Modell -> Classes -> Domain -> Model
        $demand->setCategories($settings['categories']);
        return $demand;
    }

NeuerInhalt.php (Classes -> Domain -> Model)

Aktueller Code:

public function setCategories(\TYPO3\CMS\Extbase\Persistence\ObjectStorage $categories) {
        $this->categories = $categories;
    }

Ändern in:

public function setCategories($categories) {
        $this->categories = $categories;
    }

NeuerInhaltRepository.php (Classes -> Domain -> Repository)

Aktueller Code:

protected $defaultOrderings = array(
        'sorting' => \TYPO3\CMS\Extbase\Persistence\QueryInterface::ORDER_ASCENDING
    );

Ersetzen durch:

public function findDemanded($demand) {
        $query = $this -> createQuery();
        $query -> getQuerySettings() -> setRespectStoragePage(FALSE);
        $query -> setOrderings($this -> createOrdering());
        $constraints = $this -> createConstraintsFromDemand($query, $demand);
        if (!empty($constraints)) {
            $query -> matching(
            $query -> logicalAnd($constraints)
        );
        }
        return $query -> execute();
    }
        
        
    protected function createConstraintsFromDemand(\TYPO3\CMS\Extbase\Persistence\QueryInterface $query, $demand) {
        $constraints = array();
        
        $categories = $demand -> getCategories();
        if ((!empty($categories))) {
            $categoryConstraints = array();
            $categories = \TYPO3\CMS\Core\Utility\GeneralUtility::intExplode(',', $categories, TRUE);
            foreach ($categories as $category) {
                $categoryConstraints[] = $query -> contains('categories', $category);
            }
            $constraints = $query -> logicalOr($categoryConstraints);
        }
        return $constraints;
    }
        
    protected function createOrdering() {
        $orderings = array('sorting' => \TYPO3\CMS\Extbase\Persistence\QueryInterface::ORDER_DESCENDING);
        return $orderings;
    }

Flexform hinzufügen

ext_tables.php

Am Ende hinzufügen:

$extensionName = strtolower(\TYPO3\CMS\Core\Utility\GeneralUtility::underscoredToUpperCamelCase($_EXTKEY));
$pluginName = strtolower('Fekategorieext');
$pluginSignature = $extensionName.'_'.$pluginName;

$TCA['tt_content']['types']['list']['subtypes_excludelist'][$pluginSignature] = 'layout,recursive,select_key,pages';
$TCA['tt_content']['types']['list']['subtypes_addlist'][$pluginSignature] = 'pi_flexform';
\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addPiFlexFormValue($pluginSignature, 'FILE:EXT:'.$_EXTKEY . '/Configuration/FlexForms/flexform.xml');

FlexForms Ordner erstellen (Configuration -> FlexForms)

Im FlexForms Ordner eine flexform.xml erstellen (Configuration -> FlexForms -> flexform.xml)

Inhalt:

<T3DataStructure>
    <meta>
        <langDisable>1</langDisable>
    </meta>
    <sheets>
        <sDEF>
            <ROOT>
                <TCEforms>
                    <sheetTitle>title</sheetTitle>
                </TCEforms>
                <type>array</type>
                <el>
                    <settings.categories>
                        <TCEforms>
                          <exclude>1</exclude>
                          <label>Kategorien:</label>
                          <config>
                            <type>select</type>
                            <autoSizeMax>50</autoSizeMax>
                            <foreign_table>sys_category</foreign_table>
                            <foreign_table_where> AND sys_category.sys_language_uid IN (-1, 0) ORDER BY sys_category.title ASC</foreign_table_where>
                            <maxitems>9999</maxitems>
                            <renderMode>tree</renderMode>
                            <size>10</size>
                            <treeConfig>
                                <appearance>
                                    <expandAll>1</expandAll>
                                    <showHeader>1</showHeader>
                                </appearance>
                                <parentField>parent</parentField>
                            </treeConfig>
                          </config>
                        </TCEforms>
                    </settings.categories>
                </el>
            </ROOT>
        </sDEF>
    </sheets>
</T3DataStructure>

setup.txt (Configuration -> TypoScript)

Das komplette CSS_DEFAULT_STYLE kann gelöscht werden

Aktueller Code:

plugin.tx_hakategorieext_fekategorieext {
    view {
        templateRootPaths.0 = {$plugin.tx_hakategorieext_fekategorieext.view.templateRootPath}
        partialRootPaths.0 = {$plugin.tx_hakategorieext_fekategorieext.view.partialRootPath}
        layoutRootPaths.0 = {$plugin.tx_hakategorieext_fekategorieext.view.layoutRootPath}
    }
    persistence {
        storagePid = {$plugin.tx_hakategorieext_fekategorieext.persistence.storagePid}
    }
}

Ändern zu:

plugin.tx_hakategorieext_fekategorieext {
    view {
        templateRootPaths.0 = {$plugin.tx_hakategorieext_fekategorieext.view.templateRootPath}
        partialRootPaths.0 = {$plugin.tx_hakategorieext_fekategorieext.view.partialRootPath}
        layoutRootPaths.0 = {$plugin.tx_hakategorieext_fekategorieext.view.layoutRootPath}
    }
    persistence {
        storagePid = {$plugin.tx_hakategorieext_fekategorieext.persistence.storagePid}
    }
    mvc {
        callDefaultActionIfActionCantBeResolved = 1
    }
}

Extension aktivieren

That’s it! Zum Schluß müssen wir nur noch unsere TYPO3 Extension im Extension Manager aktivieren. Das Statische TypoScript einbinden und schon kann man die System internen Kategorien von TYPO3 nutzen.

10 Gedanken zu „Eine eigene TYPO3 Extension (Extbase/Fluid) mit System Kategorien erstellen (Teil 2)“

  • Bernd
    7.12.2017 um 9:47

    Sehr ausführlich aufgebaut und nett geschrieben. M,it der Anleitung kann ich zwar diese eine Extension nachbauen, jedoch würde ich gerne wissen, warum man die einzelnen Schritte macht und was die einzelnen Sachen bewirken.
    Natürlich versteht man das meiste durch den Code.. Aber trotzdem wäre eine textliche Übersetzung eine nette Ergänzung. Dann könnte man lernen statt einfach nur zu kopieren. 🙂
    Trotzdem Danke für diesen ausführlichen Beitrag. Hat mir sehr weiter geholfen. Typo3 ist ja kleider kaum dokumentiert.. und selbst wenn etwas dokumentiert ist, ist das oft veraltet.

  • Markus
    7.12.2017 um 12:10

    Hallo Bernd, vielen dank für deinen Kommentar. Manchmal ist weniger mehr. 😉 Die Seite kennst du? https://docs.typo3.org/

  • Oliver
    2.02.2018 um 9:55

    Mit der Zeile $TCA[‚tt_content‘][‚types‘][‚list‘][’subtypes_excludelist‘][$pluginSignature] = ‚layout,recursive,select_key,pages‘; in der ext_tables.php entfernst du ja quasi die Datensatzsammlung. Wenn ich die Zeile entferne, erscheint die Datensatzsammlung wieder im Backend, hat aber keine Auswirkung auf die Anzeige im Frontend. Lässt sich das in deiner Beispiel-Extension. irgendwie einfach kombinieren – die Auswahl der Datensatzsammlung und die der Systemkategorien?

  • Markus
    2.02.2018 um 13:27

    Hallo Oliver,

    dafür wären ein paar Zeilen mehr Code nötig das das auch im Frontend greift. Nur das Feld aktivieren reicht hier leider nicht.
    Grundsätzlich würde ich es über Flexform lösen.
    Vielleicht hilft dir der Artikel weiter: https://www.derhansen.de/2016/02/how-extbase-determines-storagepid.html

  • Oliver
    6.02.2018 um 15:43

    Hallo Markus, zunächst mal vielen Dank für deine Antwort. Könntest du vielleicht ein etwas detaillierteres Beispiel für Nicht-Programmiercracks geben?

  • Markus
    7.02.2018 um 20:23

    Hallo Oliver,

    schau mal hier, habe dazu einen Artikel erstellt.

  • Oliver
    9.02.2018 um 10:30

    Hallo Markus,

    sehr cool! Werd ich gleich mal ausprobieren. Wird mit Sicherheit auch einigen Integratoren, die mit Extension-Programmierung nicht so viel am Hut haben, helfen und das Leben erleichtern 🙂

  • Dominik
    19.03.2018 um 16:36

    Hallo Markus,
    ich habe für ca. 10 Stunden versucht, eine Extension zusammen mit einem Plugin zu erstellen und anstädig zu benutzen. Ich habe jedoch nur fehlerhafte Tutorials gefunden und deines ist das einzige, was komplett fehlerfrei und ohne Probleme mir geholfen hat. Gute Anleitung!
    Danke!!

  • Markus
    19.03.2018 um 19:54

    Hallo Dominik,

    vielen Dank für dein Feedback! Freut mich dir geholfen zu haben.

  • Christine
    13.03.2019 um 10:46

    @Oliver:
    Folgendermaßen lässt sich die Kombination „Datensatzsammlung“ und „Kategorien“ recht einfach realsieren (zumindest in TYPO3 7.6):

    In der Datei NeuerInhaltRepository.php (Classes -> Domain -> Repository) statt
    $query -> getQuerySettings() -> setRespectStoragePage(FALSE);
    neu:
    $query -> getQuerySettings() -> setRespectStoragePage(TRUE);

    UND zusätzlich folgendes beachten:

    Bei der Entwicklung einer eigenen Extension muss folgendes bedacht werden: ab TYPO3 Version 7 überschreibt die Deklaration von plugin.tx_extensionname.persistence.storagePid den Wert im Feld „Datensatzsammlung“. Dazu muss nicht einmal ein Wert für storagePid angegeben werden! Damit der Wert in „Datensatzsammlung“ nicht überschrieben wird, ändern wir die Angaben im Typoscript (Constants und Setup) folgendermaßen:

    In Configuration/TypoScript/setup.txt ändern:
    „plugin.tx_extensionname_pluginname“ zu „plugin.tx_extensionnamen“

    In Configuration/TypoScript/constants.txt ändern: „plugin.tx_extensionname_pluginname“ zu „plugin.tx_extensionname“

    Der Extension Builder generiert das TypoScript direkt für das einzelne Plugin. Obwohl das im Grunde funktioniert, ändern wir den Pfad auf eine allgemeine Extension-Konfiguration ab. Ein Vorteil ist, dass die Einträge im Feld Datensatzsammlung nicht länger von storagePid überschrieben werden.
    TYPO3 bzw. Extbase (das dieser Extension zugrundeliegende Framework) sucht nach Speicherorten in einer festgelegten Reihenfolge. Plugin-spezifische Konfigurationen überschreiben dabei stets die Werte im Feld Datensatzsammlung. Dazu muss für storagePid in tx_extensionname_pluginname nicht einmal ein Wert hinterlegt sein – es genügt schon die grundsätzliche Deklaration.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht.