Kunterbuntes TER

Mittwoch, 26. Oktober 2011

Aktuell gibt es über 5300 Extensions im TER (TYPO3 Extension Repository), viele davon sind schon sehr alt, manche davon funktionieren schon gar nicht mehr mit der aktuellen TYPO3 Version, andere sind auf sehr spezielle Einsatzzwecke ausgerichtet, viele haben keine oder fehlerhafte Dokumentation (die Umwandlung von dem sxw-Dokument in HTML klappt nicht immer), so dass man deren Nutzen nur schwer erkennen kann.

Ich möchte in diesem Beitrag auf die (wenigen) “schlechten”, die unprofessionellen und zweifelhaften Erweiterungen eingehen; Extensions, die doppelt vorhanden oder unnötig sind – also ein wenig “Extension-Bashing” betreiben. Sei mir nicht böse, wenn eine deiner TYPO3-Erweiterungen darunter ist. Ich möchte keinen an den (Internet-)Pranger stellen. Wer sich dennoch an mir Rächen möchte: in einer meiner fast 20 TYPO3-Erweiterungen finden sich bestimmt auch Fehler ;-)

Extensions mit sehr geringem Umfang

Es mag zwar Erweiterungen geben, die trotz ihres geringen Umfangs durchaus eine Daseinsberechtigung haben, wie z.B. die Erweiterungen example_bepreview, pagenotfound_handler, hyphenator, ka_browserexclusion, langfeautoconfig, indexedsearch_icons oder das beliebte rgaccordion, doch die Extension cs_multiline_page_header ist mir negativ aufgefallen: Diese Erweiterung ermöglicht einen mehrzeiligen Seitentitel und wandelt dafür das Eingabefeld für den Seitentitel in eine Textarea um. Die eine(!) Zeile TCA-Konfiguration, aus der die Extension besteht, schreibt man besser in die Datei “typo3conf/extTables.php”. Ok, ich habe untertrieben, seit der neuesten Version (mittlerweile gab es immerhin 5 Updates der Erweiterung im TER) unterstützt die Extension mehrsprachige Webseiten und hat damit noch eine zusätzliche Zeile TCA-Konfiguration bekommen. Dafür braucht es aber beim besten Willen keine eigene Extension, die das ganze TYPO3-System unübersichtlicher macht und verlangsamt (nur ein kleines bisschen natürlich, aber das summiert sich).

Ähnlich verhält es sich mit den Erweiterungen googleverify und alexa, die lediglich den Verification-Code in den Head-Bereich einer Webseite setzen. Oder mjj_t3quixplorer und mjj_phpmyadmin, die ebenfalls nur aus einer Zeile PHP-Code bestehen. In die gleiche Kategorie lässt sich die Extension cm_pngfix einordnen, die lediglich aus wenigen Zeilen TypoScript- und PHP-Code besteht. Die Funktion der Extension, nämlich halbtransparente PNGs im IE6 zu ermöglichen, lässt mit drei Zeilen TypoScript-Code umsetzen – ganz ohne PHP!

Neidisch blicke ich auf die Extension contentwrapper: Diese wurde schon über 2400 mal heruntergeladen! Dabei besteht sie nur aus ein wenig TypoScript und CSS, damit ein Redakteur seine Inhaltselemente in farbige Boxen setzen kann. Auch hierfür ist eine Extension zu “überdimensioniert”, die knapp zwei Dutzend Zeilen TypoScript Code schreibt man besser zu der allgemeinen TypoScript Konfiguration der Seite.

Was meint ihr? Macht es Sinn, für jede Kleinigkeit eine TYPO3 Erweiterung zu erstellen? Ein Vorteil davon ist sicherlich, dass auch Nicht-Entwickler diese nutzen können.

Extension-Raub

Unverschämt sind Entwickler, die eine bestehende Extension dublizieren und als eigene ausgeben: So basiert die Erweiterung cm_downloads auf (einer älteren Version von) sb_downloader. Oder die Erweiterung cl_metatags auf der Erweiterung metatags. Die Unterschiede sind minimal, 99% des Codes stammt von der originalen Erweiterung. Ich finde das frech, eine Erweiterung, die ein Entwickler in vielen Stunden mühsam erstellt hat, einfach zu kopieren und als seine eigene Kreation auszugeben. Natürlich kann man Erweiterungen für seine Bedürfnisse anpassen, diese sollte man dann aber nicht ins TER hochladen oder zumindest auf den ursprünglichen Entwickler hinweisen. Bei dieser Vorgehensweise sehe ich auch noch ein Problem bei Sicherheitslücken, die in der ursprünglichen Extension entdeckt wird – ob diese auch in das Dublikat übernommen wird, ist fraglich.

Auch der Autor der Extension enter_new_weeaar_googlesitemap hält es nicht für nötig, auf den ursprünglichen Entwickler hinzuweisen bzw. was seine Gründe für sein Erweiterung sind. Diese Erweiterung ist eine 1:1-Kopie von weeaar_googlesitemap, mit nur minimalen Änderungen im PHP-Code des Plugins. enter_new_weeaar_googlesitemap hat eine kuriose Besonderheit: Um sie nutzen zu können, muss man sie in “weeaar_googlesitemap” umbenennen.

Kuriositäten

Wieso der Entwickler der Extension linkstats und linkclickcounter diese doppelt im TER hat, erschließt sich mir nicht wirklich. Hat ihm der Extension-Key nicht gefallen? Kleiner Tipp: Es gibt die Möglichkeit, Erweiterungen als “obsolete” zu kennzeichen.

Der Autor der Extension bsd_tmplselect lernt sich wohl gerade in TYPO3 ein und möchte uns an seinem Lernprozess teilhaben. Interessant sind dabei auch seine Upload-Kommentare.

Ganz eindeutig in die Jux-Kategorie gehört die Extension terbingo – diese fordert bei der Installation eine weitere, zufällig gewählte Extension aus dem TER an. Ohne den “großen Bruder” terbingohelper funktioniert diese Extension erst gar nicht.

