Ein RSS Feed in TYPO3 erstellen

In diesem Artikel wird gezeigt, wie man mit typoscript und TYPO3 Mittel ohne Extension einen RSS Feed erstellen kann.

Ausgangslage

Wieso ein RSS Feed anbieten?
Folgendes habe ich mir diesbezüglich überlegt.

Ich möchte das Besucher dieser Webseite sich nicht jedes mal durch die ganzen Bereiche klicken müssen um zu sehen was es neues gibt.

Besucher sollen nicht sporadisch auf meine Webseite kommen und schauen was es neues gibt, sondern sie sollen über Neuigkeiten informiert werden können.

Ãœber diese Neuigkeiten will ich nicht per Newsletter informieren, weil ich nicht möchte das man sich dafür anmelden muss. Zudem ist es für mich zu aufwendig jedes mal einen Newsletter erstellen zu müssen um einen neuen Artikel oder Informationen einem Interessenten mitteilen zu können.

Vorbereitung und Analyse

Was ist also ein RSS ( oder Atom ) Feed genau? Wie erstellt man einen solchen Feed? Was ist der Unterschied zwischen RSS und Atom? Was muss man beachten?

Fragen über Fragen, aber alles der Reihe nach!

RSS wie auch Atom sind kurz gesagt ein Internet-Nachrichtenformat welche Artikel in einem XML Format anbieten. Genaueres kann man bei Wikipedia nachlesen.

Um die Frage der Unterscheide zu beantworten gibt es ebenfalls einige Artikel über Google zu finden. Informativ fand ich diesen Artikel auf meiert.com zu RSS 2.0 und Atom 1.0 im Vergleich.

Ebenfalls fand ich bei Google einige Artikel zu: Wie man einen RSS Feed erstellt. Den Artikel bei selfhtml.de fand ich zwar interessant, aber ich will das TYPO3 dies anbietet, ohne die Seite parsen zu müssen.

Auf den Punkt gebracht.

Beides sind XML Dateien welche über diverse Elemente wie Titel, Beschreibung, Inhalt etc. Informationen anbieten.

So weit so Gut! Aber wie machen es andere? Brauchen Sie eine Extension für dies? Sucht man nach rss bei typo3.org, findet man einige Extensions. Meine Erfahrung zeigt jedoch, das die meisten die RSS Funktion von tt_news verwenden und somit News als Inhalt für die RSS Feeds benutzen.

Es gibt viele Tutorials wie man tt_news mit RSS Feeds verwendet. Eines der besseren finde ich die Anleitung von rainer-grundel.de.

Aus meiner Sicht ist es ein Nachteil, wenn jede News auch gleich immer im RSS Feed erscheint. Besser wäre es, wenn man eine News Kategorie einrichtet und nur News aus einer Bestimmten RSS-Kategorie im Feed anzeigt. Somit kann man den Inhalt bestimmen, welcher ausgegeben wird.

Weil ich jedoch tt_news noch nicht verwende, ist dies alles keine aktuelle Lösung für mich.

Anforderungen an den RSS Feed

Viele Anforderungen an den RSS Feed dieser Webseite habe ich nicht. Folgende Anforderungen möchte ich jedoch erfüllen können.

  • Möglichst validen XML Code liefern, damit er mit den meisten Reader ohne Probleme gelesen werden kann.
  • Neuigkeiten und Artikel sollen nur mit Kurzbeschreibung (angeteasert) werden.
  • Benutzer sollen den ganzen Artikel auf der Webseite lesen, so das ich diese auf der Webseite habe und mir die Hits was bringen.

Testen und Ãœberprüfen

  • Eine Seite, bei welcher im TYPO3 Verbergen gesetzt hat darf im RSS nicht erscheinen, auch wenn die Seite im Content Element ausgewählt ist.
  • Wenn im Seitentitel Sonderzeichen wie zum Beispiel & < > eingegeben werden, darf dies nicht zu fehlerhaftem XML führen.
  • Die Ausgabe des RSS Feeds soll beim Test auf FEED Validator bestmöglich valid sein.

Lösungsbeispiel

