Extend a Typo3 Extbase model with custom field

Extending an extbase model of a Typo3 extension for custom fields is a commonly needed feature and quite easy to implement, once you figured out the necessary steps. In this post I am going to explain how a custom field is added in the case of extending the popular extension news for the custom field subtitle.
Requirement for this article is a working Typo3 installation with the news extension by Georg Ringer installed and a news page for the list- and detailview of the news items though it’s possible to extend any model/record with the same procedure.

First of all we are going to make a completely new Typo3 extension with the help of the extension builder name “news_extend”, extension category is “frontend” and no model added. A basic empty extension.

In the next step we are going to tell the news extension to not use the default html template for the detail page but our custom one by adding some Typoscript.

Add two files in your extension:
EXT:news_extend/Configuration/TypoScript/constants.txt
EXT:news_extend/Configuration/TypoScript/setup.txt

and insert the following in your constants.txt (!)

plugin.tx_news.view.templateRootPath = EXT:news_extend/Resources/Private/Templates/

To add your extension typoscript to the list of selectable typoscript templates add the following to your EXT:news_extend/ext_tables.php

\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addStaticFile($_EXTKEY, 'Configuration/TypoScript', 'News Extend');

and add the extension typoscript template named ‘News Extend’ in your main typoscript template on the root page.

Now create the directory EXT:news_extend/Resources/Private/Templates/News/  and copy the file EXT:news/Resources/Private/Templates/News/Detail.html into it. If you make a change in this html file you should see the changes in the frontend detail view of your news.

The next step is creating a model that extends the news base model,  add your new field in this custom model and tell extbase to use this altered model for the news records.

Create Ext:news_extend/Classes/Domain/Model/NewsDefault.php with the following content:

<?php
namespace LuJa\NewsExtend\Domain\Model;

/**
 * News model for default news
 *
 * @package TYPO3
 * @subpackage tx_news
 */
class NewsDefault extends \GeorgRinger\News\Domain\Model\NewsDefault {
   /**
    * @var string
    */
   protected $subtitle;

   /**
    * Get title
    *
    * @return string
    */
   public function getSubtitle()
   {
      // return "teststring";
      return $this->subtitle;
   }

   /**
    * Set title
    *
    * @param string $subtitle subtitle
    * @return void
    */
   public function setSubtitle($subtitle)
   {
      $this->subtitle = $subtitle;
   }
}

(Make sure the vendor-name at the top of the file is the same as you set in the extension builder)

As you can see this class extends the basic news class, so you have all properties and methods of the base class in addition to your “subtitle” property.

To tell extbase to use this model instead of the original add the following typoscript to your extension typoscript setup: EXT:news_extend/Configuration/TypoScript/setup.txt

plugin.tx_news {
    persistence {
        classes {
            GeorgRinger\News\Domain\Model\News {
                subclasses {
                    # three different classes are used for each news type
                    # 0 == default news
                    0 = LuJa\NewsExtend\Domain\Model\NewsDefault
                }
            }
            LuJa\NewsExtend\Domain\Model\NewsDefault {
                mapping {
                    recordType = 0
                    tableName = tx_news_domain_model_news
                }
            }
        }
    }
}

(Ext:news uses three different models for the three news types. Here we overwrite the model for the default type with type == 0)

This should already work and if you outcomment the

// return "teststring";

in Ext:news_extend/Classes/Domain/Model/NewsDefault.php, add the fluidmarker {newsItem.subtitle} in your custom detail html template
EXT:news_extend/Resources/Private/Templates/News/Detail.html you should see the teststring on your news detail view.

Thinks missing here are adding the subtitle field to the news TCA and displaying it in the news record.

First we add the new field to the database table by adding
EXT:news_extend/ext_tables.sql with the following content:

CREATE TABLE tx_news_domain_model_news (
 subtitle varchar(255) DEFAULT '' NOT NULL
);

For displaying the field to the news record, add the following to
EXT:news_extend/ext_tables.php

// define new fields
$tempColumns = array(
   'subtitle' => array(
      'exclude' => 0,
      'label' => 'LLL:EXT:news_extend/Resources/Private/Language/locallang_db.xlf:tx_newsextend_domain_model_news.subtitle',
      'config' => array(
         'type' => 'input',
         'size' => 30,
         'eval' => 'trim'
      ),
   ),
);

// add field to tca
\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addTCAcolumns(
   'tx_news_domain_model_news',
   $tempColumns,
   1
);

// add new field subtitle after title
\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addToAllTCAtypes("tx_news_domain_model_news", 'subtitle', '', 'after:title');

Finally we add the language file and the defined label in
EXT:news_extend/Resources/Private/Language/locallang_db.xlf

<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<xliff version="1.0">
   <file source-language="en" datatype="plaintext" original="messages" date="2015-07-31T15:13:12Z" product-name="news_extend">
      <header/>
      <body>
         <trans-unit id="tx_newsextend_domain_model_news.subtitle">
            <source>Untertitel Neu</source>
         </trans-unit>

      </body>
   </file>
</xliff>

Troubleshooting:

  • Extension installed ?
  • Extension Typoscript template added to your main template (after the news template) ?
  • Vendor name correct ? (your individual vendorname instead of “LuJa”)
  • Install tool cache cleared ?
  • Database updated (Install tool) ?

This way of extending can be done with any data model/extension with as many fields as you wish.