Thema: Allgemein, Ärgernisse, Sonstiges, TYPO3, TYPO3 Extensions | Kommentare (2)

TYPO3: Verschiedene Seiten-Templates mit Fluid und BE Layout

Donnerstag, 26. Mai 2011

Mit der Fluid Template Engine (ab TYPO3 Version 4.3) und dem Backend Layout (ab TYPO3 Version 4.5) kann man mit wenig Aufwand dem Redakteur verschiedene Seiten-Layouts zur Auswahl anbieten, die er über eine Select-Box in den Seiteneigenschaften einer Seite wählen kann (siehe Abbildung).

Das macht Erweiterungen wie z.B. rlmp_tmplselector unnötig. Hier die Schritt-für-Schritt-Anleitung für die Einrichtung und Konfiguration der Seiten-Templates:

1) Backend Layout anlegen

Backend Layouts legt man als Datensätze in einem beliebigen SysFolder ab. Die Erstellung ist sehr einfach, TYPO3 stellt dafür in dem Datensatz einen Wizard zur Verfügung, hier am Beispiel eines einfachen zwei-spaltigen Layouts:

Als “Spaltennummer” wird eine Zahl vergeben. Diese wird weiter unten verwendet, um den Inhalt einzulesen. Meistens benötigt man als Seiten-Layout ein 1-spaltiges, ein 2-spaltiges und eines, das nur den Seiten-Inhalt (ohne Header, Footer, Randspalten usw.) ausgibt, z.B. für Popups oder Lightboxen.

2) HTML-Templates erstellen

Als nächstes legt man die HTML-Templates für die Seiten-Layouts an. Ich habe dabei folgende Struktur vorliegen:

fileadmin/templates/fluid/ für die Seiten-Templates
fileadmin/templates/fluid/layouts/ für die Templates, welche die grobe Struktur der Seite vorgeben (Rahmen-Layout)
fileadmin/templates/fluid/partials/ für die Templates, die Seiten-Teile enthalten (z.B. Subnavigationen oder den Kopfbereich). Diese Seiten-Teile können in unterschiedlichen Layouts oder Seiten-Templates eingebunden werden. In diesem Beispiel-Setup werden diese aber nicht benötigt.

fileadmin/templates/fluid/layouts/default.html

<div id="header">...</div>
<div id="content">
  <f:render section="content" />
</div>
<div id="footer">...</div>

fileadmin/templates/fluid/1col.html

<f:layout name="default" />
<f:section name="content">
  <div id="content_main">
    <f:format.html>{content}</f:format.html>
  </div>
</f:section>

fileadmin/templates/fluid/2col.html

<f:layout name="default" />
<f:section name="content">
  <div id="content_main">
    <f:format.html>{content}</f:format.html>
  </div>
  <div id="content_left">
    <f:format.html>{content_left}</f:format.html>
  </div>
</f:section>

fileadmin/templates/fluid/popup.html

<div id="content">
  <f:format.html>{content}</f:format.html>
</div>

Hinweis: Bei mir gab es Probleme mit dem Rendering. Standardmäßig jagt Fluid den Content durch die Rendering-Funktion “parseFunc” mit den Einstellungen von “lib.parseFunc_RTE”. Allerdings ist in diesen Einstellungen keine iframes, Formulare usw. vorgesehen (diese kann man und soll man über den RTE gar nicht einpflegen), so dass die Tags <iframe> und <form> sichtbar auf der Seite ausgegeben werden. Um das zu verhindern, gibt es mehrere Lösungen:

1) Verwendung von “f:format.raw” (Fluid Version > 1.3.0):

<f:format.raw>{content}</f:format.raw>

2) TypoScript-Objekt direkt einbinden:

<f:cObject typoscriptObjectPath="lib.content" />

Und in TypoScript:

lib.content < styles.content.get

3) Ein nicht existierendes Rendering-Setup angeben, z.B. lib.parseFunc_FLUID:

<f:format.html parseFuncTSPath="lib.parseFunc_FLUID">{content}</f:format.html>

Lösung 1 und 2 ist von marcoseiler.de

3) TypoScript Konfiguration

Allgemeine Konfiguration und Zuweisung der Platzhalter

TS Setup

page.10 = FLUIDTEMPLATE
page.10 {
  partialRootPath = fileadmin/templates/fluid/partials/
  layoutRootPath = fileadmin/templates/fluid/layouts/
  variables {
    content < styles.content.get
    content_left < styles.content.get
    content_left.select.where = colPos=1
  }
}

In die Platzhalter “content” und “content_left” werden nun die Inhalte eingelesen, die vom Redakteur im Backend in den entsprechenden Spalten angelegt wurde. Gei “content_left” lesen wir die Inhalte aus “Spaltennummer” 1 ein, also die Inhalte aus Spalte “Linker Rand”, die weiter oben im Backend Layout definiert wurde.

Zuweisung BE Layout zu HTML-Template

Je nachdem, welches Backend Layout in den Seiteneigenschaften ausgewählt wurde, sollte ein anderes Seiten-Template verwendet werden. Dies geschieht mit diesen TypoScript-Anweisungen:

TS Setup

page.10.file.stdWrap.cObject = CASE
page.10.file.stdWrap.cObject {
  key.data = levelfield:-1, backend_layout_next_level, slide
  key.override.field = backend_layout
  default = TEXT
  default.value = fileadmin/templates/fluid/2cols.html
  2 = TEXT
  2.value = fileadmin/templates/fluid/1col.html
  3 = TEXT
  3.value = fileadmin/templates/fluid/popup.html
}

Standardmäßig wird dabei das 2-Spalten-Layout verwendet (dieses sollte deshalb auch auf der Root-Seite in zwei Select-Boxen für das Backend-Layout ausgewählt werden). Die Templates werden über die IDs der Backend-Layouts zugewiesen. In meinem Fall hat das 1-spaltige Backend-Layout die ID 2, das Popup-Backend-Layout die ID 3.

