---
title: "AbstractPlugin"
manual: "TYPO3 Explained"
version: "11.5"
permalink: "https://docs.typo3.org/permalink/t3coreapi:abstractplugin@11.5"
source: "ExtensionArchitecture/HowTo/FrontendPlugin/AbstractPlugin.rst"
rendered: "2026-10-21T15:30:00+00:00"
---

> [!WARNING]
> **Attention**
>
> TYPO3 v11 has reached end-of-life as of October 31th 2024 and
> is no longer being maintained. Use the version switcher on the top
> left of this page to select documentation for a supported version of TYPO3.
>
> Need more time before upgrading?
> You can purchase Extended Long Term Support (ELTS) for TYPO3 v11 here:
> [TYPO3 ELTS](https://typo3.com/services/extended-support-elts).

# AbstractPlugin {#abstractplugin}

This class is used as base class for frontend plugins.

Most legacy frontend plugins are extension classes of this one.

This class contains functions which assists these plugins in creating lists,
searching, displaying menus, page-browsing (next/previous/1/2/3) and handling
links.

Functions are all prefixed `pi_` which is reserved for this class. Those
functions can be overridden in the extension classes. Therefore plugins based
on the `AbstractPlugin` are also called "pi-based plugins".

The `AbstractPlugin` still contains hard-coded HTMl in many functions.
These can not be used for non-HTML output like JSON or XML feeds.

<!-- TODO: no Markdown rendering for "versionchanged" -->

The AbstractPlugin class used to be named tslib_pibase before
TYPO3 v6.0. Therefore the old names "pi_base" or "pi-based plugin" are
still used by some people for historic reasons. "pi" is short for
plug-in.

## TypoScript {#typoscript}

There is no predefined entry method, the method to be used as entry-point is
defined via TypoScript:

**EXT:sr_feuser_register/Configuration/TypoScript/PluginSetup/setup.typoscript**

```typoscript
plugin.tx_srfeuserregister_pi1 = USER_INT
plugin.tx_srfeuserregister_pi1 {
   userFunc = SJBR\SrFeuserRegister\Controller\RegisterPluginController->main
   // set some options

   _DEFAULT_PI_VARS {
      // set some default values
   }
}
```

You can use the TypoScript content objects [USER](https://docs.typo3.org/m/typo3/reference-typoscript/11.5/en-us/ContentObjects/UserAndUserInt/Index.html#cobj-user) for
cached plugins or [USER_INT](https://docs.typo3.org/m/typo3/reference-typoscript/11.5/en-us/ContentObjects/UserAndUserInt/Index.html#cobj-user-int) when caching should
be disabled.

The following keys are reserved when creating pi-based plugins:

-   **`_DEFAULT_PI_VARS`**

    Used to define default values that override values not set in the main
    TypoScript plugin definition.

-   **`_LOCAL_LANG.<key>`**

    Used to override translated strings.

## AbstractPlugin implementation {#abstractplugin-implementation}

An implementing class could look like this:

**EXT:sr_feuser_register/Classes/Controller/RegisterPluginController.php**

```php
<?php
namespace SJBR\SrFeuserRegister\Controller;

use TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer;
use TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController;
use TYPO3\CMS\Frontend\Plugin\AbstractPlugin;
// ...

class RegisterPluginController extends AbstractPlugin
{
   /**
    * Content object
    *
    * @var ContentObjectRenderer
    */
   public $cObj;

   /**
    * Extension key
    *
    * @var string
    */
   public $extKey = 'sr_feuser_register';

   // ...

   /**
    * Plugin entry script
    *
    * @param string $content: rendered content (not used)
    * @param array $conf: the plugin TS configuration
    * @return string the rendered content
    */
   public function main($content, $conf)
   {
      $extensionName = GeneralUtility::underscoredToUpperCamelCase($this->extKey);
      $this->pi_setPiVarDefaults();
      $this->conf =& $conf;

      // do something

      return $this->pi_wrapInBaseClass($this->prefixId, $content);
   }
}
```

See extension [sr_feuser_register](https://codeberg.org/sjbr/sr-feuser-register)
for a complete example.

## TCA configuration {#tca-configuration}

**EXT:my_extension/Configuration/TCA/Overrides/tt_content.php**

```php
use TYPO3\CMS\Core\Utility\ExtensionManagementUtility;
defined('TYPO3') or die();

$GLOBALS['TCA']['tt_content']['types']['list']['subtypes_excludelist']['myextension_pi1'] = 'layout,select_key';
$GLOBALS['TCA']['tt_content']['types']['list']['subtypes_addlist']['myextension_pi1'] = 'pi_flexform';

// Use this function if you want to register a FlexForm for the backend record
ExtensionManagementUtility::addPiFlexFormValue(
    'myextension_pi1',
    'FILE:EXT:my_extension/Configuration/FlexForms/SomeFlexForm.xml'
);

ExtensionManagementUtility::addPlugin(
    [
        'LLL:EXT:my_extension/Resources/Private/Language/locallang_db.xlf:tt_content.list_type',
        'myextension_pi1'
    ],
    'list_type',
    'my_extension'
 );
```

`ExtensionManagementUtility::addPlugin` expects the following parameters:

-   **$itemArray**

    `array`: Numerical array:

    -   **\[0\]**

        `string`: Plugin label,

    -   **\[1\]**

        `string`: Plugin identifier / plugin key, ideally prefixed with an extension-specific name (for example `'events2_list'`),

    -   **\[2\]**

        `string`:  Path to plugin icon,

    -   **\[3\]**

        an optional group idenitfier, falls back to `'default`

-   **$type**

    `string`: Type (Default: `'list_type'`) - basically a field from "tt_content" table

-   **$extensionKey**

    `string`: The extension key in snake_case, for example :php`'my_extension'`
