Ein interessanter Artikel mit dem Vorschlag größere Schriftgrößen auf Webseiten zu verwenden.
16px body copy, anything less is a mistake
Da hat er Recht der Mann. Kleine Schriften haben auch den Nachteil, dass bei einer Webseitenbreite von 900px und einer Spalte die Zeilen viel zu lang zum Lesen sind. Lesen auf dem Bildschirm ist anstrengender als auf dem Papier, manche Seiten sind eh sehr textlastig und dann noch die kleinen Schriften.
Untertitel der Seite in TypoScript ausgeben mit Fallback auf Titel
Über einer Navigation in der linken Spalte soll der Titel der übergeordneten Seite aus Level 1 dargestellt werden. Da im Web keine Silbentrennung existiert, habe ich mir gedacht, dass das Wort inklusive Silbentrennung in den subtitle geschrieben wird. Wenn das Feld subtitle befüllt ist, dann soll statt titel der Inhalt von subtitle ausgegeben werden. Hier ist mein TypoScript:
lib.navigation.sub = COA lib.navigation.sub.10 = TEXT lib.navigation.sub.10 { data = levelfield: 1, title wrap = <h3>|</h3> override.required = 1 override.data = levelfield: 1, subtitle }
Eigenes Javascript vor dem der Extensions einbinden
Normalerweise inkludiert TYPO3 die JavaScript-Dateien in der Reihenfolge: zunächst was in den Extensions hinzugefügt wird, dann das was in page.includeJS definiert wurde und dann das, was über page.headerData hinzugefügt wurde. Man kann jedoch einzelne Dateien ganz an den Anfang dieser Kette setzen mit forceOnTop.
page.includeJS { jquery = fileadmin/path/to/jquery-1.6.2.min.js jquery.forceOnTop = 1 }
Zwiebelkuchen
Zutaten:
- 300g Mehl
- 80g Butter
- 1 kg Zwiebeln
- 6 Eier
- 250g Schinkenwürfel
- 1 Becher Schmand (200g)
Zubereitung:
Die Zwiebeln klein schneiden (das dauert ca. 30 Minuten) – mein Tipp: eine Schwimmbrille tragen, dann tränen die Augen nicht 😉 Die Zwiebeln salzen. Dann den Teil zubereiten: dazu die Butter in Stückchen in das Mehl geben, mit den Händen zu Teig verarbeiten, einen Löffel Wasser dazugeben. Der Teig im Kühlschrank ruhen lassen.
Backofen auf 200° vorheizen. Die Schinkenwürfen in einer Pfanne anbraten, Zwiebeln dazugeben. Eier mit Schmand verrühren, Salz, Pfeffer und etwas Muskat hinzugeben. Während die Zwiebeln abkühlen, den Boden einer Springform mit Backpapier auslegen und den Rand mit Butter einschmieren. Den Teig dünn zu einem großen Kreis ausrollen und in die Springform damit auslegen. Die Zwiebeln langsam in die Eiermasse geben und anschließend die Zwiebel-Eier-Masse in die Form geben. Ca. 30-40 Minuten backen.
Mühsame Installation von TYPO3 auf Localhost
Ich hatte die letzten zwei Mal schwierigkeiten die neueste TYPO3 Version 4.5.x auf Localhost (XAMPP) zu installieren. In XAMPP ist der Datenbank-User, der bereits eingerichtet ist root ohne Passwort. Solange man lokal arbeitet ist es ja auch in Ordnung. Im Install-Tool kann man das Feld Passwort nicht einfach frei lassen, da es erforderlich ist. Also überspringe ich den 1-2-3-Modus und will die Datenbankzugangsdaten selbst in localconf.php eingeben. Das funktioniert aber auch nicht – TYPO3 Install Tool meldet noch immer „Keine Verbindung zur Datenbank“. Ich versuche einen neuen Datenbank-Benutzer über phpMyAdmin anzulegen – mit Passwort – und trage die Daten dann in localconf.php ein. Immer noch kein Erfolg. Nachdem ich schließlich den Datenbank-Namen in die Konfigurationsdatei geschrieben habe und eine Fehlermeldung auftauchte „ADONewConnection: Unable to load database driver“, hatte ich zumindest eine Fehlermeldung, nach der ich Suchen konnte.
Meine Recherche ergab, dass die Fehlermeldung auftaucht, wenn die Extensions adodb und dbal installiert sind, aber nicht korrekt konfiguriert sind (Quelle jweiland.net). Da es aber eine ganz neue TYPO3 Installation ist, konnte ich noch keine Extensions manuell aktivieren, also ist das wohl die Standardkonfiguration. Um die Extensions zu deaktivieren, habe ich in der localconf.php in der Extension Liste (extList) den Eintrag dbal entfernt. Und siehe da, es funktioniert sofort und die Verbindung zur Datenbank steht.
Fehler im allgemeinen Validator an ein Feld hängen
(attach object errors to a specific field)
Es gibt die Möglichkeit in Extbase Validatoren für Objekte zu definieren. Wenn man also ein Model mit dem Namen „Domain_Model_ObjectModel“ hat, wird falls vorhanden der Validator mit dem Namen „Domain_Validator_ObjectValidator“. Dabei wird nachdem die einzelnen Felder geprüft wurden mit dem angegebenen Validator das komplette Objekt überprüft. So kann man wie in meinem Beispiel feststellen, ob der Titel bereits vergeben worden ist (Unique). Normalweise wird die Fehlermeldung bei einer nicht erfolgreichen Validierung an das Objekt drangehängt. Da ich die Fehlermeldungen neben dem Feld ausgebe (siehe dazu Fehlermeldung mit Fluid direkt neben dem Feld ausgeben), wollte ich den Fehler an das Attribut title dranhängen.
class Tx_MyExtension_Domain_Validator_ObjectValidator extends Tx_Extbase_Validation_Validator_AbstractValidator { /** * Check if there is a object with the same name * @param Tx_MyExtension_Domain_Model_Object $object * @return bool */ public function isValid($object) { $objectRepository = t3lib_div::makeInstance('Tx_MyExtension_Domain_Repository_ObjectRepository'); $sameNameCount = $objectRepository->countByTitleExcludeUid($object->getTitle(), $object->getUid()); if($sameNameCount > 0) { if (!isset($this->errors['title'])) { $this->errors['title'] = new Tx_Extbase_Validation_PropertyError('title'); } $error = new Tx_Extbase_Validation_Error(Tx_Extbase_Utility_Localization::translate('error.object_title_exists', 'MyExtension'), '1312448731'); $this->errors['title']->addErrors(array($error)); return FALSE; } return TRUE; } }
Fluid If-Condition und String-Vergleich
Leider kann der Fluid-ViewHelper keine Strings vergleichen. Ich habe ein wenig recherchiert und Lösungen gefunden.
Die erste ist ein eigener View Helper, der in der Lage ist, zwei Objekte (Strings z.B.) zu vergleichen.
<?php class Tx_MyExt_ViewHelpers_CompareViewHelper extends Tx_Fluid_Core_ViewHelper_AbstractViewHelper { /** * Returns true if $a and $b are type-equal, false otherwise. * * @param mixed $a * @param mixed $b * @return boolean */ public function render($a, $b) { return $a === $b; } } ?>
Dann soll es laut dem Eintrag so funktionieren:
<f:if condition="{myext:compare(a: 'foo', b: 'bar')}"> <f:then>...</f:then> <f:else>...</f:else> </f:if>
Leider hat es bei mir nicht funktioniert.
Aber der Vorschlag zwei hat hingegen funktioniert. Es wird mit Fluid ein Alias für den zu vergleichenden String defininiert und dann verglichen:
<f:alias map="{foobar: 'myString'}"> <f:if condition="{object.property} == {foobar}"><!-- do something --></f:if> </f:alias>
Weiter-Button in verschachtelten Tabs
In verschachtelten Tabs, die mit jQuery erstellt wurden, sollte eine Navigation mittels Weiter-Button umgesetzt werden. Für einfache Tabs habe ich einige Beispiele gefunden:
jQuery UI Tabs with Next/Previous oder jQuery Tabs Next Button. Allerdings sind in diesem Fall die Tabs verschachtelt. d.h. innerhalb von Tabs befinden sich wiederum Tabs: Tab A enthält Tabs A1, A2 und A3, Tab B enthält B1, B2 und B3 und C hat keine Subtabs. Wenn man also in A3 angekommen ist, sollte der Weiter-Button zu B1 verweisen. Weiterhin sollte die normale Tab-Navigation (also das Anklicken der Tab-Titel) weiterhin funktionieren. Wenn man also den Tab A2 auswählt, sollte der Weiter-Button immer noch auf A3 springen lassen.
<div id="tab"> <ul> <li><a href="#tab-a">A</a></li> <li><a href="#tab-b">B</a></li> <li><a href="#tab-c">C</a></li> </ul> <div id="tab-a"> <ul> <li><a href="#tab-a1">A1</a></li> <li><a href="#tab-a2">A2</a></li> <li><a href="#tab-a3">A3</a></li> </ul> <div id="a1"> Inhalt A1 </div> <div id="a2"> Inhalt A2 </div> <div id="a3"> Inhalt A3 </div> </div> <div id="tab-b"> <ul> <li><a href="#tab-b1">B1</a></li> <li><a href="#tab-b2">B2</a></li> <li><a href="#tab-b3">B3</a></li> </ul> </div> [... usw] </div>
Ich habe einen Button implementiert, der sich außerhalb der Tabs befindet. Damit eine Navigation möglich ist, müssen die Tab-Objekte gespeichert werden:
var $firstLevel = $('#tabs').tabs(); var counter = 0; $('#tabs .tabbed').each( function(index, elem) { var cid = $(elem).parent().attr('id'); tabObjects[counter] = $(elem).tabs(); counter++; });
Wenn der Weiter-Button geklickt wird, wird ermittelt, welcher Tab der ersten Ebene gerade aktiv ist. Falls es Tabs der zweiten Ebene gibt, wird ermittelt, welcher von denen gerade aktiv ist. Dann wird geprüft, ob auf den Tab der zweiten Ebene Geschwister-Elemente folgen. Wenn ja, dann wird der nächste aktiviert. Wenn nicht, dann wird der nächste Tab der ersten Ebene aktiviert.
$('#next-button a').click( function() { var selected = $firstLevel.tabs('option', 'selected'); var tabId = $('#tabs > div').eq(selected).attr('id'); $subTab = tabObjects[selected]; var length = $firstLevel.tabs('length'); if($subTab != undefined) { var subSelected = $subTab.tabs('option', 'selected'); var subLength = $subTab.tabs('length'); if(subSelected + 1 < subLength) { /* * switch to next tab */ $subTab.tabs('select', subSelected + 1); } else if(selected + 1 < length) { /* * switch no next parent tab */ $firstLevel.tabs('select', selected + 1); if(length == selected + 2) { $(this).hide(); } $subTab = tabObjects[selected + 1]; if($subTab != undefined) { $subTab.tabs('select', 0); } } } else { $firstLevel.tabs('select', selected + 1); } });
Step Choreos
Aufbau nach Split
Block A (symmetrisch):
Repeater + 2 Basic =>
Double Stomp, Mambo Chacha auf dem Boden, Turn Reverse, Basic (wird zu Kick bevor Teil 2 drangehängt wird)
Block B (assymetrisch):
Repeater + 2 Basic =>
Squat hold, Squat hold andere Seite, Kneelift, Double Stomp Tango Drehen auf dem Boden, Single Stomp
Block C (asym):
Kneelift + 3 Basic =>
2 March rauf, auf 3 öffnen, R Fuß ab, L ab Straddle, Box zurück, Basic
Block D (asym):
Repeater + 2 Knee =>
Stomp, Side Leg Lift (auf die andere Seite drehen), Stomp auf dem Boden, Chacha over zurück, Knee
Block E (asym):
Repeater + 2 Basic =>
Double Knee, Sixpoint hinten kreuzen, Mambo
Block F (asym):
3 Basic + 1 Knee =>
2 V-Step, Fersen vor, Flieger
jQuery: Tinyscrollbar innerhalb von Tabs
Wenn man das jQuery Plugin Tiny Scrollbar für Inhalte eines Tabs verwendet, dann wird die Höhe des Elements nicht korrekt berechnet und die Funktionalität nicht gesetzt. Eine Erklärung dafür gibt es auf der jQuery Tabs-Seite: der Tab-Inhalt ist versteckt, daher können die Dimensionen nicht berechnet werden.
Man kann den Tiny Scrollbar aber aktivieren, wenn der Tab (vorausgesetzt es ist nicht der erste und sichtbare) sichtbar wird.
$('#tabs').bind('tabsshow', function(event, ui) { if (ui.panel.id == "tab1") { $('#content1').tinyscrollbar(); } else if(ui.panel.id == "tab2") { $('#content2').tinyscrollbar(); } });
Neueste Kommentare