Die letzten Wochen habe ich mich auf der Arbeit viel mit
t3Blog, der neuen Blog-Extension der Schweizer Firma
Snowflake beschäftigt. War die bisherige Arbeit mit tt_news und timtab doch immer eine ziemliche Fummelei, erweckte die überwiegend
positiv besprochene Extension hohe Erwartungen in mir. Sollte man doch mit wenigen Mausklicks einen Blog aufsetzen können. Doch wie die Realität zeigt: So einfach ist das nicht. Besser gesagt: So wie ich das will, ist das nicht einfach.
Möchte man die Extension Out-of-the-Box installieren und ist mit dem mitgelieferten Layout auch glücklich, dann geht es wirklich schnell und man kann bereits nach wenigen Minuten anfangen zu bloggen. Bei uns sollte das Ganze aber in eine bestehende Seite mit einer bestehenden Navigation integriert werden. Dazu sollten es die einzelnen Backend-Benutzer in ihren Zweigen jeweils einsetzen können, ohne das sich die Blogs ins Gehege kommen und ohne das die Benutzer mit TypoScript in Berührung kommen. Dafür waren einige Änderungen, Erweiterungen und ausführliche Tests nötig. Insgesamt ist das Konzept, die einzelnen Anwendungen in sogenannte Widgets zu kapseln, sehr gelungen. Dadurch weiß man recht gut wie und wo man ansetzen muss und will.
Ich möchte mich auch bei
Thorsten Schneider und beim
Kaktusteam bedanken, die mir besonders beim RSS-Feed mit ihren Einträgen geholfen haben. Den Blog bei uns im Einsatz, gut eingepasst in die bestehende Navigation und Seitenstruktur sieht man auf unseren
Seiten des Rechenzentrums. In den nächsten Zeilen werde ich grob auf einige Klippen und Hürden eingehen, die umschifft werden mussten. Einigen Code dazu in der Langfassung des Artikels.
1. TemplaVoila: Hauptproblem mit TemplaVoila ist, dass die Inhaltselemente doppelt angezeigt werden. Um dies zu umgehen habe ich ein neues TO erschaffen, dass einen zusätzlichen Inhaltsbereich, deckungsgleich mit dem eigentlich Inhaltsbereich enthält. Der eigentliche Inhaltsbereich wird über CSS ausgeblendet. Jetzt kommen die für den Blog genutzten Content Element in den nicht-sichtbaren Bereich und die Blog-Elemente in den sichtbaren Bereich. So kann man recht elegant das Problem der doppelt angezeigten Elemente bei t3blog umgehen.
2. BE-User Autorfeld: Blöd ist, dass ein eingeloggter BE-User alle anderen User als Autor auswählen kann, nicht nur die aus seiner BE-Gruppe. Das kann man umgehen, in dem man das Auswahlfeld nicht sichtbar macht und den Autor vorbelegt.
TCAdefaults.tx_t3blog_post.author :=author_return(uid)
3. Template Einstellungen: Ich finde es zwar nicht schlecht, dass man den Blog nahezu komplett über TS konfigurieren kann, aber es ist nicht immer ganz ersichtlich, ob man jetzt pi1 oder pi2 ansprechen muss. Da ist Rumprobiererei angesagt. Danach lassen sich aber Labels und Einstellungen sehr gut ansprechen. Trotzalledem bin ich nicht drumherum gekommen in den eigentlich setup.txt - Dateien Einstellungen vorzunehmen. Da diese mehrfach verschachtelt und sehr komplex sind, war es für mich weniger aufwendig schnell die setup.txt zu editieren und die Änderungen für spätere Updates zu dokumentieren, als das alles in das TS-Setup der Seite zu packen. Ich habe einige Einstellungen in den Wraps vorgenommen um z.B. das Autorenbild auszublenden, die Anzahl der Kommentare einzuklammern, Kategorie und Autor mit einem Bezeichner zu versehen und Elemente mit einer zusätzlichen umgebenden <div>-Box zu versehen, um sie mittels CSS besser stylen zu können.
4. CoolURI: Leider arbeitet t3blog noch nicht korrekt mit CoolURI zusammen. Um das zu umgehen, habe ich mir eine kleine userFunc in der localconf.php geschrieben, die abfragt ob auf der jeweiligen Seite ein Blog-Element vorhanden ist. Wenn dem so ist, dann wird CoolURI für die Seite einfach abgeschaltet.
5. Kommentar E-Mails: Bei neuen Kommentaren wird eine E-Mail an den Adminstrator verschickt. Normalerweise kann man den über den Constant Editor einstellen. Da ich diesen dem Benutzer nicht zur Verfügung stellen will, habe ich die Widget-Auswahl-Maske um ein Feld zur Eingabe einer E-Mail-Adresse erweitert. Jetzt kann der Benutzer beim Anlegen eines Blogs selber festlegen, an welche Adresse er die Mails haben möchte.
6. TagCloud: Leider sortiert die TagCloud standardmäßig nach dem Vorkommen der Begriffe. Ich wollte aber lieber eine Sortierung nach Alphabet. Dazu muss man einfach in der Datei class.tagCloud.php die Funktion sortByCountValue() auskommentieren.
7. JS-Files: Die JS-Files binden wir manuell ein und auch nur dann, wenn sich auf der Seite auch ein Blog befindet. Dazu bedienen wir uns wieder der userFunc die ich schon für CoolUri geschrieben habe.
8. CSS Styling: Das Styling des Blogs erfolgt in CSS-Dateien. Hier war auch einiges an Anpassung nötig, da die von Snowflake mitgelieferten Vorgaben nur auf das vorgegebene Layout passten. Aber mit viel Ausprobieren habe ich eine schöne Lösung gefunden, die die BlogList links und alle Widgets rechts auf der Seite positioniert. Von den Maßen her ist es sehr an unsere TYPO3-Installation angepasst, eine Weitergabe bringt nicht viel.
9. RSS-Feeds: Am meisten Probleme bereiteten die RSS-Feeds. Hier musste ich einige Eingriffe im Code vornehmen, damit nur die Beiträge aus dem zugehörigen Blog und nicht alle angezeigt werden. Außerdem wollte ich lieber einen Full-Feed statt einen Short-Feed. Auch hierzu musste der Quelltext abgeändert werden, da wir statt dem Text die UID brauchten um das zugehörige Content Element manuell zu rendern. Ansonsten habe ich keinen schönen Feed bekommen. Bei den Links musste man das vorkommende & maskieren und durch & ersetzen. Zum Schluß habe ich noch die komplette Feed-Metadaten, die man normalerweise über den Constant Editor setzen kann so umgeschrieben, dass sie entweder automatisch generiert werden, von mir allgemein vorgegeben werden oder vom Benutzer selber über zusätzliche Felder bei der Widget-Auswahl eingegeben werden können.
Fazit: Ein hartes Stück Arbeit, aber im Ergebnis eine sehr gut in TYPO3 integrierte Blog-Umgebung die jeder Benutzer komfortabel in seinem eigenen Zweig nutzen kann. Als kleinen Bonus gibt es noch einen Auszug aus dem Handbuch für unsere Benutzer zum Download: Benutzerhandbuch_Blog.pdf
CoolURI#Keine Umschreibung, wenn Blog-Element
[userFunc = user_isBlog()]
config.tx_cooluri_enable = 0
[end]
Diese Funktion ruft die Methode user_isBlog auf. Gibt die true zurück, dann wird die URL-Umschreibung ausgeschaltet. Die entsprechende Methode in der Datei localconf.php sieht so aus:
//UserFunc um zu überprüfen, ob sich auf der Seite ein Kalender befindet
function user_isBlog() {
$id = $GLOBALS['TSFE']->page['uid'];
$res = $GLOBALS['TYPO3_DB']->exec_SELECTquery(
'*',
'tt_content',
'pid='.$id.' AND list_type = "t3blog_pi2"',
'',
'',
'');
$num = mysql_num_rows($res);
if($num > 0) {
return true;
} else {
return false;
}
}
Kommentar E-Mails:Damit jeder Benutzer hier eine eigene Adresse eintragen kann, müssen wir das Flexform für die Widget-Auswahl erweitern. Dies geschieht in der Datei flexform_pi2.xml im Extension-Verzeichnis. Nach der Beschreibung des <storagePid> Feldes fügen wir folgenden Code ein:
<commentEmail>
<TCEforms>
<exclude>1</exclude>
<label>LLL:EXT:t3blog/pi2/locallang.xml:pi_flexform.commentEmail</label>
<config>
<type>input</type>
<size>50</size>
</config>
</TCEforms>
</commentEmail>
In der referenzierten locallang.xml Datei muss der gewünschte Text eingetragen werden:
<label index=“pi_flexform.commentEmail“>E-Mail Adresse des Blog-Verantwortlichen (Bei Blog list- und RSS-Widget eintragen):</label>
Damit kann der Benutzer jetzt eine E-Mail Adresse angeben. Damit die dort eingegebene Adresse vom Blog bei Kommentaren auch verwendet wird, müssen wir Änderungen im Code vornehmen:
In der Datei pi2/class.tx_t3blog_pi2.php fügen wir in der init-Methode nach Zeile 75 ein:
$this->internal[‚commentEmail‘] = this->pi_getFFvalue($this->cObj->data[‘pi_flexform’], ‘commentEmail’, ‘sDEF’)
Anschließend schreiben wir so ermittelte Adresse in der main-Methode nach Zeile 54 in das globale Array. Dazu rufen wir eine Methode aus der Library auf:
t3blog_div::setCommentEmail($this->internal[‚commentEmail‘]);
In der Datei pi1/lib/class.t3blog_div.php müssen wir die Methode natürlich implementieren. Zusätzlich implementieren wir eine Methode, die die E-Mail Adresse zurückgibt und von außen aufgerufen werden darf.
function setCommentEmail($mail) {
if($mail == „“) {
$GLOBALS[‚commentEmail‘] = “root”
} else {
$GLOBALS[‚commentEmail‘] = $mail;
}
}
function getCommentEmail() {
return $GLOBALS[‚commentEmail‘];
}
Zum Schluß ist dann im blogList-Widget die Datei class.singleFunctions.php zu ändern. In der Methode adminMailComment() ab Zeile 830 lesen wir die entsprechende Variable aus und fügen die E-Mail_Adresse als Zieladresse in den Aufruf der plainMailEncoded Methode ein.
$mailTo = t3blog_div::getCommentEmail();
RSS-Feeds:Damit der RSS-Feed funktioniert, sind ein paar Einstellungen nötig. RSS-Feeds werden über den speziellen Seitentyp 100 gekennzeichnet. Dieser muss definiert werden, dies geschieht im TS-Setup des Root-Templates:
#Definition des Seitentypes 100 um RSS-Feeds in Blogs anzuzeigen
xmlnews = PAGE
xmlnews {
typeNum = 100
config {
disableAllHeaderCode = 1
additionalHeaders = Content-type:text/xml
linkVars = L
no_cache = 1
xhtml_cleaning = 0
admPanel = 0
}
10 = USER
10 {
# Call the user function
userFunc = tx_t3blog_pi1->main
widget.rss < plugin.tx_t3blog_pi1.rss
# Load "design" of the RSS-stuff
# Attention! This will only work, when you are
# using the static template "T3BLOG Layout".
# The static template has included the full design of
# a blog (position of widgets and much more)t
template =< plugin.tx_t3blog_pi1.layoutBlog.40.80
}
}
Weiterhin setzen wir im TS-Setup noch die folgenden Einstellungen:
#t3Blog: RSS Feed
plugin.tx_t3blog_pi1 {
rss {
postItemCount = 10
feedCopyright = 2009 Universität Konstanz
feedWebMaster = typo3@uni-konstanz.de
}
}
plugin.tx_t3blog_pi2 {
rss {
_LOCAL_LANG.de.rss_click_here = Feeds!
}
}
Der erste Block (pi1) setzt die Anzahl der Beiträge im Feed auf 10 und definiert einige Metadaten, die für alle Feeds im System gelten. Weitere Metadaten werden in einem separaten Unterkapitel behandelt. Der zweite Block (pi2) ändert die Überschrift im Frontend für die Feeds in der deutschen Sprachdatei.
Nur eigener Blog:In der Methode getContentResult fügen wir ab Zeile 200 ein:
//Nur Beiträge/Comments aus dem zugehörigen Blog-Folder
$pid = t3blog_div::getBlogPid();
Und erweitern die where-Klausel für die Datenbankabfrage um die Abfrage der PID:
$where = ‚WHERE ‘.$table.‘deleted = 0 AND ‘.$table.’.hidden = 0 AND ‘.$table.’.pid = ‘.$pid;
Full-Feed statt Short-Feed:Um den Benutzern einen Full-Feed anzubieten, der die kompletten Inhalte ausliefert, ist ebenfalls eine Änderung im Code notwendig. In der Methode make_xml erweitern wir in Zeile 137 & 147 den Methoden Aufruft setRecFields um den Parameter text.
$xmlObj->setRecField(‚tx_t3blog_com‘, ‚title,author,uid,fk_post,date,text‘);
Der ausgelesene Text muss aber noch gerendert werden, ansonsten ist er unformatiert und ohne Zeilenumbrüche. Zu diesem Zweck ändert man die Abfrage der Datenbank in Zeile 227. Die SELECT-Klausel lautet neu:
$select .= ‚, tt-content.uid AS text ‚;
Anstatt also über eine CONCAT-SQL-Funktion den Text direkt auszulesen, lassen wir nur die ID des Content Elements ausgeben.
Im weiteren Verlauf ändert man in der der fieldWrap – Methoden den case ‚text‘: Anstatt des Textes bekommen wir hier die ID übergeben und rendern das Content Element mit den folgenden zwei Zeilen manuell:
$getBodytext = array(‚tables‘ => ‚tt_content‘, ‚source‘ => $value, ‚dontCheckPid‘ => 1);
$this->item = $this->cObj->RECORDS($getBodytext);
Das ist natürlich nicht 100% sauber, da man auch einen eigenen case-Fall dafür bauen könnte.
Link-Generierung://Temporäre Generierung der Link-URL
$linkTempGen =
''.(stripos('http://',t3lib_div::getIndpEnv('HTTP_HOST'))?'':'http://').t3lib_div::getIndpEnv('HTTP_HOST').'/'.tslib_pibase::pi_getPageLink(t3blog_div::getBlogPid(), '', array('no_cache' => 1, 'tx_t3blog_pi1[blogList][year]' => $year, 'tx_t3blog_pi1[blogList][month]' => $month, 'tx_t3blog_pi1[blogList][day]' => $day, 'tx_t3blog_pi1[blogList][showUid]' => $this->conf['feedItemLinkPrefix'].$postid)).'';
$linkTempGen = str_replace("&","&",$linkTempGen);
return '<link>'.$linkTempGen.'</link><guid>'.$linkTempGen.'</guid>';
Feed-Metadaten:Damit der Benutzer von TypoScript verschont bleibt, ist es notwendig die FlexForm Variablen auch in den Widgets verfügbar zu machen. Dazu ist eine Methode nötig, die die FlexForm Daten manuell aus der Datenbank holt und zur Verfügung stellt. Diese Methode wird als eigene Funktion implementiert:
function getFlexform($value) {
//Seiten ID
$id = intval(t3lib_div::GP(‚id‘);
//RSS Widget ist Nummer 7
$like = “’%<value index=\”vDEF\”>7</value>%’”;
//Flexform Daten besorgen
$sql = $GLOBALS[‘TYPO3_DB’]->exec_SELECTquery (
‚pi_flexform‘,
‚tt_content‘,
‚pid = ‚.$id.‘ AND pi_flexform LIKE ‚.$like,
‘’,
‘’,
‘’
);
$row = $GLOBALS[‘TYPO3_DB’]->sql_fetch_assoc($sql);
//Flexform-XML in Array umwandeln
$flex = t3lib_div::xml2array($row[‘pi_flexform’]);
Return $this->pi_getFFvalue($flex, $value, ‘sDEF’);
Der Zugriff und die Zuweisung zu den einzelnen Feldern erfolgt dann im Kopf der renderHeader-Methode mit den folgenden Aufrufen:
$this->conf[‚feedManagingEditor‘] = $this->getFlexform(„commentEmail“);
$this->conf[‚feedDescription‘] = $this->getFlexform(„feedDescription“);
$this->conf[‚feedTitle‘] = $this->getFlexform(„feedTitle“);
Wichtig ist dabei, dass der der Methode getFlexform übergebene Wert dem Wert entspricht, der auch in der flexform_pi2.xml so definiert ist. Die E-Mail Adresse wurde bereits für Kommentar-Emails definiert, die anderen Einstellungen müssen wir noch festlegen. Dies geschieht nach dem Block commentEmail.
<feedTitle>
<TCEforms>
<exclude>1</exclude>
<label>LLL:EXT:t3blog/pi2/locallang.xml:pi_flexform.feedTitle</label>
<config>
<type>input</type>
<size>50</size>
</config>
</TCEforms>
</feedTitle>
<feedDescription>
<TCEforms>
<exclude>1</exclude>
<label>LLL:EXT:t3blog/pi2/locallang.xml:pi_flexform.feedDescription</label>
<config>
<type>input</type>
<size>50</size>
</config>
</TCEforms>
</feedDescription>
In der verlinkten locallang-Datei müssen noch die Beschriftungen eingetragen werden.
<label index=“pi_flexform.feedTitle“>Titel des RSS-Feeds (Bei RSS-Widget eintragen):</label>
<label index=“pi_flexform.feedDescription“>Kurzbeschreibung des RSS-Feed (Bei RSS-Widget eintragen):</label>
feedLink
Der Link wird zur Startseite des Blogs generiert. Diese ermitteln wir und generieren daraus den Link mit folgender Befehlszeile am Anfang der renderHeader-Methode:
$this->conf[‚feedLink‘] =
(stripos(‚http://‘,t3lib_div::getIndpEnv(‚HTTP_HOST’))?’’:’http://’).t3lib_div::getIndpEnv(‘HTTP_HOST’).’/’.tslib_pibase::pi_getPageLink(t3blog_div::getBlogPid(),’’,’’);
feedImage
Ein Bild zum Feed wollen wir nicht anzeigen, deshalb kommentieren wir den Teil zur Generierung des Feed-Bildes im Code aus. Das geschieht in der Methode renderHeader ab Zeile 294.
Ich leite dein Post mal an unsere t3blog-Entwickler weiter...
Gruss
Mario
Danke für deine Klasse Erläuterungen. Für die Einbindung in Templavoila habe ich noch eine andere Version. Da der Code sehr umfangreich ist, habe ich mal einen eigenen Blogeintrag erstellt. Vielleicht kannst du was davon gebrauchen.
http://www.thomaskieslich.net/blog/t3post/2009/03/24/interessante-infos-zum-t3blog.html
Liebe Grüße Thomas
erstmal danke für die Hilfen hier. Ich bin gerade dabei als Novize eine "t3blog" für obige Homepage zu machen. Ich hab aber bei den Tag-Clouds das Problem, dass sobald ich das sortieren auskommentiere, bekomme ich alle tags angezeigt. Ich meine es ist spät aber so spät in der Nacht , was sehe ich nicht?
Danke schonaml für alles
R
wie ich sehe funktioniert dein RSS-Feed, ich habe deine Anleitungen befolgt, aber bekomme immer die Meldung:
"XML-Verarbeitungsfehler: Kein Element gefunden
Adresse: http://....../index.php?id=24&type=100&tx_t3blog_pi1[rss][feed_id]=0.91&tx_t3blog_pi1[rss][value]=Posts
Zeile Nr. 1, Spalte 1:".
Ich weis das du das Problem auch hattes, aber was hast genau gemacht?
Danke schonmal im Vorraus
Weisst du wie man die SQL Anweisung umbauen muss damit man alle zugehörigen FCEs holt? Ich bekomms einfach nicht hin....
Aber grob geschätzt müsste man doch nur abfragen, wieviele CEs zu einem Blog-Eintrag existieren und die dann mit einer Schleife abfragen und zusammenfügen.
Naja, jetzt hat mich der Ehrgeiz gepackt. Es fehlen noch Bilder im Feed
Wenn ich es dann mal schaffe meine Seite live zu stellen, werde ich mal ein Tutorial bereitstellen.
Grüße FElix
wie genau hast das mit dem Rss-feed angestellt???
Ich bekomme immer eine Fehlermeldung (siehe Eintrag #4).
Brauche ich noch irgend eine Erweiterung oder muss ich irgendwas danach noch im TS oder Constanten einstellen
Kanst du mit da irgendwie etwas helfen ?
Danke im vorraus
Hast du schon im Code rumgehackt oder ist alles Standard? Wie bindest du das RSS widget ein? Per TS oder als CE?
Poste mal mehr infos, wenn möglich nen link zu deinem Blog.
Ihr wäre auch noch ein Link zur Testseite.
http://sgu.webtrekk-tech.de/blog-de.html
Ich bin mir nicht sicher. Was hast du sonst noch an config? Hau das vielleicht mal in ein pastebin.
In jedem Falle darfst diesen Teil nicht einbinden wenn du das ganze als CE einbindest.
xmlnews = PAGE
xmlnews {
typeNum = 100
config {
T3Blog in Verbindung mit TV ist eh ziemlich tricky. Man muss ganz schön was anpassen um das zum laufen zu kriegen. Von der Anpassung im Core von TV (für die richtige Sortierung) über TS Anpassungen im TV Template bishin zu mehreren Anpassungen im T3Blog (um einige Bugs zu fixen und Funktionen aufzubohren).
Ich könnte ja mal mein TS und Constanten posten, damit du mal ein blick drauf werfen kast, nur wenn ich das tuhe poste ich mein TS nicht hir sondern auf der Testhomepage (siehe oben).
PS.: bitte die homepage nicht mit IE besichtigen
Musste nur unter TS noch ein paar sachen einstellen (siehe .../typo3conf/ext/t3blog/static/t3blog)
und in Zeile 220 bei $select steht
tt-content.... anstat tt_content...., dadurch wir die MySQL abfrage gestört.
aber trotzdem danke
Super Anleitung hier - Respekt!!!
Weiß einer von euch wie man in den RSS Feed auch Fotos rein bekommt.
Ich nutzte ein Newsletter Programm welches automatisch aus RSS Feeds Newsletter versendet und würde hierfür gerne auch die Fotos verwenden können...
lg
Wolfgang