| Adventskalenderöffner
Registriert seit: 27.11.2008
Beiträge: 72
PHP-Kenntnisse: Fortgeschritten
| 10100: Newsfeed's back 10100:Nun habt Ihr das schöne RSS Logo aus Türchen 1001, aber — gar keinen Feed! Wer jetzt kein System mit fertigem Modul verwendet (Blog, CMS), kann sich vielleicht nachfolgend was abgucken. Quellen
Als erstes stellt sich die Frage, welche Inhalte für einen Newsfeed geeignet sind. Ihr solltet einen eingeschränkten Themenbereich wählen, dessen Inhalt sich regelmäßig ändert. Inhalte sollten textbasiert und einkürzbar sein. Technisch sind zentral gespeicherte Daten sinnvoll, eine hohe Anzahl von Einzelseiten ist nicht so geeignet.
Newsfeeds sind wohlstrukturierter Inhalt, sie sind semantisch als XML ausgezeichnete Nutzdaten. Sinnvollerweise sollte man bei der Erstellung deshalb an der Datenquelle selbst ansetzen. Das kann eine Datenbank sein oder ein als XML vorliegender Inhalt, ja, selbst ein gut strukturiertes HTML Dokument oder eine Textdatei kann Ausgangspunkt für ein Feed-Format sein. Entscheidend ist die Aufbereitung der benutzen Quelldatei.
Für bereits vorliegende XML-Inhalte bietet sich XSLT perfekt an. Das erfordert einige Einarbeitungszeit, ist dann aber optimal, um ein XML Format in ein anderes umzuwandeln. XML Dokumente liegen aber eher auf Einzelseiten herum, Ihr müßt Euch also ein Script basteln, das - Alle Inhalte (bspw. ordnerbasiert) durchläuft
- die Aktualität feststellt (bspw. Inhalte nach Erstellungsdaten sortiert)
- eine Auswahl ausliest, zusammenfasst und schließlich als XML Struktur umsetzt.
Für alle anderen Eingaben müssen wir etwas anders verfahren. Wir setzen dort an, wo die Daten ausgelesen (bspw. Datenbankdaten) bzw. verarbeitet werden (bspw. ausgelesene Textdateidaten). Werden beispielsweise Kommentare für eine kleine Homepage aus einer Datei ausgelesen und anschließend in einer Schleife ausgegeben, ist hier schon der grundlegende Mechanismus zum Erstellen des Feeds gegeben. So werden in der Kommentaransicht vielleicht Autor und Datum mit separaten span's ausgezeichnet, der Kommentartext mit einem div. Uns genügen schon die Daten in getrennten Variablen. Ob diese letztendlich zwischen <span> Tags oder <author><name> geschrieben werden, ist gleich aufwendig. Wir kopieren uns also diesen Codeteil und passen ihn an unser erzieltes Ausgabeformat an. Strukturelles
Womit wir bei der Struktur sind. Wie oben bereits angedeutet sind Newsfeeds XML-Dokumente mit fest definierten Elementen und Eigenschaften. Verbreitet sind dabei die Formate RSS und Atom, die sich im Grunde sehr ähneln. Um ein Grundschema zu erzeugen, setzen wir die Struktur einfach mal in zwei printf-kompatible Strings um, einen für den Datensatz und einen für das Dokument (hier für Atom): PHP-Code: // Template für Datensätze
$feedSetTemplate = '
<entry>
<title>%s</title>
<link href="%s" />
<id>%s</id>
<updated>%s</updated>
<summary>%s</summary>
</entry>';
PHP-Code:
// Template für Feed Gesamtstruktur
$feedBodyTemplate = '<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
<author>
<name>%s</name>
</author>
<title>%s</title>
<id>%s</id>
<updated>%s</updated> %s
</feed>'; Über sprintf können wir die Platzhalter dieser Ausdrücke jetzt füllen. Dabei greifen wir auf unsere oben ausgelesenen Daten zurück und erzeugen Daten wie die ID oder Datumsangaben on the fly. Generierungsbeispiel
Als Beispiel sei hier eine Datenbanktabelle gedacht, die Kommentare für unsere Homepage zentral speichert: Comments
ID | Date | Author | Email | Website | Title | Comment
Ein perfektes Eingabeformat für unseren Plan! Alle Daten sind separat hinterlegt und können in unser Template eingepasst werden.
Zunächst beschränken wir unseren Feed, z.B. auf die 20 aktuellsten Einträge: SELECT * FROM Comments ORDER BY `Date` DESC LIMIT 20
Dann lesen wir die Datensätze wie üblich aus und füllen munter unseres Feed-Datensatzstrings: PHP-Code: <?
// unsere Templatedefinitionen von oben
// ...
// Datenbank Connection und Anfrage
// ...
$feedContent = '';
while ($set = mysql_fetch_assoc ($db_ressource)) {
// Datensätze per Template generieren und aneinanderreihen
$feedContent .= sprintf (
$feedSetTemplate ,
empty ($set['Title'])
? 'Eintrag von ' . $set['Author']
: $set['Title'] ,
'http://url/zu/den/Kommentaren/view.php?id=' . $set['ID'] ,
$set['ID'] ,
rssDate ($set['Date']) ,
substr ($set['Comment'] , 0 , 120)
);
}
// Metadaten und Datensatz-String in Template einfügen
$feedContent = sprintf (
$feedBodyTemplate ,
'Dein Name' ,
'Dein Feed Titel' ,
'http://url/zum/script/atom_feed.php#' . time () ,
rssDate (time ()) ,
$feedContent
);
// Ausgabe oder Speichern
// ... echo oder file_put_contents
?> Die Sache mit dem Datum
Feeds verlangen spezifische Datumsformate, Atom bspw. ISO.8601.1988, W3C.NOTE-datetime-19980827 oder W3C.REC-xmlschema-2-20041028. Deswegen benutzen wir im obigen Code die Funktion rssDate, die wir nachfolgend deklarieren wollen.
Für php5 liefert die date () Funktion mit dem Formatzeichen „c“ bereits einen perfekten String, für ältere PHP Versionen können wir uns auch selbst das Format zusammenklauben: PHP-Code: function rssdate ($timestamp)
{
// php 5 Variante
// return (date ('c' , $timestamp));
// php < 5 Variante
return (date ('Y-m-d' , $timestamp) . 'T' . date ('H:i:s+01:00' , $timestamp));
}
Caching
Stellt sich die Frage, wann wir den Feed erzeugen. Man könnte natürlich bei jedem Aufruf jetzt unsere Inhalte abgrasen. Viel sinnvoller ist es aber, Feeds zwischenzuspeichern und erst, wenn wieder neue Daten vorhanden sind, die Neuerzeugung anzustoßen. Umgesetzt werden kann dies mit einem einfachen Datumsvergleich. Ist ein Datensatz neuer als die Datei, die wir zwischengespeichert haben, wird der Feed neu erzeugt und ausgegeben, sonst der alte ausgelesen und ausgeliefert. Genau diese Aufgabe übernimmt unser Feedscript. Es schreibt einen erstellten Feed als temporäre Datei in einen Cache-Ordner.
Wird jetzt auf unserer Homepage ein neuer Kommentar erzeugt, wird gleichzeitig die Löschung der Feeddatei veranlasst. Bei der nächsten Anfrage registriert das Feedscript diesen Umstand, liest die aktuellsten Datensätze aus und schreibt die neuen Cache-Inhalt.
Mehr zu Caching-Prinzipien könnt Ihr demnächst im Wiki erfahren. Browserfreundlich
Besonders schön ist, wenn der Feed auf der Startseite oder der jeweiligen Inhaltsseite dem Browser angeboten wird. Im Firefox findet sich dann ein kleines Icon in der Adresszeile, über die man den Feed abonnieren kann, so z.B. als dynamisches Browserbookmark.
Glücklicherweise ist die Einbindung in HTML simpel: Einfach in die betreffende Seite im Headerbereich Code: <link rel="alternate" type="application/rss+xml" title="Dein Feed Titel" href="http://url/zum/script/rss_feed.php">
<link rel="alternate" type="application/rss+xml" title="Dein Feed Titel" href="http://url/zum/script/atom_feed.php">
notieren. Na bitte. Da ist unser Bookmark-Icon nach Neuladen der Seite. Auf diese Weise kann man übrigens auch verschiedene Feeds für unterschiedliche Themenbereiche o.ä. anbieten.
So. Damit habt Ihr ein Grundgerüst für einen RSS/Atom Feed. Was Ihr jetzt damit anbietet und wie Ihr ihn erweitert bleibt Euch überlassen. Die Spezifikation läßt jedenfalls noch eine Menge Spielräume offen. Also… beglückt Eure Stammleser doch mal mit Eurem eigenen Newsfeed! Z.B. von den philosophischen Weltbetrachtungen Eures Goldhamsters. Oder so.
Viel Spaß beim Basteln,
Euer Nikolaus.
P.S.: |