Optional: body-Tag mit Klasse auszeichnen

Für das Layout ist es oft nötig, dass man in CSS weiß, welches Layout aktuell gewählt ist. Deshalb kann man dem body-Tag je nach gewählten Layout eine andere Klasse geben:

TS Setup

page.bodyTagCObject = COA
page.bodyTagCObject {
  10 = COA
  10.stdWrap.dataWrap = !!<=|>
  10.20 = CASE
  10.20 {
    key.data = levelfield:-1, backend_layout_next_level, slide
    key.override.field = backend_layout
    default = TEXT
    default.value = layout-2col
    2 = TEXT
    2.value = layout-1col
    3 = TEXT
    3.value = layout-popup
  }
}

Thema: TYPO3, Web Entwicklung | Kommentare (5)

PHP: Zufällige Werte aus einem Array auslesen mit mt_rand

Montag, 9. Mai 2011

Mit der Funktion “array_rand” hatte ich bei der Generierung eines 6-stelligen, eindeutigen Codes (aus einem Array mit ca. 30 möglichen Werten) Probleme, die Funktion hat immer ähnliche Kombinationen aus dem Array zurückgegeben. php.net schreibt dazu:

Viele Zufallszahlengeneratoren, die auf älteren libc-Versionen basieren, haben seltsame oder doch zumindest unerwartete Verhaltensweisen und sind zudem recht langsam.

Vorteil der Nutzung von “mt_rand” ist außerdem, dass diese Funktion die Zufallszahlen ca. 4mal schneller generiert.

Deshalb hier die “array_rand”-Funktion nachgebaut mit “mt_rand”:

/**
 * Pick one or more random entries out of an array. Alternative for function "array_rand", uses the better function "mt_rand"
 *
 * @param array $input: The input array.
 * @param integer $num_req: Specifies how many entries you want to pick.
 * @return mixed: If you are picking only one entry, array_rand returns the key for a random entry. Otherwise, it returns an array of keys for the random entries. This is done so that you can pick random keys as well as values out of the array.
 */
public static function array_mt_rand($input, $num_req = 1) {
  // check parameters
  if(!is_array($input) || $num_req < 1 || count($input) < $num_req) {
    return NULL;
  }
 
  // define needed vars
  $randomKeys = array();
  $result = array();
 
  // get some random numbers
  $arraySize = count($input) - 1;
  for($i = 0; $i < $num_req; $i++) {
    do {
      $randomNumber = mt_rand(0, $arraySize);
    } while(in_array($randomNumber, $randomKeys));
    $randomKeys[] = $randomNumber;
  }
 
  // get the array keys
  $index = 0;
  foreach($input as $key => $val) {
    if(in_array($index, $randomKeys)) {
      array_push($result, $key);
    }
    $index++;
  }
  return count($result) == 1 ? array_shift($result) : $result;
}

Thema: PHP, Web Entwicklung | Keine Kommentare

TYPO3: Extensions für tt_news

Donnerstag, 24. März 2011

tt_news ist zwar nicht sehr sauber programmiert, aber es ist sehr flexibel einsetzbar. Außerdem gibt es dutzende Erweiterungen für tt_news, so dass sich ganz neue Anwendungsgebiete eröffnen:

