Skip to main navigation Skip to main content Skip to page footer

Aggiungere un plugin ad una estensione

Esempio completo e coerente per niceadmin con:

  • vendor: Novaera
  • extension key: niceadmin
  • model: Tag
  • controller: TagController
  • plugin: Tags

Così puoi creare la tabella, leggere i record e mostrarli nel template.


1) ext_localconf.php

 

<?php

declare(strict_types=1);

defined('TYPO3') or die();

use Novaera\Niceadmin\Controller\TagController;
use TYPO3\CMS\Extbase\Utility\ExtensionUtility;

ExtensionUtility::configurePlugin(
    'Niceadmin',
    'Tags',
    [
        TagController::class => 'list,show,edit,delete',
    ],
    [
        TagController::class => 'edit,delete',
    ]
);

 


2) Configuration/TCA/Overrides/tt_content.php

 

<?php

declare(strict_types=1);

defined('TYPO3') or die();

use TYPO3\CMS\Extbase\Utility\ExtensionUtility;

ExtensionUtility::registerPlugin(
    'Niceadmin',
    'Tags',
    'Gestione Tags'
);

 


3) ext_tables.sql

 

CREATE TABLE tx_niceadmin_domain_model_tag (
    uid int(11) unsigned NOT NULL auto_increment,
    pid int(11) unsigned DEFAULT '0' NOT NULL,

    title varchar(255) DEFAULT '' NOT NULL,
    slug varchar(255) DEFAULT '' NOT NULL,

    tstamp int(11) unsigned DEFAULT '0' NOT NULL,
    crdate int(11) unsigned DEFAULT '0' NOT NULL,
    deleted tinyint(4) unsigned DEFAULT '0' NOT NULL,
    hidden tinyint(4) unsigned DEFAULT '0' NOT NULL,

    PRIMARY KEY (uid),
    KEY parent (pid)
);

 


4) Configuration/TCA/tx_niceadmin_domain_model_tag.php

 

<?php

declare(strict_types=1);

return [
    'ctrl' => [
        'title' => 'Tag',
        'label' => 'title',
        'tstamp' => 'tstamp',
        'crdate' => 'crdate',
        'delete' => 'deleted',
        'enablecolumns' => [
            'disabled' => 'hidden',
        ],
        'searchFields' => 'title,slug',
        'iconfile' => 'EXT:niceadmin/Resources/Public/Icons/Extension.svg',
    ],
    'types' => [
        '1' => [
            'showitem' => 'title, slug, hidden',
        ],
    ],
    'columns' => [
        'hidden' => [
            'exclude' => true,
            'label' => 'Hidden',
            'config' => [
                'type' => 'check',
                'renderType' => 'checkboxToggle',
            ],
        ],
        'title' => [
            'exclude' => true,
            'label' => 'Title',
            'config' => [
                'type' => 'input',
                'size' => 50,
                'eval' => 'trim,required',
            ],
        ],
        'slug' => [
            'exclude' => true,
            'label' => 'Slug',
            'config' => [
                'type' => 'input',
                'size' => 50,
                'eval' => 'trim',
            ],
        ],
    ],
];

 


5) Classes/Domain/Model/Tag.php

 

<?php

declare(strict_types=1);

namespace Novaera\Niceadmin\Domain\Model;

use TYPO3\CMS\Extbase\DomainObject\AbstractEntity;

class Tag extends AbstractEntity
{
    protected string $title = '';
    protected string $slug = '';

    public function getTitle(): string
    {
        return $this->title;
    }

    public function setTitle(string $title): void
    {
        $this->title = $title;
    }

    public function getSlug(): string
    {
        return $this->slug;
    }

    public function setSlug(string $slug): void
    {
        $this->slug = $slug;
    }
}

 


6) Classes/Domain/Repository/TagRepository.php

 

<?php

declare(strict_types=1);

namespace Novaera\Niceadmin\Domain\Repository;

use TYPO3\CMS\Extbase\Persistence\Repository;

class TagRepository extends Repository
{
}

 


7) Classes/Controller/TagController.php

 

<?php

declare(strict_types=1);

namespace Novaera\Niceadmin\Controller;

use Novaera\Niceadmin\Domain\Model\Tag;
use Novaera\Niceadmin\Domain\Repository\TagRepository;
use Psr\Http\Message\ResponseInterface;
use TYPO3\CMS\Extbase\Mvc\Controller\ActionController;

class TagController extends ActionController
{
    public function __construct(
        protected readonly TagRepository $tagRepository
    ) {}

    public function listAction(): ResponseInterface
    {
        $tags = $this->tagRepository->findAll();
        $this->view->assign('tags', $tags);

        return $this->htmlResponse();
    }

