Typo3 Extension Manager zeigt nur drei Punkte ‘…’ statt den Icons zum Installieren und Entfernen

Nachdem ich kürzlich meinen Firefox auf Version 12 geupdatet habe, stellte ich heute fest, dass ich im Typo3 Extension Manager keine Extensions mehr installieren und entfernen konnte. Nach stundenlanger Suche stellte ich fest, dass die Icons im Prinzip noch da sind, nur durch eine falsche Margin-Angabe außerhalb des sichtbaren Bereichs katapultiert werden. Es scheint wohl mit einem Bug der neusten Version des Extension Managers zusammenzuhängen. Näheres zu diesem Bug steht hier:
http://forge.typo3.org/issues/30900

Workaround (von Stefan Sorgen):
In typo3/sysext/em/res/css/t3_em.css, Zeile 283 ff. ändern von

.paddingNoActionIcon img {
    margin-right: 20px;
}

in

.paddingNoActionIcon img {
    margin-right: 5px;
}

Wenn Fluid-Variablen im Frontend nicht ausgegeben werden

Ein blöder Fehler, den ich von Zeit zu Zeit immer wieder reinrenne. Eine Fluid-Variable wird im Frontend einfach nicht ausgegeben, als wäre die Variable gar nicht bekannt. Dabei ist doch der Variablen-Name vollkommen richtig geschrieben und die Variable auch in der Controller-Action mit dem assign-Befehl and die View überbegeben worden.

Lösung: Einfach mal alle <f:render …>-Tags durchgehen, ob nicht irgendwo vergessen worden ist, die Variable auch an das Partial übergeben worden ist.

By the way: Irgenwie gefällt mir das bei Rails besser, wo man neue Variablen einfach als Instanzvariablen der Controller-Klasse deklarieren und dadurch sofort für das zu rendernde Template sowie alle dessen inkludierte Partials sichtbar machen kann. Dann kann man so einen Vergesslichkeitsfehler wie diesen gleich vermeiden.

Backend templateRoot Pfad in Extbase nicht erkannt

Wo ich gerade fix mit dem Extension Builder in Extbase eine neue Extension gebaut habe, ist es doch sehr interessant, das für das Backend-Modul die Views in Ressources/Private/Backend, also die Layouts, Partials und Templates für das Backend, nicht erkannt werden, sondern stattdessen die normalen Views aus Ressources/Private des Frontends verwendet werden. Dabei werden die Unterschiedlichen Pfade doch in Configuration/TypoScript/constants.txt definiert und in Configuration/TypoScript/setup.txt verwendet.

Nach ewas Sucherei habe ich die Lösung schließlich in http://www.typo3forum.net/forum/extension-modifizieren-neu-erstellen/51435-extbase-fluid-rootpaths.html gefunden: Es ist kein Programmierfehler, sondern das TypoScript dieser Extension muss nur in einem Template der Seiten einmal als ‘Include Static’ eingebunden werden. das wirkt sich dann nicht nur für das Frontend, sondern interessanterweise auch für das Backend-Modul aus … und schon läuft alles!

Bug in Prototype 1.7 mit Scriptaculous Draggables

Interessant, Protoype 1.7 ist nun schon eine ganze Weile draußen und enthält einen Fehler in Verbindung mit Scriptaculous Draggables, der bis heute nicht gefixt worden ist. Wenn man ein Draggable mit ghosting per Drag and Drop verschiebt und loslässt, bleibt es mit “position: absolute” formatiert und erscheint dadurch an einer völlig anderen Stelle als erwartet. Abhilfe schafft ein kleiner Workaround in der prototype.js, den ich hier gefunden habe: In Zeile 3797 einfach
, position: element.getStyle('position')
am Ende ergänzen.

Automatisches Persistieren in Extbase

Ja, ja, wie das so ist, wenn man seit Jahren mit Ruby on Rails arbeitet und es zum MVC-Framework schlechthin kührt, dann rennt man beim Arbeiten mit anderen MVC-Frameworks nicht nur in jede Menge Stolperfallen rein, wo diese anders funktionieren, sondern begegnet diesen Abweichungen auch mit äußerstem Unverständnis. So geht es mir jedenfalls bei der Extension-Entwicklung mit Extbase.

Mit Erstaunen stellte ich gerade erst fest, dass Extbase nach Ende einer Controller-Action die Datenbank-Modelle, die man sich aus einem Repository-Objekt geholt hat, automatisch speichert, … also nicht erst, wenn man die update()-Methode aufgerufen hat, sondern auch so voll automatisch. Ein Verhalten, dass ich am liebsten abstellen würde, da ich es aus Rails gewohnt bin, die Objekte selber mit der save()-Methode zu persistieren. Erst recht ist dieses Verhalten blöd, wenn man die Änderungen nur temporär vornehmen und noch gar nicht speichern möchte. Um dies zu erreichen, muss man ein Objekt, nachdem man es aus dem Repository geholt hat, einfach nur mit dem clone-Befehl klonen und mit dem Klon weiterarbeiten, wie ich herausgefunden habe.

Deutsche Pluralisierungen in Rails

Rails nimmt ja die Pluralisierung bzw. Singularisierung von Model-Namen automatisch vor. Die funktioniert auch vorzüglich … zumindest in Englisch!!! Blöd nur, wenn man deutsche Model-Namen verwenden möchte. Das führt dann zu so herrlich falschen Pluralisierungen wie “Kategories” oder “Lieferungs”. Die Absicht, trotzdem deutsche Namen zu verwenden und nicht alles ins Englische zu übersetzten, finde ich aber durchaus legitim. So hat man gemäß der objektorientierten Programmierung Namen für Modelle, die man als den realen Objekten leichter zuordnen kann als wenn man sie ins englische übersetzt (z.B. “Lastschrift” statt “Direct Debit”). Außdem erhält man gleich deuschte Begriffe in den URLs, die sich der Benutzer besser merken kann und eventuell auch für Suchmaschinenoptimierung interessant sein könnte.

Die Regeln für Pluralisierung lassen sich in config/initializers/inflections.rb angeben. Dort hat man für deutsche Übersetzungen grundsätzlich zunächst mal die Möglichkeit, die Pluralisierung für einen Namen als Unregelmäßigkeit anzugeben:

inflect.irregular 'boot', 'boote'

Eleganter ist es natürlich, allgemeine Regeln für die Pluralisierung anzugeben, um nicht für jedes neue Model eine neue Regel definieren zu müssen. Leider ist Pluralisierung im deutschen nicht ganz so einfach und so regelmäßig wie im englischen. Ich haben mir trotzdem mal die Mühen gemacht und versucht, einige dieser Regeln in regulären Ausdrücken aufzuschreiben. Sicherlich sind diese noch ausbaufähig, aber ca. 60-70% der Pluralisierungen werden hiernach schon mal richtig gebildet:

ActiveSupport::Inflector.inflections do |inflect|
inflect.plural /(e)$/i, '\1n'
inflect.singular /([a-fh-z]*e)n$/i, '\1'
inflect.plural /([abcdfhijklmnpqrstuvwxyz]{1})$/i, '\1e'
inflect.singular /([abcdfhijklmnpqrstuvwxyz]{1})e$/i, '\1'
inflect.plural /(o)$/i, '\1s'
inflect.singular /^([a-zA-Z]*o)s$/i, '\1'
inflect.plural /(ung)$/i, '\1en'
inflect.singular /(ung)en$/i, '\1'

inflect.irregular 'haus', 'haeuser'
inflect.uncountable %w( benutzer )
end