Add custom fields 

Follow this chapter to learn how to add new fields or actions.

It is important to know how this concept is implemented. If a class should be extended, EXT:news will generate a new file containing the original class of the extension itself and all other classes which should extended it.

Take a look at the following 2 working examples:

The files are saved by using the Caching Framework in the directory typo3temp/Cache/Code/news.

1) Add a new field in the backend 

To add new fields, use either the extension extension_builder or create the extension from scratch.

The extension key used in this examples is eventnews.

Create the fields 

3 files are basically all what you need:

ext_emconf.php 

The file ext_emconf.php holds all basic information about the extension like the title, description and version number.

<?php

$EM_CONF[$_EXTKEY] = [
   'title' => 'news events',
   'description' => 'Events for news',
   'category' => 'plugin',
   'author' => 'Georg Ringer',
   'author_email' => '',
   'state' => 'alpha',
   'uploadfolder' => false,
   'createDirs' => '',
   'clearCacheOnLoad' => true,
   'version' => '1.0.0',
   'constraints' => [
      'depends' => [
         'typo3' => '7.6.13-8.7.99',
         'news' => '6.2.0-6.9.99',
      ],
      'conflicts' => [],
      'suggests' => [],
   ],
];
Copied!

SQL definition 

Create the file ext_tables.sql in the root of the extension directory with the following content:

# Table structure for table 'tx_news_domain_model_news'
#
CREATE TABLE tx_news_domain_model_news (
   location_simple varchar(255) DEFAULT '' NOT NULL,
   other_categories int(11) DEFAULT '0' NOT NULL
);
Copied!

TCA definition 

The TCA defines which tables and fields are available in the backend and how those are rendered (e.g. as input field, textarea, select field, ...).

In this example, the table tx_news_domain_model_news will be extended by a simple input field and a 2nd category relation. Create the file Configuration/TCA/Overrides/tx_news_domain_model_news.php.

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

$fields = [
   'location_simple' => [
      'label' => 'My location',
      'config' => [
         'type' => 'input',
         'size' => 15
      ],
   ],
   'other_categories' => [
      'label' => 'Other categories',
      'config' => [
         'type' => 'category',
      ],
   ],
];

\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addTCAcolumns('tx_news_domain_model_news', $fields);
\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addToAllTCAtypes('tx_news_domain_model_news', 'location_simple,other_categories');
Copied!

Install the extension 

Now you should be able to install the extension and if you open a news record, you should see the new field in the last tab.

2) Register the class 

Until now, EXT:news won't use the new field because it doesn't know about it. To change that, you need to register your new model.

Registration 

Create the file ext_localconf.php in the root of the extension:

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

$GLOBALS['TYPO3_CONF_VARS']['EXT']['news']['classes']['Domain/Model/News']['eventnews'] = 'eventnews';
Copied!

Domain/Model/News is the namespace to the class which should be extended and eventnews is the extension key.

Custom class 

As the class Domain/Model/News should be extended, create a file at the same path in the own extension which is path/to/eventnews/Classes/Domain/Model/News.php:

<?php

namespace GeorgRinger\Eventnews\Domain\Model;

use GeorgRinger\News\Domain\Model\Category;
use TYPO3\CMS\Extbase\Annotation\ORM\Lazy;
use TYPO3\CMS\Extbase\Persistence\ObjectStorage;

class News extends \GeorgRinger\News\Domain\Model\News
{
   protected string $locationSimple = '';

   /**
    * @var ?ObjectStorage<Category>
    */
   #[Lazy]
   protected ?ObjectStorage $otherCategories;

   public function __construct()
   {
      $this->otherCategories = new ObjectStorage();
   }

   public function initializeObject(): void
   {
      $this->otherCategories = $this->otherCategories ?? new ObjectStorage();
   }

   public function getLocationSimple(): string
   {
      return $this->locationSimple;
   }

   public function setLocationSimple(string $locationSimple): void
   {
      $this->locationSimple = $locationSimple;
   }

   /**
    * @return ?ObjectStorage<Category>
    */
   public function getOtherCategories(): ?ObjectStorage
   {
      return $this->otherCategories;
   }

   /**
    * @param ObjectStorage<Category> $otherCategories
    */
   public function setOtherCategories(ObjectStorage $otherCategories): void
   {
      $this->otherCategories = $otherCategories;
   }
}
Copied!

3) Exclude the class from dependency injection 

As the class you define will be added to a new generated class, the class needs to be excluded from dependency injection in Configuration/Services.yaml:

services:
  _defaults:
    autowire: true
    autoconfigure: true
    public: false

  GeorgRinger\Eventnews\:
    resource: '../Classes/*'
    exclude: '../Classes/Domain/Model/*'
Copied!

Rebuild proxy classes 

After changes to the extending class or its registration, rebuild the proxy classes:

bin/typo3 news:rebuildProxyClasses
Copied!

This regenerates the merged class files in var/cache/code/news/. You should run this command after every change to the news model or any extension that extends it.

Alternatively, clearing the system cache via the backend or the Admin Tools module will also trigger a rebuild on the next request.