Die Extbase Extension „news“ um ein Feld erweitern

Aktualisiert für TYPO3 7 LTS am 16.11.2015.

Wie erweitert man eine Extbase Extension um ein neues Datenbank-Feld? Und zwar ohne die Extension direkt anzufassen, ohne Quick’n’dirty Hacks und ohne Workarounds? Welche Schritte muss man befolgen, um ein neues Datenbankfeld am Datensatz anzuzeigen und es schlussendlich im Fluid Template auch benutzen zu können?

Das nachfolgende Beispiel setzt eine Extension „news_new_fields“ voraus (ggf. leer mit dem Extension Builder angelegt), in die die zwei Template-Ressourcen „Detail.html“ und „List.html“ der „news“-Extension kopiert wurden und in der die genannten Dateien aufgebaut werden.

ext_tables.sql


CREATE TABLE tx_news_domain_model_news (
	new_field varchar(250) DEFAULT '' NOT NULL
);

ext_tables.php


<?php
\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addStaticFile($_EXTKEY, 'Configuration/TypoScript', 'News new fields');

$tempColumns = Array (
		"new_field" => Array (
				"exclude" => 1,
				"label" => "LLL:EXT:news_new_fields/Resources/Private/Language/locallang_db.xlf:new_field",
				"config" => Array (
						"type" => "input",
						"size" => "30",
						"eval" => "trim",
				)
		),
);

\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addTCAcolumns("tx_news_domain_model_news",$tempColumns,1);
\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addToAllTCAtypes("tx_news_domain_model_news","new_field;;;;1-1-1");
?>

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-11-15T16:01:20Z" product-name="news_new_fields">
		<header/>
		<body>
			<trans-unit id="new_field" xml:space="preserve">
				<source>New field</source>
			</trans-unit>
		</body>
	</file>
</xliff>

Resources/Private/Language/de.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-11-15T16:01:20Z" product-name="news" target-language="de">
		<header/>
		<body>
			<trans-unit id="new_field" xml:space="preserve" approved="yes">
				<target>Neues Feld</target>
			</trans-unit>
		</body>
	</file>
</xliff>

Configuration/TypoScript/constants.txt


plugin.tx_news {
	view {
		templateRootPath = EXT:news_new_fields/Resources/Private/Templates/
	}
}

Configuration/TypoScript/setup.txt


plugin.tx_news {
        persistence {
                classes {
                        GeorgRinger\News\Domain\Model\News {
                                subclasses {
                                        # hier wichtig: index 0 überschreiben für die 
                                        # normale News-Ansicht
                                        # 0 == Typ-Auswahl an News-Datensatz
                                        0 = Marwein\NewsNewFields\Domain\Model\NewsDefault
                                }
                        }
                        Marwein\NewsNewFields\Domain\Model\NewsDefault {
                                mapping {
                                        recordType = 0
                                        tableName = tx_news_domain_model_news
                                }
                        }
                }
        }
}

Classes/Domain/Model/NewsDefault.php


<?php
namespace Marwein\NewsNewFields\Domain\Model;

class NewsDefault 
    extends \GeorgRinger\News\Domain\Model\News
{
        /**
         * the new field
         * @var string
         */
        protected $newField;
        
        /**
         * Returns an array of orderings created from a given demand object.
         *
         * @param string $newField
         * @return void
         */
        public function setNewField($newField) {
                $this->newField = $newField;
        }
        /**
         * Get new field
         *
         * @return string
         */
        public function getNewField() {
                return $this->newField;
        }
}
?>

Resources/Private/Templates/News/List.html


<f:section name="content">
 ...
	<!-- Here comes the new field: -->	
	<h3>{newsItem.newField}</h3>
 ...
</f:section>

Resources/Private/Templates/News/Detail.html


<f:for each="{paginatedNews}" as="newsItem" iteration="iterator">
	<!-- Here comes the new field: -->				
	<h2>» {newsItem.newField}</h2>
	...
</f:for>