Als Lösung habe ich eine reine typoscript Version erstellt. Dazu verwende ich ein Menü Content Element (Menü dieser Seiten) von TYPO3, welches ich in einem System Ordner abgelegt habe. In diesem Content Element kann ich nun alle gewünschten Artikel als Seite angeben.

Für den Aufbau wurde zuerst eine RSS Beispiel Datei erstellt (rss.xml) und alle Inhalte welche benötigt werden durch Marker ersetzt. Danach wird per typoscript die XML Datei eingelesen und mit den Daten abgefüllt.

Die einzelnen Einträge sind somit Seiten, welche über einen Titel und eine Inhaltsangabe verfügen. Damit sich das publiziert Datum der Seite nicht ädert, verwende ich bei den Seiteneigenschaften das Feld Letzte Änderung.

 

Sobald ich einen neuen Artikel im RSS Feed anzeigen will, bearbeite ich das Content Element und füge die gewünschte Seite hinzu.

Um einen RSS Feed zu erstellen benötigt man somit eine XML Datei, den typoscript Aufbau und das einbinden des Codes in eine Seite.

Alle unteren Code Beispiele sind im oberen Absatz ebenfalls verlinkt. Die gelb markierten Zeilen müssen entsprechend angepasst werden. Wichtig ist, das die Seiten ID und die Content Element ID richtig angegeben werden!

Das war mein erster Artikel, Feedback ist Willkommen ;-)

XML Datei

<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom">
	<channel>
		<atom:link href="###RSS_link###" rel="self" type="application/rss+xml" />

		<title>###RSS_title###</title>
		<link>###RSS_link###</link>
		<description>###RSS_description###</description>
		<copyright>###RSS_copyright###</copyright>
		<language>###RSS_language###</language>
		<image>
			<title>###RSS_title###</title>
			<url>###RSS_image_url###</url>
			<link>###RSS_image_link###</link>
			<width>###RSS_image_width###</width>
			<height>###RSS_image_height###</height>
			<description>###RSS_image_description###</description>
		</image>

		<docs>http://blogs.law.harvard.edu/tech/rss</docs>

		<pubDate>###RSS_pubDate###</pubDate>
		<lastBuildDate>###RSS_lastBuildDate###</lastBuildDate>

		###RSS_ITEMS###

	</channel>
</rss>
rss.xml
typoscript RSS Aufbau