Frontend

  • rgmediaimagesttnews Ermöglicht mp3s (z.B. für Podcasts), Videos und iframes für News.
  • rgnewsce Erlaubt normale Content-Elemente in News-Datensätzen. cool!
  • ttnews_irre siehe rgnewsce
  • aba_ttnews_content_con Erlaubt tt_content in News Details.
  • pagebrowse_tt_news Ersetzt tt_news-Pagebrowser durch Ext. pagebrowse
  • tweet_and_like Stellt Twitter Tweet-Button (kürzt URL über bit.ly-API) und Facebook Like-Button (als iframe) zur Verfügung.
  • googleplusonettnews Google’s Plus One Button
  • news2facebook Fügt Open Graph Meta Tags auf News-Detailseite ein. Im News-Datensatz kann über den neuen Reiter “Facebook-Meta” z.B. der Titel, Beschreibungstext oder das Bild angegeben werden, das für die Facebook-Share-Funktion verwendet wird.
  • mail2news Importiert E-Mails von einer bestimmten E-Mail-Adresse als News-Datensätze.
  • lonewsdownloads Erweitert Datei-Downloads für tt_news (Icon und Dateigröße), konfigurierbar über TypoScript.
  • lonewsaddress Stellt neuen Reiter (Felder u.a. PLZ, Stadt, URL, Telefon, Längen- und Breitengrad, Map-Kategorie) für News-Datensatz zur Verfügung. Karte kann auf News-Detailseite ausgegeben werden. Demo verfügbar: http://magenband-op.info/krankenhaus-magenband/klinik/arzt-magenband-berlin.html
  • ttnews_share Social Bookmark Links für News-Datensätze, ähnlich timtab_sociable oder sp_socialbookmarks. In einem BE Modul kann ausgewählt werden, welche Dienste ausgegeben werden.
  • sp_newsteaserbox Aufwändige Präsentation der zuletzt eingestellten News: Teaser-Bild, darüber in einem Reiter weitere News. Bei Klick auf Reiter wird Teaser-Bild geladen. Reiter schalten selbstständig alle x Sekunden weiter. Verwendet jQuery, Fallback wenn kein JavaScript verfügbar, bietet eigenes Plugin.
  • yag_ttnews Integriert die umfangreiche Bildergalerie-Extension yag in News. Einfache Auswahl der Bildergalerie über News-Datensatz.
  • newscalendar Kalender für tt_news.
  • ttnews_calendar Kalender für tt_news
  • nc_ttnews_mostpopular Zählt Aufrufe von tt_news-Detailseiten mit; man kann die am häufigsten aufgerufenen News auflisten.
  • readnews Zeigt an, ob eine News von dem eingeloggten FE-User bereits gelesen wurde. cool!
  • newsbreadcrump Zusätzlicher Marker, der Breadcumb-Pfad anzeigt.
  • ttnews_marker The Extension tt_news marker enables to substitute any marker in the HTML template of tt_news. Any Marker has the std_wrap property. There are special markers for a link and counting.
    obsolete (integriert in tt_news ab Version 3.0.0)
  • ttnewstags Stichpunkte aus Feld “Keywords” werden im Frontend ausgegeben und (optional) mit der Suche verlinkt (sehr sinnvoll für Blogs).
  • newssignificance tt_news werden nach Wichtigkeit markiert und im Frontend ausgegeben.
  • sysfire_ttnewsrating Bewertung für tt_news durch den Redakteur über das BE und Ausgabe im FE.
  • bz_sitemap Sitemap, die auch News-Artikel anzeigt.
  • xw_ttnewsarchiver Bestimmte Anzahl von News sind immer sichtbar, der Rest wird archiviert.
  • allnews Gibt alle vorhandenen News aus, auch die, deren “starttime” noch nicht erreicht ist.
    obsolete:
    dafür gibt es die TypoScript-Einstellung “ignoreEnableFields”
  • hp_tt_news_catmenu Gibt Kategorie-Menü als unsortierte Liste aus.
  • marker Man kann News-Datensätze bookmarken und in einem Bookmark-Center verwalten.
  • jf_easymaps Google Maps für News durch Eingabe von Straße, Stadt, Land. Schlecht: Gibt Google Map über eigenes Plugin aus, anstatt einen Marker für das News-Template bereitzustellen. Api Key muss in jedem Plugin eingegeben werden, anstatt einmalig über die Extension Manager Konfiguration oder über TypoScript. Hat etliche Bugs.
  • evo_news_sorting News-Auflistung läßt sich von Benutzer anhand Titel, Datum und anderen Daten sortieren (auf- und absteigend), Anzahl der anzuzeigenden News kann definiert werden.
  • rgnewslinks Zwei Links in Single-Ansicht einer News, um zur nächsten bzw zur vorherigen News zu schalten.Ist gegenüber “nextprevious” zu bevorzugen, da es mehr Konfigurationsmöglichkeiten gibt, die Extension ist aktueller und hat eine Doku.
    obsolete (integriert in tt_news ab Version 3.0.0, Konfiguration über nextPrevRecSortingField und weitere TypoScript-Anweisungen)
  • nextprevious Zwei Links in Single-Ansicht einer News, um zur nächsten bzw zur vorherigen News zu schalten.
    obsolete (integriert in tt_news ab Version 3.0.0)
  • custom_ttnews_singlepid Detailseite für News kann anhand verschiedener Parameter bestimmt werden, z.B. des News-SysFolders. D.h. verschiedene News in einer Liste können unterschiedliche Detailseiten haben.
  • mc_podcast Stellt mp3-Player in News zur Verfügung.
    Schlecht: XClass für tt_news, letzte Aktualisierung 2006
  • elemente_fenews Frontend Editing für News-Datensätze, mit RTE, Kategorie-Auswahl und Bild-Upload.
  • ttnews_glossary Glossar für News-Datensätze, sehr flexibel.
  • ttnews_ajaxpagebrowser Beim Blättern über Pagebrowser werden die News per Ajax nachgeladen.
  • mbl_newsevent News nutzbar als Veranstaltungen: Zusatzinfos (Event, Ort, Preis, Registrierung) für News-Datensatz; stellt Ansichten für Events zur Verfügung; Anmeldung für Events möglich (z.B. mit powermail)
  • dw_ttnews_protect News können über Checkbox als “geschützt” markiert werden. Diese News können nicht in der Detailansicht geöffnet werden, in der Listen-/Latest-Ansicht fehlt der mehr-Link.
  • tnm_ttnewsfaq Nutzung von tt_news-Datensätzen als FAQ, Ausgabe erfolgt über eigenes Plugin. Effekte mit jQuery oder mootools. Kaum Konfiguration im Plugin oder über TypoScript möglich, komplettes(!) Templating erfolgt über TypoScript
  • t3s_newsslider Slider und Ticker für News, nutzt jQuery | Demo

Backend

  • mpossnewssorting tt_news-Datensätze können im Backend sortiert werden (so wie bei anderen Datensätzen). Sinnvoll, wenn man tt_news für etwas anderes als News nutzt.
    Schlecht: Da das Flexform für FE-Plugins nicht erweitert werden kann, stellt die Ext. die Flexform für tt_news komplett neu zur Verfügung.
    Lösung: Einbindung von Flexform deaktivieren, Sortierung über TypoScript: plugin.tt_news.listOrderBy = sorting ASC.
  • ics_newssorting Wie mpossnewssorting, das Feld “listOrderBy” wird auch per FlexForm eingebunden, aber nicht die komplette FlexForm wird ersetzt, sondern nur dieses eine Feld (die FlexForm wird mit der tt_news FlexForm über ein PHP Skript gemerged).
  • lab_newsfolders News-Kategorien können Seiten zugeordnet werden (über Seiteneigenschaften). News erhalten dann die Kategorie von der Seite, in der sie sich befindet. Nutzt TYPO3-Hook. Seite muss vom Typ “News SysFolder” sein.
  • chnewssort Stellt BE-Modul zur Verfügung, in dem man erkennen kann, welche News ein Plugin auf der Seite im FE ausgibt. Sortierung der News kann über das Modul geändert werden.
    Schlecht: Liest News selbst aus DB aus, d.h. Funktionsweise ist bei neuer tt_news-Version nicht gewährleistet.
  • ods_update_page Automatisches Leeren des Cache der Seiten mit tt_news-Plugin, wenn neue News-Datensätze hinzukommen.
    Alternative: Verwendung des TypoScript-Befehls “clearCacheCmd”.
  • ods_newsfilter Stellt neue Filter zur Verfügung.
    Schlecht: Überschreibt Flexform

