---
title: "Extensions based on EXT:news"
manual: "News system"
version: "main"
permalink: "https://docs.typo3.org/permalink/georgringer/news:ext-based-on-news@main"
source: "Tutorials/ExtendNews/ExtensionBasedOnNews/Index.rst"
rendered: "2026-09-23T19:24:09+00:00"
---

# Extensions based on EXT:news {#ext-based-on-news}

If you are using news records but need custom configuration and custom settings, you should think of creating a separate extension. This is really simple, just take a look at the following example.

-   [Setup of the extension](https://docs.typo3.org/permalink/georgringer/news:setup-of-the-extension@main)
-   [Setup](https://docs.typo3.org/permalink/georgringer/news:setup@main)
-   [Configuration](https://docs.typo3.org/permalink/georgringer/news:configuration@main)

## Setup of the extension {#setup-of-the-extension}

As a demonstration, a new extension with the extension key `news_filter` will be created. The following files and its content is required.

### ext_emconf.php {#ext-emconf-php}

This file contains the basic information about its extension like name, version, author...

```php
<?php

$EM_CONF[$_EXTKEY] = [
   'title' => 'News Filter',
   'description' => 'News filtering',
   'category' => 'fe',
   'author' => 'John Doe',
   'author_email' => 'john@doe.net',
   'author_company' => '',
   'state' => 'stable',
   'uploadfolder' => 0,
   'clearCacheOnLoad' => 1,
   'version' => '1.0.0',
   'constraints' => [
      'depends' => [
         'typo3' => '7.6.0-8.9.99',
      ],
      'conflicts' => [],
      'suggests' => [],
   ],
];
```

### ext_localconf.php {#ext-localconf-php}

Create a basic plugin with one action called `list`.

```php
<?php
defined('TYPO3') or die();

$boot = function () {
    \TYPO3\CMS\Extbase\Utility\ExtensionUtility::configurePlugin(
        'NewsFilter',
        'Filter',
        [
            \GeorgRinger\NewsFilter\Controller\FilterController::class => 'list',
        ]
    );
};

$boot();
unset($boot);
```

### Configuration/TCA/Overrides/tt_content.php {#configuration-tca-overrides-tt-content-php}

Register the plugin:

```php
<?php
defined('TYPO3') or die();

/***************
 * Plugin
 */
\TYPO3\CMS\Extbase\Utility\ExtensionUtility::registerPlugin(
   'NewsFilter',
   'Filter',
   'Some demo'
);
```

### Classes/Controller/FilterController.php {#extension-custom-controller}

Create a basic controller with the mentioned action.

```php
<?php

namespace GeorgRinger\NewsFilter\Controller;

use GeorgRinger\News\Domain\Model\Dto\NewsDemand;
use GeorgRinger\News\Domain\Repository\NewsRepository;
use TYPO3\CMS\Extbase\Mvc\Controller\ActionController;

class FilterController extends ActionController
{
    protected NewsRepository $newsRepository;

    public function __construct(NewsRepository $newsRepository)
    {
        $this->newsRepository = $newsRepository;
    }

    public function listAction()
    {
        $demand = $this->createDemandObject();
        $this->view->assignMultiple([
            'news' => $this->newsRepository->findDemanded($demand)
        ]);
    }

    protected function createDemandObject(): NewsDemand
    {
        $demand = new NewsDemand();
        $demand->setLimit(10);

        return $demand;
    }
}
```

### Resources/Private/Templates/Filter/List.html {#resources-private-templates-filter-list-html}

Create the template:

```html
<f:if condition="{news}">
   <f:then>
      <div class="row">
         <f:for each="{news}" as="newsItem">
            <div class="col-md-3">
               <h5>{newsItem.title}</h5>
            </div>
         </f:for>
      </div>
   </f:then>
   <f:else>
      <div class="alert alert-danger">No news found</div>
   </f:else>
</f:if>
```

## Setup {#setup}

After enabling the extension in the Extension Manager and creating a plugin "Filter" on a page, you will see up to 10 news records of your system.

> [!TIP]
> **Hint**
>
> If your installation is based on composer, you need to add the classes to the PSR-4 section.
>
> ```js
> "autoload": {
>    "psr-4": {
>       "GeorgRinger\\NewsFilter\\": "path/to/news_filter/Classes/"
>    }
> }
> ```

## Configuration {#configuration}

There are multiple ways how to configure which news records should be shown. The fastest way is to hardcode the configuration.

### Hardcode it {#hardcode-it}

By modifying the controller with the following code, you will change the output to show only those news records which fulfill the following requirements:

-   The pid is `123`
-   The author is `John`
-   The id of the records is neither `12` nor `45`.

```php
protected function createDemandObject(): NewsDemand
{
    $demand = new NewsDemand();
    $demand->setStoragePage('123');
    $demand->setAuthor('John');
    $demand->setHideIdList('12,45');

    return $demand;
}
```

### Use FlexForms {#use-flexforms}

FlexForms are a powerful tool to let editors configure plugins.

#### Configuration/TCA/Overrides/tt_content.php {#configuration-tca-overrides-tt-content-php-1}

Exchange the existing file with the following content.

```php
<?php
defined('TYPO3') or die();

/***************
 * Plugin
 */
\TYPO3\CMS\Extbase\Utility\ExtensionUtility::registerPlugin(
   'news_filter',
   'Filter',
   'Some demo'
);

$GLOBALS['TCA']['tt_content']['types']['list']['subtypes_excludelist']['newsfilter_filter'] = 'recursive,select_key,pages';
$GLOBALS['TCA']['tt_content']['types']['list']['subtypes_addlist']['newsfilter_filter'] = 'pi_flexform';
\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addPiFlexFormValue('newsfilter_filter',
   'FILE:EXT:news_filter/Configuration/FlexForms/flexform_news_filter.xml');
```

#### Configuration/FlexForms/flexform_news_filter.xml {#configuration-flexforms-flexform-news-filter-xml}

The syntax of `FlexForms` is identical to the one of `TCA` with the only difference that it is written in XML instead of PHP.

```xml
<T3DataStructure>
   <sheets>
      <sDEF>
         <ROOT>
            <sheetTitle>LLL:EXT:news/Resources/Private/Language/locallang_be.xlf:flexforms_tab.settings</sheetTitle>
            <type>array</type>
            <el>
               <settings.startingPoint>
                  <label>LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.startingPoint</label>
                  <config>
                     <type>group</type>
                     <allowed>pages</allowed>
                     <size>3</size>
                     <maxitems>50</maxitems>
                     <minitems>0</minitems>
                     <wizards>
                        <suggest>
                           <type>suggest</type>
                           <default>
                              <searchWholePhrase>1</searchWholePhrase>
                           </default>
                        </suggest>
                     </wizards>
                  </config>
               </settings.startingPoint>
            </el>
         </ROOT>
      </sDEF>
   </sheets>
</T3DataStructure>
```

Important is that each element's name is prepended with `settings.`.

> [!TIP]
> **Hint**
>
> Take a look at the FlexForms of the news extension for inspiration. You can even just copy & paste settings from there.
> The file can be found at `EXT:news/Configuration/FlexForms/flexform_news.xml`.

#### Classes/Controller/FilterController.php {#classes-controller-filtercontroller-php-1}

Adopt the controller to use the settings instead of the hardcoded ones.

```php
protected function createDemandObject(): NewsDemand
{
    $demand = new NewsDemand();
    // Because of the naming "<settings.startingPoint>", you can use $this->settings['startingPoint']
    $demand->setStoragePage($this->settings['startingPoint']);
    $demand->setLimit(10);

    return $demand;
}
```