# rss template erstellen
temp.rssTemplate = COA
temp.rssTemplate {

  1 = LOAD_REGISTER
  1 {
  # config
    # type, welche auf URL passt : index.php?type=200
    type = 200
    # hier die ID von Seite angeben, bei welcher das Content Element zu finden ist
    pageid = XY ( <= zahl angeben )
    # hier die ID von Content Element angeben
    contentid = XY ( <= zahl angeben )

    title = Titel des RSS Feeds
    description = Beschreibung zum RSS Feed
    copyright = copyright angaben
    # sprache festlegen
    language = de

    # icon angaben
    image_width = 128
    image_height = 128
    image_description = Beschreibung zum RSS Feed
    image_url = pfad-zu-datei/ico_rss_128x128.png

    # default wert, wenn es nicht bei den eigenschaften der seite (item) hinterlegt ist
    item_author = author
    item_author_email = author@example.ch
  }

  10 = TEMPLATE
  10 {

    # template einbinden
    template = FILE
    template.file = pfad-zu-datei/rss.xml

    marks {

      RSS_title = TEXT
      RSS_title.data = register:title

      RSS_description = TEXT
      RSS_description.data = register:description

      RSS_link = TEXT
      RSS_link.value = {getIndpEnv:TYPO3_SITE_URL}index.php?type={register:type}
      RSS_link.insertData = 1

      RSS_copyright = TEXT
      RSS_copyright.data = register:copyright

      RSS_language = TEXT
      RSS_language.data = register:language

      RSS_image_url = TEXT
      RSS_image_url.value = {getIndpEnv:TYPO3_SITE_URL}{register:image_url}
      RSS_image_url.insertData = 1

      RSS_image_link = TEXT
      RSS_image_link.value = {getIndpEnv:TYPO3_SITE_URL}index.php?type={register:type}
      RSS_image_link.insertData = 1

      RSS_image_width = TEXT
      RSS_image_width.data = register:image_width

      RSS_image_height = TEXT
      RSS_image_height.data = register:image_height

      RSS_image_description = TEXT
      RSS_image_description.data = register:image_description

      RSS_pubDate = TEXT
      RSS_pubDate {
        data = register:SYS_LASTCHANGED
        date = r
      }

      RSS_lastBuildDate = TEXT
      RSS_lastBuildDate {
        data = register:SYS_LASTCHANGED
        date = r
      }

      RSS_ITEMS = COA
      RSS_ITEMS {
        1 = LOAD_REGISTER
        1 {
          # auslesen den Content Elements (Menü dieser Seiten)
          pages.cObject = CONTENT
          pages.cObject {
            table = tt_content

            select {
              pidInList.dataWrap = {register:pageid}
              where.dataWrap = uid= {register:contentid}
              languageField = sys_language_uid
              insertData = 1
            }

            renderObj = TEXT
            renderObj {
              field = pages
            }
          }
        }

        # zum erstellen der ITEMS wird ein HMENU verwendet
        10 = HMENU
        10 {
          special = list
          special.value.data = register:pages
          wrap = |
          1 = TMENU
          1 {
            target = {$PAGE_TARGET}
            noBlur = 1

            NO {
              doNotLinkIt = 1
              doNotShowLink = 1
              stdWrap2 {
                # diverese informationen aufbereiten
                cObject = COA
                cObject {
                  1 = LOAD_REGISTER
                  1 {
                    title {
                      field = title
                      htmlSpecialChars = 1
                    }

                    subtitle {
                      field = subtitle
                      noTrimWrap = | : | |
                      required = 1
                      htmlSpecialChars = 1
                    }

                    link_and_guid {
                      typolink {
                        parameter.field = uid
                        returnLast = url
                      }
                      wrap = {getIndpEnv:TYPO3_SITE_URL}|
                      insertData = 1
                    }

                    guid.cObject = TEXT
                    guid.cObject {
                      value = {getIndpEnv:TYPO3_SITE_URL}index.php?id={field:uid}
                      insertData = 1
                    }

                    page_author_email {
                      data = field:author_email // register:item_author_email
                    }
                  }

                  10 = TEXT
                  10 {
                    data = field:abstract // field:description
                    wrap = <description><![CDATA[|]]></description>
                    required = 1
                    htmlSpecialChars = 1
                    # output kosmetik
                    prepend = TEXT
                    prepend.char = 10
                    append = TEXT
                    append.char = 10
                  }

                  15 = TEXT
                  15 {
                    data = field:author // register:item_author
                    wrap = <author>{register:page_author_email} (|)</author>
                    insertData = 1
                    required = 1
                    # output kosmetik
                    append = TEXT
                    append.char = 10
                  }

                  40 = TEXT
                  40 {
                    wrap = <pubDate>|</pubDate>
                    data = field:lastUpdated // field:tstamp // field:crdate
                    date = r
                    # output kosmetik
                    append = TEXT
                    append.char = 10
                  }

                }
              }

              allWrap (
              <item>
                <title>{register:title}{register:subtitle}</title>
                <link>{register:link_and_guid}</link>
                <guid>{register:guid}</guid>
                |
              </item>
              )
              allWrap.insertData = 1
            }

          }
        }
      }
    }

  }
}
template.ts
PAGE erstellen und RSS Template einbinden

# rss template einbinden
<INCLUDE_TYPOSCRIPT: source="FILE:pfad-zu-datei/template.ts">

# rss feed erstellen
rss200 = PAGE
rss200 {
	typeNum = 200
	config {
		# keine header daten aus TYPO3
		disableAllHeaderCode = 1
		# type und charset anpassen
		additionalHeaders = Content-type:text/xml;charset=utf-8
		# nicht zwingend noetig...
		linkVars = L,debug
		# seite darf nicht gecacht werden
		no_cache = 1
		# cleaning deaktivieren
		xhtml_cleaning = 0
		# kein adminpanel anzeigen
		admPanel = 0
	}

	# template einbinden
	10 < temp.rssTemplate
}
setup.ts