RSS

  • chnewsfeeds Man kann RSS-Feed sehr einfach über Plugin konfigurieren: Felder für “Titel”, “Beschreibung” und “News Kategorien” sind vorhanden.
  • advanced_sitemaps Gibt tt_news-Datensätze als XML-Sitemap aus, z.B. für Google News. Siehe auch Artikel zu Sitemaps
  • ttnews_feeder Importiert News aus Suchmaschinen oder normalen HTML-Seiten. Sinnvoll, wenn eine Webseite keinen RSS-Feed bietet.
  • xml_ttnews_import Liest RSS / XML Feeds als tt_news-Datensätze ein.
  • newsfeedimport Liest RSS2 / Atom Feeds als tt_news-Datensätze ein.

Weitere

  • ttnewscache Verbessert Caching von News; sinnvoll, wenn man viele hunderte von News hat, siehe http://forge.typo3.org/wiki/extension-ttnewscache
  • ttnews_selectconf Einfache Extension, die mittels TypoScript die Manipulation der Datenbank-Abfrage von tt_news über einen Hook erlaubt. Umfangreiche Doku.

Thema: TYPO3, TYPO3 Extensions | Kommentare (7)

TYPO3: Meta Keywords und Description

Mittwoch, 2. März 2011

Für die Ausgabe von Meta-Tags im Quellcode einer TYPO3 Webseite gibt es verschiedene Möglichkeiten, die ich hier vorstellen möchte. Ein Meta-Tag wird von TYPO3 bereits automatisch gesetzt: <meta name=”generator” content=”TYPO3 4.4 CMS” />. Um die Ausgabe aller anderer Meta-Tags muss man sich selbst kümmern

Die – meiner Meinung nach – beste Lösung ist das Setzen der Meta-Tags über die TypoScript-Einstellung “page.meta”, da diese Lösung sehr flexibel ist und keine TYPO3 Erweiterung benötigt wird.

Per TypoScript “page.meta”

TYPO3 stellt die TypoScript-Einstellung “page.meta” für die Meta-Tags zur Verfügung:

TS Setup

page.meta.description = Meine Beschreibung ...
page.meta.keywords.data = levelfield :-1, keywords, slide
page.meta.keywords.wrap = Keyword 1,Keyword 2,|

Die Angaben laufen durch die stdWrap-Funktion, dadurch ist man sehr flexibel und kann z.B. die Felder “Stichworte” und “Beschreibung” aus den Seiteneigenschaften einlesen.

Komplette Konfiguration

Bei dieser Beispiel-Konfiguration vererben sich die Meta-Inhalte auf Unterseiten, sie werden aus verschiedenen Feldern automatisch ausgelesen bzw. sind über TypoScript Konstanten konfigurierbar. Ist eine TypoScript-Konstante nicht gesetzt, wird der Meta-Tag nicht ausgegeben. Wenn für eine Seite in den Seiteneigenschaften die Checkbox “Nicht suchen” aktiviert ist, wird ein entsprechender Meta-Tag gesetzt, so dass Suchmaschinen diese Seite nicht indexieren.

TS Constants

temp.meta {
  robots = index,follow
  copyright =
  language =
  distribution =
  rating =
  revisit = 7 days
}
[globalVar = TSFE:page|no_search = 1]
temp.meta.robots = noindex,follow
[global]

TS Setup

page.meta {
  description {
    data = page:description
    ifEmpty.data = levelfield :-1, description, slide
  }
  keywords {
    data = page:keywords
    ifEmpty.data = levelfield :-1, keywords, slide
  }
  title {
    data = page:title
  }
  author {
    data = levelfield :-1, author, slide
  }
  date {
    data = page:SYS_LASTCHANGED // page:crdate
    date = Y-m-d
  }
  robots = {$temp.meta.robots}
  copyright = {$temp.meta.copyright}
  distribution = {$temp.meta.distribution}
  rating = {$temp.meta.rating}
  revisit-after = {$temp.meta.revisit}
}

WICHTIG: Damit “slide” (Vererbung der Felder auf Unterseiten) bei “description”, “keywords” und “author” funktioniert, muss man diese Felder im Install-Tool in “All Configuration” in Feld “addRootLineFields” eintragen.

Hinweis: Die Anweisung “data = page:myField” bei “keywords” und “description” scheint unnötig zu sein, ermöglicht jedoch das Setzen der Meta-Info über PHP:

$GLOBALS['TSFE']->page['description'] = 'the new description'

Wer hier den Meta-Tag für “content-language” vermisst: Diese Anweisung ist veraltet, die Sprache sollte man im body- oder html-Tag setzen.

Weitere Möglichkeiten für Konfiguration

Felder aus Seiteneigenschaften plus globale Werte

Mit nur einer Zeile TypoScript kann man die Keywords, die ein Redakteur über die Seiteneigenschaften einpflegt, um weitere Keywords ergänzen:

TS Setup

page.meta.keywords.wrap = Keyword 1,Keyword 2,|

Setup für tt_news Detailansicht

Auf der News-Detailseite kann man die Meta-Tags mit den Daten aus dem News-Datensatz überschreiben. Dazu legt man diesen TypoScript-Code in der News-Detailseite an:

TS Setup

// meta keywords and description from news record
page.meta {
  description.override.data = register:newsSubheader
  keywords.override.data = register:newsKeywords
}

Hinweis: Der Meta-Tag “author” sollte an dieser Stelle natürlich auch mit dem Autor der News überschrieben werden, allerdings geht dies erst, wenn tt_news diesen für die Anwendung in TypoScript per LOAD_REGISTER-Funktion zur Verfügung stellt.

Per PHP

Setzen der Meta-Tags mit PHP, z.B. über eine eigene Erweiterung:

$GLOBALS['TSFE']->page['keywords'] = '...';
$GLOBALS['TSFE']->page['description'] = '...';