39 thoughts on “Die Extbase Extension „news“ um ein Feld erweitern

  1. Jochen

    Hallo Rüdiger,

    sorry, wenn ich dich nochmal belästige. Ich habe heute versucht, die fertige und funktionierende News-Erweiterung news_subheader auf meinem Produktivsystem zu installieren. Also aus der Entwicklungsumgebung heruntergeladen als zip-Datei, die entpackt und hochgeladen, anschließend im Produktivsystem installiert. Alles klappt soweit, nur wird das neue Feld einfach nicht ausgelesen. Übersehe ich da irgendwas?

    Danke im voraus
    Jochen

  2. Jochen

    Hi zusammen,

    ich bin ziemlicher Anfänger bei der Eytension-Programmierung und habe versucht die News um ein Untertitel-Feld news_subheader zu erweitern. Das klappt im Backend soweit ziemlich gut, das Feld ist im Reiter Erweitert drin, wenn ich dort was eintrage, wird es auch in der Datenbank im Feld news_subheader eingetragen. Die Templates werden auch korrekt verwendet, an den Stellen, an denen der Untertitel erscheinen soll, stehen die umgebenden Tags mit den von mir gesetzten CSS-Classes. Nur der Untertitel selbst steht da nicht. Ich vermute, dass ich die NewsDefault.php nicht richtig geschrieben habe, weil ich das mit dem Naming wohl nicht korrekt verstehe (wahrscheinlich eher gar nicht).

    Es wäre sehr freundlich, wenn mir jemand weiterhelfen könnte. Hier ist der Code meiner NewsDefault.php:
    newField = $news_subheader;
    }
    /**
    * Get new field
    *
    * @return string
    */
    public function getNewField() {
    return $this->newField;
    }
    }
    ?>

    • Jochen

      Sry, der Code ist scheinbar nicht komplett rüberkopiert worden, deshalb hier nochmal:

      namespace Jok\NewsSubheader\Domain\Model;

      class NewsDefault
      extends \GeorgRinger\News\Domain\Model\News
      {
      /**
      * the new field
      * @var string
      */
      protected $news_subheader;

      /**
      * Returns an array of orderings created from a given demand object.
      *
      * @param string $newField
      * @return void
      */
      public function setNewField($news_subheader) {
      $this->newField = $news_subheader;
      }
      /**
      * Get new field
      *
      * @return string
      */
      public function getNewField() {
      return $this->newField;
      }
      }

      • Rüdiger

        Hallo Jochen,
        mein neues Feld heisst „new_field“ und von daher auch alles was im Model darauf Bezug nimmt. Also die Member-Variable „newField“ und die Funktionen „getNewField()“ als auch „setNewField()“.
        Hast Du ein Feld „news_subheader“ musst Du natürlich auch die Namen entsprechend vergeben. Also „newsSubheader“ für die Member-Variable und „getNewsSubheader()“ als auch „setNewsSubheader()“ für die Funktionen.
        Stimmen die Namen nicht, können die Datenbankfelder nicht richtig zugeordnet werden.

    • Rüdiger

      Hi Frank,
      vermutlich stimmt etwas mit Deinem neuen Model nicht.
      Das kann bspw nur ein Schreibfehler in Dateiname, Klasse oder Mapping sein.
      Wird das Original-Model herangezogen, fehlt das Feld natürlich.

  3. Frank

    Zusatz: Mein vorangegangener Kommentar bezieht sich auf Typo3 7.6.2.
    Zusatzinfo: Wenn ich f:debug verwende, wird in news[0], news[1]…, also in den Arrays, die im Template in der for-Schleife zu jeweils ’newsItem‘ werden das neue Feld nicht ausgegeben. D.h. in meinem Fall existiert die Ganze Variable nicht im Frontend. Warum nur?

  4. Frank

    Hallo,

    ich habe das jetzt 3 mal von Null an exakt laut Anleitung umgesetzt:
    Neue Spalte wird in der db angelegt -> ok
    Neues Feld wird im Backend angezeigt und ist ausfüllbar (Listview und news-Admin) -> ok
    Im Backend eingegebener Feldinnhalt wird in der db gespeichert -> ok
    Inhalt im Frontend ausgeben -> FEHLER, keine Ausgabe

    Es hat ja bei vielen offensichtlich funktioniert und wenn es hing, dann meist hieran.
    Gibt es dazu noch einen Tipp, eine Hilfestellung zur Fehlersuche?
    Das wäre super!
    Vielen Dank auf jeden Fall für das Teilen dieser infos!!!

  5. Sebastian

    Hallo
    Ich bin dem Tutorial gefolgt kann aber im Backend beim editieren das neue Feld nicht in der News Administration sehen. Wie weis denn das Backend von tx_news das da neue Felder sind?

  6. vkr

    Hallo zusammen,

    ich bin auf dieses Tutorial gestoßen und habe bemerkt, dass es lange nicht mehr aktualisiert worden ist.

    Keine Änderungen
    ext_tables.sql
    Resources/Private/Language/locallang_db.xml
    Configuration/TypoScript/constants.txt

    Hier meine Änderungen (Typo3 6.2.13 & (Tx_)News 3.2.0):

    ext_tables.php
    \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addStaticFile($_EXTKEY, 'Configuration/TypoScript', 'VendorName: ExtensionName');
    Configuration/TypoScript/setup.txt
    config.tx_extbase {
    persistence {
    classes {
    GeorgRinger\News\Domain\Model\News {
    subclasses {
    0 = VendorName\News\Domain\Model\NewsDefault
    }
    }
    VendorName\News\Domain\Model\NewsDefault {
    mapping {
    recordType = 0
    tableName = tx_news_domain_model_news
    }
    }
    }
    }
    }

    Classes/Domain/Model/NewsDefault.php
    <?php
    namespace VendorName\News\Domain\Model;
    class NewsDefault extends \GeorgRinger\News\Domain\Model\NewsDefault {

    ext_autoload.php:
    $extensionPath . 'Classes/Domain/Model/NewsDefault.php',
    );

    So hat das Ganze bei mir funktioniert. Denkt bitte daran „VendorName“, „ExtensionName“ und „ext_name“ anzupassen – und achtet auch auf die lowerCamelCase und underscored Namen/Bezeichnungen. Ich hoffe es ist verständlich, habe leider erst vor kurzem mit Typo3 angefangen und weiss nicht, ob es einen besseren Weg gibt.

  7. sugi

    Hallo Harald,

    um den Wert vom neuen Feld im Frontend anzuzeigen, musst du {newsItem.newField} in news-Erweiterung „news/Resources/Private/Templates/News/Detail.html“ eingeben. Ich habe erstmals auch in der neuen Erweiterung {newsItem.newField} eingefügt, was nicht anzeigt. Muss wohl in news eingefügt werden. Verstehe ich irgendwie nicht, aber es funktioniert.

    VG,
    sugi

  8. Detlef Fluess

    Noch eine Frage:

    class Tx_TorrNewsExt_Domain_Model_NewsDefault
    extends Tx_News_Domain_Model_NewsDefault {

    Muss das nicht heißen:
    class Tx_TorrNewsExt_Domain_Model_NewsDefault
    extends Tx_News_Domain_Model_News {
    ??

  9. Detlef Fluess

    Auch von mir ein herzlichen Dank. Denn ich schlage mich nun schon länger mit einer Erweiterung der Feldern herum. Doch ein Problem bleibt:

    Ich habe es 1:1 nach Anleitung umgesetzt. Die neuen Felder sind im TCA und die Inhalte werden in die DB gespeichert. Auch im Template wird das neue Feld eingesetzt. Aber es wird ums verrecken nichts angezeigt. Wo kann das Problem liegen?
    Ich benutze TYPO3 6.2.6

    Viele Grüße, Detlef

  10. Sebastian

    Hallo Rüdiger,

    ich habe das selbe Problem wie Anne. Das Feld lässt sich im Frontend nicht ausgeben. Eine Idee woran das liegen könnte?

  11. Igor

    Hallo Rüdiger,

    vielen Dank für das lehrreiche Tutorial. Ich habe vor, unter TYPO3 6.2 die tx_news zu erweitern. Daher die Frage, ob es sich am Vorgehen, das Du beschrieben hast, etwas ändert?

    Viele Grüße
    Igor

  12. Michael

    Hallo Rüdiger,

    der Eintrag hier ist zwar schon etwas älter, dennoch hat er mir sehr geholfen. Danke dafür!

    Allerdings habe ich nun noch ein weiteres Problem.
    Und zwar kennt die news Extension ja verschiedene Typen (News, Internal Page, External Page). Wenn ich den Typ „External Page“ auswähle wird der Editor für den Bodytext ausgeblendet. In meinem RSS Feed möchte ich aber auch zu externen Seiten einen kleinen (über den Teasertext hinausgehenden) Text erstellen. Dafür müsste ich in meiner erweiterten News Extension die Werte im „types“ Feld des Arrays ändern. (Das Original liegt in der Original News Extension news/Configuration/Tca/news.php ca. Zeile 518ff)

    Hab ich die Möglichkeit diesen Wert nur für den Type 2 (external page) über ext_tables.php in meiner News Extension zu überschreiben?
    Ich steh hier grad echt auf dem Schlauch und habe keinen Schimmer wie ich das anstellen könnte.

    Viele Grüße,
    Michael

  13. Anne

    Herzlichen Dank für das Tutorial. Leider kann ich über das Template item.html (Partials) nicht das neuangelegte Feld ausgeben lassen. Es wird im Frontend nicht angezeigt. Im Backend ist das Feld sichtbar und kann beschrieben und gespeichert werden. Muss ich die neuen Felder für das Frontend noch bekanntgeben? Wo liegt mein Fehler?
    Herzlichen Dank, Anne

  14. Bernd Göbel

    Hallo Rüdiger,

    ich habe gerade meinen Fehler gefunden, jede Variable muss Kommentiert werden.
    /**
    * @var string
    */
    protected $fbDachzeile;
    /**
    * @var string
    */
    protected $fbAusgabe;

    Vielleicht hifts ja jemanden.

    Viele Grüße,

    Bernd

  15. Bernd Göbel

    Ertsmal Danke Rüdiger,

    ich habedie gleichen Probleme wie die anderen auch.
    Ein Feld klappt super, mehr als ein Feld führt zu der Fehlermeldung
    „Exception while property mapping at property path „“:Could not determine the child object type.“
    Alle Anleitungen die ich bis jetzt gefunden haben erweitern immer nur um ein Feld.

    Gibt es irgendwo eine Anleitung die mehr ale ein Feld hinzufügt?

    Viele Grüße,

    Bernd

  16. Das Problem beim Hinzufügen eines Feldes mit Fehlermeldung „#1251315967: Could not determine the child object type. (More information)“ ist vermutlich zurückzuführen auf:

    http://forge.typo3.org/issues/56603

    Ein Leeren von cf_extbase_reflection hat mir hier ebenfalls geholfen.

    Was zumindest mir nicht klar war ist, dass die Klasse ebenfalls in NewsDefault.php gespeichert werden muss, da sonst die Generierung der Dateien in typo3temp/Cache/Code/cache_phpcode nicht funktioniert.

  17. Devrim

    Hallo,

    vielen Dank für die Anleitung. Ich versuche in TYPO3 Version 6.1.7 neue Felder hinzufügen, aber ich bekomme Fehlermeldung, sobald es sich um mehr als ein Feld handelt. Wenn ich nur ein Feld hinzufüge, funktioniert alles ohne Problem. Was mache ich falsch? Muss ich auf irgendetwas achten, wenn ich mehrere Felder hinzufüge?

    Beste Grüße,

  18. Niklas

    Hallo,
    das Tutorial funktioniert grundsätzlich gut, allerdings bei mir nur genau in der oben beschriebenen Konfiguration. Will ich ein weiteres Feld hinzufügen „seminar_date“ und gebe das so NewsDefault.php an
    protected $seminarPlace;

    public function setSeminarPlace($seminarPlace) {
    $this->seminarPlace = $seminarPlace;
    }

    public function getSeminarPlace() {
    return $this->seminarPlace;
    }

    bekomme ich eine Fehlermeldung, sobald ich etwas in das Feld hineinschreibe.

    Genauer:

    Uncaught TYPO3 Exception
    #1251315967: Could not determine the child object type. (More information)

    TYPO3\CMS\Extbase\Persistence\Generic\Exception\UnexpectedTypeException thrown in file
    …/typo3/sysext/extbase/Classes/Persistence/Generic/Mapper/DataMapper.php in line 587.

    Ws mache ich da verkehrt?

    Beste Grüße
    Niklas

  19. Harald

    Hallo Rüdger,

    vielen dank für deine Anleitung. Leider funktionierts bei mir nicht. Das neue Feld wird im Backend angezeigt und man kann die eingetragen Werte werden auch in der Datenbank übernommen. Das neue Feld ist aber nicht im an das Fluid-Template übergeben Array {news} enthalten. Ich benutze Typo3 4.7 und news 2.1.0

    Was mache ich falsch?

    viele Grüße
    Harald

  20. Jan

    Hallo Rüdiger,

    vielen Dank für deine Hilfreiche Anleitung.
    Wie wäre denn der gedankliche Ansatz, wenn ich statt eines neuen Feldes eine eine weitere Controller Action hinzufügen möchte? Konkreter Hintergrund: Ich möchte eine randomAction hinzufügen, die eine zufällige News in der Detailansicht ausgibt.

    Vielen Dank für Deine/Eure Hilfe
    Jan

  21. Florian

    Danke für die tolle Anleitung. Weiß auch zufällig jemand, wie es geht, dass ich eben die List-Ansicht nach einem der neu hinzugefügten Felder sortieren lassen kann?

    Ich habe es jetzt so versucht, dass ich in meiner ext_tables.php meiner Erweiterung folgendes eingetragen habe:
    $GLOBALS['TYPO3_CONF_VARS']['EXT']['news']['orderByNews'] = 'tstamp,datetime,datefrom,dateto,price,crdate,title';

    So steht es zumindest in der Dokumentation der Extension. So bekomm ich die Felder (datefrom, dateto, price) meiner Extension zwar im Dropdown in der Plugin-Konfiguration im Backend, aber die Sortierung im Frontend ändert sich nicht.

    Wäre über Hilfe sehr dankbar!

  22. Rosario Torregrossa

    Hi Johannes

    Danke für dein Beispiel. Funktioniert einwandfrei. Ich hätte einen Frage. Wie sieht das ganze aus wenn ich z.b. relatedFiles erweitern will? Irgendwie hänge ich da.

    • ruediger

      Hi Rosario,
      wer ist Johannes? :)
      Also den IRRE-Datensatz „relatedFiles“, ja? Da das bei IRRE echte Datenbanktabellen sind … das gleiche Prozedere in den entsprechenden Konfigurationsdateien.
      Die Tabelle in diesem Fall wäre tx_news_domain_model_file.
      Grüße, Rüdiger

  23. Hallo und Danke für diese tolle Anleitung!
    Allerdings habe ich auch gleich ne Frage, vielleicht kannst Du ja helfen.
    Ich versuche nicht nur ein Feld einzufügen, sondern ganze Objekte. Dazu habe ich in meinem Modell:

    class \Enzephalon\Psoabilling\Domain\Model\News extends Tx_News_Domain_Model_NewsDefault{
    
      /**
       * @var \TYPO3\CMS\Extbase\Object\ObjectManagerInterface
       */
      protected $psoabilling;
    
      /**
    	 * The constructor.
    	 */
    	public function __construct() {
    		$this->psoabilling = $this->objectManager->get('EnzephaloN\\Psoabilling\\Domain\\Model\\Band');
    	}  
    
      /**
       * @param \TYPO3\CMS\Extbase\Object\ObjectManagerInterface $bands
       * @return void
       */
      public function setPsoabilling($psoabilling){
        $this->psoabilling = $psoabilling;
      }
      /**
       * @ \TYPO3\CMS\Extbase\Object\ObjectManagerInterface $bands
       */
      public function getPsoabilling(){
        return $this->psoabilling;
      }
    
    }
    

    Aber irgendwie funktioniert das so noch nicht. Hast Du eine Idee, wie ich das zum Laufen bekomme? Danke!

    • ruediger

      Hi Johannes,

      ein „ganzes Objekt“ wäre bspw ein IRRE-Feld (Typ „inline“) oder eine Verknüpfung zu einem Datensatz (Typ „select“). Dazu musst zu unter dem Stichwort TCA und Deinem Konfigurationswunsch googlen. Die TCA-Doku findest Du hier: http://docs.typo3.org/typo3cms/TCAReference/

      Wenn es sich um ein Set an Objekten handelt, musst Du es auch so kennzeichnen, in Deinem Fall

      \TYPO3\CMS\Extbase\Persistence\ObjectStorage<\EnzephaloN\Psoabilling\Domain\Model\Band>

      Falls es als nur ein Objekt konfiguriert ist, zumindest das richtige Model verwenden:

      \EnzephaloN\Psoabilling\Domain\Model\Band
  24. Manuel R.

    Hallo Rüdiger,
    danke für den Code! Hat mir viel gebracht!
    Eine Sache; Ich glaube an folgender Stelle fehlt ein Semikolon:
    public function setNewField($newField) {
    $this->newField = $newField ;;;;
    }

    Und noch eine Frage: Wie würdest du denn weitere Felder im Backend erstellen? Damit habe ich gerade einige Schwierigkeiten…

    Liebe Grüße,
    Manuel

Schreib einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind markiert *