    public function showAction(Tag $tag): ResponseInterface
    {
        $this->view->assign('tag', $tag);

        return $this->htmlResponse();
    }

    public function editAction(?Tag $tag = null): ResponseInterface
    {
        $this->view->assign('tag', $tag);

        return $this->htmlResponse();
    }

    public function deleteAction(Tag $tag): ResponseInterface
    {
        $this->tagRepository->remove($tag);
        $this->addFlashMessage('Tag eliminato');

        return $this->redirect('list');
    }
}

 


8) Configuration/TypoScript/setup.typoscript

 

plugin.tx_niceadmin_tags {
    view {
        templateRootPaths.10 = EXT:niceadmin/Resources/Private/Templates/
        layoutRootPaths.10 = EXT:niceadmin/Resources/Private/Layouts/
        partialRootPaths.10 = EXT:niceadmin/Resources/Private/Partials/
    }
}

 


9) ext_typoscript_setup.typoscript

Se non stai usando Site Sets, aggiungi questo file:

 

<INCLUDE_TYPOSCRIPT: source="FILE:EXT:niceadmin/Configuration/TypoScript/setup.typoscript">

 


10) Resources/Private/Templates/Tag/List.html

 

<f:layout name="Default" />

<f:section name="Main">
    <h1>Lista tag</h1>

    <f:if condition="{tags}">
        <ul>
            <f:for each="{tags}" as="tag">
                <li>
                    <strong>{tag.title}</strong>
                    <f:if condition="{tag.slug}">
                        <br>
                        <small>{tag.slug}</small>
                    </f:if>
                    <br>
                    <f:link.action action="show" arguments="{tag: tag}">Dettaglio</f:link.action>
                    |
                    <f:link.action action="edit" arguments="{tag: tag}">Modifica</f:link.action>
                    |
                    <f:link.action action="delete" arguments="{tag: tag}">Elimina</f:link.action>
                </li>
            </f:for>
        </ul>
    </f:if>

    <f:if condition="{tags -> f:count()} == 0">
        <p>Nessun tag trovato.</p>
    </f:if>
</f:section>

 


11) Resources/Private/Templates/Tag/Show.html

 

<f:layout name="Default" />

<f:section name="Main">
    <h1>{tag.title}</h1>

    <p>
        <strong>Slug:</strong> {tag.slug}
    </p>

    <p>
        <f:link.action action="list">Torna alla lista</f:link.action>
    </p>
</f:section>

 


12) Resources/Private/Templates/Tag/Edit.html

 

<f:layout name="Default" />

<f:section name="Main">
    <h1>Modifica tag</h1>

    <f:if condition="{tag}">
        <p>
            <strong>{tag.title}</strong><br>
            {tag.slug}
        </p>
    </f:if>

    <f:if condition="{tag} == null">
        <p>Nessun tag selezionato.</p>
    </f:if>

    <p>
        <f:link.action action="list">Torna alla lista</f:link.action>
    </p>
</f:section>

 


13) Resources/Private/Layouts/Default.html

 

<f:render section="Main" />

 


14) Struttura finale

 

typo3conf/ext/niceadmin/
├── Classes/
│   ├── Controller/
│   │   └── TagController.php
│   └── Domain/
│       ├── Model/
│       │   └── Tag.php
│       └── Repository/
│           └── TagRepository.php
├── Configuration/
│   ├── TCA/
│   │   ├── Overrides/
│   │   │   └── tt_content.php
│   │   └── tx_niceadmin_domain_model_tag.php
│   └── TypoScript/
│       └── setup.typoscript
├── Resources/
│   └── Private/
│       ├── Layouts/
│       │   └── Default.html
│       ├── Partials/
│       └── Templates/
│           └── Tag/
│               ├── Edit.html
│               ├── List.html
│               └── Show.html
├── ext_localconf.php
├── ext_tables.sql
└── ext_typoscript_setup.typoscript

 


15) Passi finali

Dopo aver creato i file:

  1. svuota cache TYPO3
  2. vai in Admin Tools > Maintenance > Analyze Database
  3. crea la tabella tx_niceadmin_domain_model_tag
  4. aggiungi qualche record nella tabella
  5. inserisci il plugin Gestione Tags in pagina

16) Nota importante su delete

Così com’è, deleteAction() cancella subito. Per produzione è meglio fare:

  • conferma delete
  • protezione con permessi/login
  • token/argomenti validati
  • magari POST invece di semplice link

Per ora però va bene per fare le prove.

Se vuoi, nel prossimo messaggio ti scrivo anche la parte per creare i record Tag nel backend con una cartella storage e i permessi giusti