Dies funktioniert aber nur, wenn die Meta-Tags nach bestimmten Regeln konfiguriert werden, z.B. page.meta.keywords.data = page.keywords

Per Extension

Es gibt natürlich auch diverse Erweiterungen für TYPO3, die sich um die Erzeugung der Meta-Tags kümmern:

Extension metatags

Generiert Meta-Tags über ein PHP-Skript.

Vorteile:

  • Globale Keywords möglich, man kann diese mit den Feldern aus den Seiteneigenschaften kombinieren
  • Dublin Core Meta Tags möglich
  • Konfiguration über TypoScript möglich, dadurch kann man z.B. auch die Vererbung einstellen oder eigene Meta-Tags für die News-Detailseite

Nachteile:

  • Unnötig, da gesamte Funktionalität über TypoScript erreicht werden kann
  • Extension ist aus Jahr 2005 und wurde für TYPO3 Version 3.6 erstellt
  • Extension ist nicht dokumentiert

Ähnliche Erweiterungen:

  • pp_pagemetadata
  • cl_metatags: Minimal geänderte metatags-Extension, gibt zusätzlich Geo-Tags aus (nicht zu empfehlen)
  • und weitere…

Extension autometa

Erzeugt Tags (keywords, description, author und date) automatisch aus vorliegendem Seiten-Inhalt, wenn diese nicht händisch für eine Seite angelegt wurden. Verwendet als Meta-Keywords die am häufigsten vorkommenden Wörter der Seite und als Meta-Description den ersten Textabschnitt. Bestimmte Keywords (stopwords) werden nicht verwendet.

Vorteile:

  • Sinnvoll für Seiten, deren Texte bewusst Suchmaschinen-optimiert sind (also wichtige Stichwörter mehrfach erwähnen, besonderen Augenmerk auf Überschrift und ersten Textabschnitt)
  • Auf jeder Seite individuelle Meta-Keywords und -Description ohne Pflegeaufwand durch den Redakteur…

Nachteile:

  • …wobei die Pflege der Stopwords doch wieder einiges an Zeit fressen wird
  • Extension ist nicht dokumentiert

Ähnliche Erweiterungen:

Es gibt viele ähnliche Erweiterungen, die technisch unterschiedlich vorgehen und verschiedene Features bieten.

  • pmkautokeywords
  • bk_automakemetatags
  • mc_autokeywords
  • autokeywords
  • autokeywordz
  • und weitere…

Thema: TYPO3 | Keine Kommentare

TYPO3: Default-Einstellungen im Backend ändern

Mittwoch, 12. Januar 2011

Die Standard-Einstellungen von Feldern im Backend, z.B. in Inhaltselementen oder Datensätzen, lassen sich anpassen:

Page TSconfig / User TSconfig

TCAdefaults.TABELLE.FELD = WERT

Den genauen Tabellen- und Feldnamen und die möglichen Werte für ein Feld, das man abändern möchte, findet man am besten, indem man direkt im Quellcode nachschaut, z.B. mit Firebug.

Leider funktioniert es nicht immer so einfach: Bei bestimmten Feldern, z.B. der Bild-Position oder der Bild-Spalten in Text-mit-Bild-Elementen, wird der Default-Wert durch TYPO3 oder durch Erweiterungen abgeändert, so z.B. in Datei “typo3/sysext/cms/ext_localconf.php” oder “typo3conf/ext/templavoila/ext_localconf.php”.

In einem solchen Fall muss man dann auch hier den Default-Wert überschreiben, also:

Page TSconfig / User TSconfig

mod.wizards.newContentElement.wizardItems.common.elements.textpic.tt_content_defValues.FELD = WERT

oder, falls TemplaVoila genutzt wird:

Page TSconfig / User TSconfig

templavoila.wizards.newContentElement.wizardItems.common.elements.textpic.tt_content_defValues.FELD = WERT

Dynamische Zuweisungen sind leider nicht möglich, wie z.B.

TCAdefaults.tt_content.date.stdWrap.strftime = %d.%m.%Y

Beispiel: Content-Element “Bild” / “Text-mit-Bild”

Bild-Abmessungen

Page TSconfig / User TSconfig

TCAdefaults.tt_content.imagewidth = 200

Bild-Position

Wenn man ein neues Content-Element “Nur Bilder” hinzufügt, ist die Position “unten mittig” voreingestellt. Eine andere
Bild-Position kann man voreinstellen, indem man in der TS-Config der BE-User / -Gruppen einträgt:

Page TSconfig / User TSconfig

TCAdefaults.tt_content.imageorient = WERT
mod.wizards.newContentElement.wizardItems.common.elements.textpic.tt_content_defValues.imageorient = WERT
templavoila.wizards.newContentElement.wizardItems.common.elements.textpic.tt_content_defValues.imageorient = WERT

Als WERT ist möglich:

  • 0 = Above, center
  • 1 = Above, right
  • 2 = Above, left
  • 8 = Below, center
  • 9 = Below, right
  • 10 = Below, left
  • 17 = In text, right
  • 18 = In text, left
  • 25 = In text, right (nowrap)
  • 26 = In text, left (nowrap)

Beispiel: tt_news

Page TSconfig / User TSconfig

TCAdefaults.tt_news.type = 1
TCAdefaults.tt_news.category = 2,3

In diesem Beispiel wird der News-Typ auf “Link zu interner Seite” umgestellt und als News-Kategorien werden die Kategorien mit ID 2 und 3 vorbelegt.

Thema: TYPO3 | Kommentare (1)

Bilder in tt_news Detailansicht in unterschiedlichen Markern & Größen

Dienstag, 5. Januar 2010

In der Detailansicht einer News kann man die Bilder in unterschiedlichen Größen und verschiedenen Markern ausgeben. Dafür legt man folgende Konfiguration an im TypoScript-Setup:

plugin.tt_news.displaySingle {
  imageMarkerOptionSplit = 1|*|2
  image.file.maxW = {$plugin.tt_news.singleMaxW}|*|100
}

Mit der Einstellung “imageMarkerOptionSplit” kann man die Bilder auf verschiedene Marker verteilen, Marker “NEWS_IMAGE_1″ enthält das erste Bild, “NEWS_IMAGE_2″ alle anderen Bilder. Im HTML-Template der News-Detailansicht stehen einem nun also diese Marker zur Verfügung:

###NEWS_IMAGE_1###
###NEWS_IMAGE_2###

Auch bei der Einstellung für die Bildbreite (image.file.maxW) wird “optionSplit” eingesetzt, so dass alle Bilder (außer dem ersten Bild) in 100 Pixel Breite gerendert werden.

Übrigens: Man kann für alle TypoScript-Einstellungen der News “optionSplit” einsetzen – der komplette Konfigurations-Array wird in Datei “pi/class.tx_ttnews.php” an die Funktion “processOptionSplit” übergeben!

Achtung: Die Einstellung “imageMarkerOptionSplit” wird nur beachtet, wenn die Einstellung “imageMarkerFunc” nicht genutzt wird (z.B. Lightbox-Extensions nutzen diese gerne).

Thema: TYPO3 | Kommentare (2)

Datensätze über TYPO3 Backend-Modul anlegen

Dienstag, 17. November 2009

Wenn man über ein Backend-Modul Datensätze anlegt oder ändert, sollte man nicht einfach selber eine INSERT-Query schreiben, sondern die Funktionalität von TYPO3 nutzen. Nach langer Einarbeitung in den TYPO3 Code und vielen Versuchen bin ich auf die recht simple Lösung gekommen:

class.lib_handleRecords.php

/**
 * Functions to handle records in BE modules
 *
 * @author Sven Burkert (sventb@googlemail.com)
 */
class lib_handleRecords {
	/**
	 * Insert new record
	 *
	 * @param string $table: table of new record
	 * @param array $fieldValues: values to insert, key is column of value
	 */
	public function lib_record_insert($table, array $fieldValues) {
		$datamap = array($table => array(uniqid('NEW') => $fieldValues));
		$this->lib_record_process($datamap);
	}
 
	/**
	 * Update existing record
	 *
	 * @param string $table: table of update record
         * @param integer $uid: uid of update record
         * @param array $fieldValues: values to update, key is column of value
	 */
	public function lib_record_update($table, $uid, array $fieldValues) {
		$datamap = array($table => array($uid => $fieldValues));
		$this->lib_record_process($datamap);
	}
 
	/**
	 * Delete a record
	 *
	 * @param string $table: table of record
	 * @param integer $uid: uid of delete record
	 */
	public function lib_record_delete($table, $uid) {
		$this->lib_record_process(array(), array($table => array($uid => array('delete' => true))));
	}
 
	/**
	 * Undelete a record
	 *
	 * @param string $table: table of record
	 * @param integer $uid: uid of record to restore
	 */
	public function lib_record_undelete($table, $uid) {
		$this->lib_record_process(array(), array($table => array($uid => array('undelete' => true))));
	}
 
	/**
	 * Move a record (to another page)
	 *
	 * @param string $table: table of record
	 * @param integer $uid: uid of record to move
	 * @param integer $pid: new (parent) page id for record (column "pid"). Prefix it with minus (-) to move it after this record.
	 */
	public function lib_record_move($table, $uid, $pid) {
		$this->lib_record_process(array(), array($table => array($uid => array('move' => $pid))));
	}
 
	/**
	 * Copy a record (to another page)
	 *
	 * @param string $table: table of record
	 * @param integer $uid: uid of record to copy
	 * @param integer $pid: new (parent) page id for record (column "pid"). Prefix it with minus (-) to move it after this record.
	 */
	public function lib_record_copy($table, $uid, $pid) {
		$this->lib_record_process(array(), array($table => array($uid => array('copy' => $pid))));
	}
 
	/**
	 * Localize a record
	 *
	 * @param string $table: table of record
	 * @param integer $uid: uid of record (default language) to localize
	 * @param integer $languageId: id of new language
	 */
	public function lib_record_localize($table, $uid, $languageId) {
		$this->lib_record_process(array(), array($table => array($uid => array('localize' => $languageId))));
	}
 
	/**
	* Process input
	*
	* @see t3lib_tcemain->process_datamap()
	* @param array $datamap: Data to be modified or inserted in the database
	*/
	private function lib_record_process(array $datamap, array $cmd = array()) {
		$t3lib_tcemain = t3lib_div::makeInstance('t3lib_tcemain');
		$t3lib_tcemain->start($datamap, $cmd);
		$t3lib_tcemain->process_datamap();
		$t3lib_tcemain->process_cmdmap();
	}
}

Diese Klasse kann man nun zum Anlegen neuer Datensätze,…

require_once(t3lib_extMgm::extPath('myExt', 'class.lib_handleRecords.php'));
$lib_handleRecords = new lib_handleRecords();
$lib_handleRecords->lib_record_insert(
	'myTableName',
	array(
		'pid' => $myPid,
		'title' => 'bla',
		'myField' => 'blubb'
	)
);

… zum Aktualisieren bestehender Datensätze und…

require_once(t3lib_extMgm::extPath('myExt', 'class.lib_handleRecords.php'));
$lib_handleRecords = new lib_handleRecords();
$lib_handleRecords->lib_record_update(
	'myTableName',
        $myUid,
        array(
		'pid' => $myPid,
		'title' => 'bla',
		'myField' => 'blubb'
	)
);

…zum Löschen von Datensätzen und…

require_once(t3lib_extMgm::extPath('myExt', 'class.lib_handleRecords.php'));
$lib_handleRecords = new lib_handleRecords();
$lib_handleRecords->lib_record_delete(
	'myTableName',
	$myUid
);

…zum Verschieben von Datensätzen usw. nutzen:

require_once(t3lib_extMgm::extPath('myExt', 'class.lib_handleRecords.php'));
$lib_handleRecords = new lib_handleRecords();
$lib_handleRecords->lib_record_move(
	'myTableName',
	$myUid,
	$newPid
);

Damit werden die Datensätze korrekt in die Tabelle eingefügt bzw. aktualisiert, d.h. mit den Timestamps, korrekten Wert für Feld “sorting” und korrektem Handling des Workspaces bzw. Versionierung (betrifft die Felder “t3ver_*”). Vor allem die Handhabung der Datensätze im Entwurfs-Workspace und anderen Workspaces wird damit erleichtert.
Beachten sollte man, dass man nun jedes Feld im TCA definieren muss, denn sonst werden die Werte für dieses Feld verworfen. Felder, die man nicht über das Backend abändern darf, kann man als “nur lesen” anlegen, z.B. so:

'config' => array(
	'type' => 'input',
	'readOnly' => 1
)

oder so:

'config' => array(
	'type' => 'select',
	'foreign_table' => 'myTable',
	'size' => 1,
	'readOnly' => 1
)

Achtung: Die Felder “uid”, “tstamp”, “crdate”, “cruser_id” und “sorting” werden von TYPO3 überschrieben, sie können also nicht selbst bestimmt werden.

EDIT 09.03.2010: Habe eben den Artikel auf http://blog.tolleiv.de/2010/03/handling-data-in-typo3-with-tcemain/ entdeckt und die weiteren Funktionen (Datensatz verschieben, kopieren und übersetzen) nachgereicht.

Thema: TYPO3, Web Entwicklung | Kommentare (1)

Unterlassungserklärungen von Alfahosting

Samstag, 7. November 2009

Eigentlich bin ich ja zufrieden mit Alfahosting (bis auf das “kleine Missverständnis”, als sie mir mein Browserspiel sperrten): Sie sind günstig und vom Support bekommt man schnell Anwort.

Doch kürzlich wurde die Webseite eines Kunden gesperrt und das “Theater” mit dem ISP ging los. Begründung für die Sperrung war folgende:

“[...]Leider mussten wir Ihren Account sperren, da sehr viele Spam-E-Mails über ein kompromittiertes Skript versandt wurden. Bitte beachten Sie das Sie fahrlässig gegen unsere AGBs verstoßen. Wichtiger Hinweis: Eine erneute Sperrung ist mit erheblichen Kosten verbunden![...]“

Heimlich, still und leise haben sie die Webseite gesperrt, ohne einen Hinweis oder eine E-Mail-Benachrichtigung, weder nach Sperrung noch im Vorfeld.

Gut, dachte ich mir, die Webseite läuft TYPO3, da gibt es wohl eine Sicherheitslücke – doch weit gefehlt: Das “kompromittierte Skript” war das Kontaktformular! Dieses hatte keinen Spam-Schutz und deshalb haben es Spam-Bots fleissig genutzt. Millionen anderer Webseiten haben diese “Sicherheitslücke”. Also habe ich einen Spam-Schutz implementiert und Alfahosting geschrieben, dass ich keinen Verstoß gegen die AGB feststellen konnte und dass sie die Seite doch bitte wieder freischalten sollen. Doch Alfahosting stellte sich quer und wollte weiterhin die Unterlassungserklärung. Doch wie kann ich garantieren, etwas zu unterlassen, was nicht ich, sondern andere (Spam-Bots) machen? Außerdem kann jeder Spam-Schutz umgangen werden, es wäre also nur eine Frage der Zeit, bis ein halbwegs intelligenter Spam-Bot den Schutz umgehen kann.

Nach mehreren Nachrichten hin und her (Alfahosting hat meinen Standpunkt natürlich nicht verstanden) riet ich dem Kunden, am besten einen Anwalt einzuschalten oder die Unterlassungserklärung zu unterschreiben. Er hat letzteres getan.

Keine 24 Stunden, nachdem die Webseite wieder freigeschaltet war, hat Alfahosting sie erneut gesperrt: Es wurden erneut Spam-E-Mails über das Kontaktformular verschickt! Freundlicherweise hat Alfahosting mir eine dieser Spam-E-Mails gezeigt und dabei ist mir aufgefallen, dass diese E-Mail in der alten Form vorlag (der Spam-Schutz erfordert ein zusätzliches Feld, das in der E-Mail aufgeführt werden müßte). Als mögliche Erklärungen habe ich nur zwei: Entweder hat Alfahosting hier das Datum gefälscht oder der E-Mail-Server hatte noch ein paar Spam-Mails in seiner Queue und hat diese nach Freischaltung des Accounts weiter abgearbeitet.

Nun wollte Alfahosting erneut eine Unterlassungserklärung und 25 Euro für das Entsperren des Accounts. Diese haben wir natürlich “gerne” gezahlt und das Kontaktformular von der Webseite entfernt. Bei solch einem Verhalten seines ISP sollte man ihn am besten wechseln oder einen Anwalt einschalten… es geht doch nicht, dass man seine Kunden mit der gesperrten Webseite um ein Unterlassungserklärung und/oder Geld erpresst. Doch das wäre wieder mit etlichen Kosten und Zeitaufwand verbunden.

Thema: Ärgernisse | Keine Kommentare

Bilder werden im Extension-Manual im TER nicht angezeigt

Mittwoch, 12. August 2009

Wenn in dem Online-Dokument einer Extension die Screenshots oder andere Grafiken nicht angezeigt werden, hat man diese falsch eingebunden, z.B. per Drag&Drop.

Im Quellcode sieht der img-Tag dann wie folgt aus:

<img width="NaN" src="{TX_TERDOC_PICTURESDIR}20000007000047A7000045FFBF8F874F.svm"/>

Die Grafiken muss man jedoch über “Einfügen” -> “Bild” -> “Aus Datei…” in die sxw-Datei einfügen. Das wußte ich bisher nicht, das “TYPO3 Kochbuch” hat mich aufgeklärt.

Thema: TYPO3, Web Entwicklung | Keine Kommentare