Categories
Dev

RSS Feed mit PHP bauen

Disclaimer: This is a new version of my RSS Feed Turorial from 2008, as it still gets a decent amount of traffic from Google. Hope it still helps 15 years later.

Einen RSS Feed kann man kinderleicht für seine dynamische Website, zum Beispiel ein News Script, erstellen. Dafür ist nur die Kenntnis vom Aufbau einer RSS Datei plus eine einfache Datenbankabfrage notwendig. Hier wird gezeigt wie man einen solchen dynamische generierten RSS Feed manuell zusammenstellt.

Einleitung

Als Vorwissen für dieses Tutorial benötigt man Kenntnisse in php und mysql. Ziel ist es ein kleines php Script zu schreiben, das auf Basis von Daten aus einer mysql o.ä. Datenbank dynamisch einen RSS Feed generiert.

Zuerst muss man sich entscheiden auf welchen RSS Standard man zurück greifen will. Es gibt diverse Standards, die man auch gängig bei anderen Seiten finden kann – zB. RSS0.91, RSS1.0 und RSS2.0 (mehr dazu hier). Wir werden in diesem Tutorial einen RSS2.0 Feed erstellen.

Dokument Definition

Als erstes erstellen wir in einem Editor eine leere Datei und fügen folgenden Header Code in die ersten Zeilen ein:

<?xml version="1.0" encoding="ISO-8859-1" ?> 
<rss version="2.0"> 
<channel> 

Hier wird erstmal definiert um was für ein Dokument es sich hier eigentlich handelt bzw. die XML DTD dazu bestimmt. Die Tags “<rss>” und ” <channel>” sind die Basis Element eines RSS Feeds. Da wir einen Dynamischen RSS Feed haben wollen und die erstellende Datei eine php Script beinhaltet, muss die erste Zeile, die XML Definition, mit einem echo ausgegeben werden, da sonst der php Interpretor auf das “?” mit einem Parse Error reagiert.

<?xml version="1.0" encoding="ISO-8859-1" ?>" 

Weiters muss hier dem Browser der content type mitgeteilt werden, da dieser sonst den Inhalt als Html und icht als xml ausgibt. Die ganze veränderte Zeile sieht dann wie folgt aus:

<?php header("Content-type: text/xml"); 
echo "<?xml version="1.0" encoding="ISO-8859-1" ?>"; ?>

Meta Daten

Nachdem wir nun die Stammelemente plus die xml Definition erstellt haben machen wir uns an die Meta Daten des Feeds. Die sehen bei RSS2.0 folgendermaßen aussehen und sind meistens statisch. Die Elemente hier sind selbsterklärend. Beim Tag “lastBuildDate” könnte man zum Beispiel mit <?php $now = time(); echo $now; ?> zur Script Laufzeit das aktuelle Datum einsetzen.

<title>Website name</title>
<link>http://www.beispiel.de</link>
<description>Beschreibung von Website</description>
<language>de-de</language>
<pubDate>Datum der Erstellung</pubDate>
<lastBuildDate>Datum des letzten Outputs, in vielen Fällen die Ausführzeit des Scriptes</lastBuildDate>
<docs>http://www.beispiel.to/rss.php</docs>
<generator>Rss Feed Engine</generator>
<managingEditor>info@beispiel.de</managingEditor>
<webMaster>info@beispiel.de</webMaster>

Elemente

Nun da die Meta Elemente ausgefüllt sind ist der nächste Schritt die einzelnen News Elemente des z.B. News Scipts in RSS konforme Daten zu konvertieren. Die Struktur eines Items sieht dabei so aus. Ein Feed kann beliebig viele Items beinhalten aber es macht Sinn diese auf ca. 10-20 Elemente zu beschränken.

<item>
<title>Beispiel Titel</title>
<link>http://www.beispiel.de/link</link>
<description>Beispiel Beschreibung, Text, Bilder etc. Die Description kann auch einen Excerpt (Auszug) des vollen Beitragtextes enthalten.</description>
<pubDate>Datum der Veröffentlichung des Beitrags</pubDate>
<guid>http://www.beispiel.de/link</guid>
</item>

Dieses Template eines Items füllen wir nun mittels einer Datenbank Abfrage o.ä. mit Daten. Der dazu passende Code könnte z.B. so aussehen:

<?php require('mysql_connect.php'); 
$SqlSelect = "SELECT link, pic, titel, text FROM news LIMIT 0,20"; 
$result = mysql_query($SqlSelect); 
if (!$result) { die('Invalid query: ' . mysql_error()); } 

while ($row = mysql_fetch_assoc($result)) { ?> 
<item> 
<title><?php echo $row['titel']; ?></title> 
<link> <?php echo $row['link']; ?> </link> 
<pubDate> Wenn vorhanden Timestamp des Beitrages, ansonst einfach weg lassen </pubDate> 
<description> <?php echo "<img src=\"".$row['pic']."\"></img></a>"; ?> <?php echo $row['text']; ?> </description> 
</item> <?php } 
mysql_free_result($result); 
mysql_close($dbh); 
?>

Zum Schluss schließen wir noch die beiden Stammelemente channel und rss am Ende des Dokumentes.

</channel>
</rss>

Um jetzt den erstellten Dynamischen RSS Feed auf der Hauptseite einzufügen und ihn für die Browser erkennbar zu machen, muss man foolgende Zeile in den Kopf der Hauptseite schreiben:

<link rel="alternate" type="application/rss+xml" title="RSS" href="http://www.beispiel.de/rss.php" />

Hier die fertigen Datei:

<?php header("Content-type: text/xml");
echo "<?xml version=\"1.0\" encoding=\"ISO-8859-1\" ?>"; ?>
<rss version="2.0">
<channel> 
	<title>Website name</title>
	<link>http://www.beispiel.de</link>
	<description>Beschreibung von Website</description>
	<language>de-de</language>
	<pubDate>Datum der Erstellung</pubDate>
	<lastBuildDate>Datum des letzten Outputs, in vielen Fällen die Ausführzeit des Scriptes</lastBuildDate>
	<docs>http://www.beispiel.to/rss.php</docs>
	<generator>Rss Feed Engine</generator>
	<managingEditor>info@beispiel.de</managingEditor>
	<webMaster>info@beispiel.de</webMaster>

<?php
require('mysql_connect.php');

$SqlSelect = "SELECT link, pic, titel, text FROM news LIMIT 0,20";
	$result = mysql_query($SqlSelect);

	if (!$result)	{	    die('Invalid query: ' . mysql_error());	}
	
	while ($row = mysql_fetch_assoc($result))	{
	
?>
	<item>
	<title><?php echo $row['titel']; ?></title>	
	<link>
	<?php echo $row['link']; ?>
	</link>	
	<pubDate>
	Wenn vorhanden Timestamp des Beitrages, ansonst einfach weg lassen
	</pubDate>
	<description>
	<?php echo "<img src=\"".$row['pic']."\"></img></a>"; ?>
	<?php  echo $row['text']; ?>
	</description>
	</item>

<?php
	}
mysql_free_result($result);
mysql_close($dbh);
?>

</channel>
</rss>
Categories
Dev Thinktank

How to create an AI driven content machine for your website

Simple AI tools and the connection of them makes it very easy to create large amounts of content (here in the example text) for your blog, website etc. All tools I used here are free and easy to handle.

Step 1: ask chatgpt to create a list of popular items of any category you are interest in. In my example I asked it for the most popular DOS Games with some data of additional information:

Chatgpt will return you a handy table that you can easily further process. The data is nice, but we need some more text and therefore we are going to query chatgpt for each of the game for a summary. You can do this also in the normal prompt screen, but this would take very long. I am using for this a Google Sheet with the GTP for work plugin, that allows you to use the chatgpt als normal Google Sheet functions.

Step 2: Add some more content in a Google Sheet. When you copy/paste the table it will look something like this:

I already added another column Summary where then we want chatgpt to generate our text for each game. To do that we use a simple function:

After some time the request will be filled with a text comparably to mine:

You can add the details or specifics you want to have in your text. Quick hint on the prompt: chatgpt tends to just end longer texts in the middle of a sentence, so to trick it here tell in the prompt you want a 1.500 word summary and the only the first 750 words should be displayed. With this little tweak you will avoid having cut off texts.

As we are in a Google Sheet, the only thing we have to do now is to extend the function to all other rows below and let chatgpt produce the 100 texts. Having our complete texts we can go the next step and get the data into our wordpress Blog. Doing so we use zapier.

Step 3: Import the data als new content to your wordpress blog. Create a new transfer with your source “Google Sheets” and destination “WordPress Blog”.

In the next step choose the Google Sheet File from the dropdown:

Your WordPress also needs some preparation and you need to install the zapier plugin there, so that the app can communicate properly with the blog system:

Next we need to connect our WordPress blog and enter the credentials:

And then we can put everything together and tell zapier which data to use from the Sheet to create our new blog post (you can also create pages or attachments with images):

You can also use HTML in some fields like the Content to create more advanced entries. For the game example here we could create a little table at the top showing all the additional data we have. In the next step you can then review the full dataset and choose which one zapier should transfer.

Final result: the post in WordPress:

If you have chosen the full 100 dataset you will have 100 new posts in your blog. Some constraints from the zapier/Wordpress connection: As you can also see in the screenshot the plugin uses the old classic editor and not the new block editor. Also there are no links in the posts, which are to add in another step.

To fully automate the flow, create a new Zap from the transfer in zapier and let the process run each time a new row has been added to the Sheet. So all you have to do then, is add the row with the name of a new game and the chatgpt function will create your text and the zapier zap will import it automatically to your blog.

Categories
Dev

WordPress: Blog unter gleichen Domains

WordPress greift für seine URL-Generierung auf 2 Konstanten zurück die über die Optionen eingestellt werden können. Man kann aber auch die URL zur Laufzeit in der wp_config.php ändern. Warum will man das? – Der Usecase bei mir ist, dass 2 Domains auf das selbe Blog zeigen, aber es keine Weiterleitung geben soll. Sprich ich will 2 Seiten mit eigenen URLs und identischen Content.

Umsetzung: Man untersucht den Host der Anfrage und setzt je nach dem die 2 Konstanten neu. Ist die Bedingung nicht erfüllt macht man gar nichts und es greifen die Einstellungen aus den Optionen.

if ($_SERVER['HTTP_HOST'] == "mobilepulse.de") {
define('WP_HOME','http://mobilepulse.de');
define('WP_SITEURL','http://mobilepulse.de');
} else if ($_SERVER['HTTP_HOST'] == "mobilepulse.at") {
define('WP_HOME','http://mobilepulse.at');
define('WP_SITEURL','http://mobilepulse.at');
}

Surft man jetzt die Seite an bleibt die generierte URL gleich der ursprünglich angefragten Domain und wechselt nicht auf die Hauptdomain (mobilepulse.at -> mobilepulse.at).

Categories
Dev

Wordpres 2.7 Pingback Probleme

WordPress 2.7 hat durch einen schweren Softwarefehler Probleme andere Blogs anzupingen. Aus irgendeinem Grund wurde der Timeout für einen Pingback auf 0.01 Sekunden anstelle 1 abgesenkt. Das führte praktisch dazu, dass keine Trackbacks und Pingbacks mehr funktionierten. Es gibt aber eine einfache Lösung für das Problem:

wp-includes/cron.php Zeile 200:

wp_remote_post($cron_url, array('timeout' => 0.01, 'blocking' => false));

ändern zu:


wp_remote_post($cron_url, array('timeout' => 1, 'blocking' => false));

Im Bugfix Release 2.71 wird der Fehler dann auch gefixt sein.

Categories
Dev

phpbb3 mysql4 zu mysql5 Update

In den letzten Tagen habe ich mir Zeit genommen einige meiner Domains/Webseiten auf einen neuen Ubuntu Server zu transferieren. Sie waren auf einem opensuse. Dank der tollen Migrations-Funktion von Plesk kann man 1:1 seine gesamte Konfig von einem Server zum anderen übertragen. Probleme gabs damit soweit nicht. Beim check der Webseiten kam aber bei einer phpbb3 Installation böses Erwachen: Durch den Umstieg von mysql4 auf mysql5 gabs hier einige Probleme. Dazu einige Hilfestellungen aus den Support Foren:

Default Values Queries
Spaltenlänge bbcode_uid

Man beachte: beide Datenbanken SIND utf8!!. Zum einen hat der DB Layer von phpbb3 Probleme mit Querys, da MySQL5 keine Default Values mehr hat und alle Querys alá “insert into xx value (”, 2, “uuu”)” aussahen. Dafür gibts aber ein offizielles Script. Drüber laufen lassen -> Beiträge können erstellt werden. Oder doch nicht..? Fehlermeldung “Data too long for column ‘bbcode_uid’ at row 1” -> Lösung: Einfach die Spaltenlänge von bbcode_uid auf 8 erhöhen. Dann noch die Probleme mit der fehlerhaften Encodierung (komischerweise ist nur die Tabelle phpbb_posts betroffen) mit folgenden SQl Script fixen:

UPDATE phpbb_posts SET post_text = REPLACE(post_text, 'ß', 'ß') WHERE post_text LIKE '%ß%';
UPDATE phpbb_posts SET post_text = REPLACE(post_text, '´', '') WHERE post_text LIKE '%´%';
UPDATE phpbb_posts SET post_text = REPLACE(post_text, 'ä', 'ä') WHERE post_text LIKE '%ä%';
UPDATE phpbb_posts SET post_text = REPLACE(post_text, 'ö', 'ö') WHERE post_text LIKE '%ö%';
UPDATE phpbb_posts SET post_text = REPLACE(post_text, 'ü', 'ü') WHERE post_text LIKE '%ü%';
UPDATE phpbb_posts SET post_text = REPLACE(post_text, 'Ä', 'Ä') WHERE post_text LIKE '%Ä%';
UPDATE phpbb_posts SET post_subject = REPLACE(post_subject, 'ß', 'ß') WHERE post_subject LIKE '%ß%';
UPDATE phpbb_posts SET post_subject = REPLACE(post_subject, '´', '') WHERE post_subject LIKE '%´%';
UPDATE phpbb_posts SET post_subject = REPLACE(post_subject, 'ä', 'ä') WHERE post_subject LIKE '%ä%';
UPDATE phpbb_posts SET post_subject = REPLACE(post_subject, 'ö', 'ö') WHERE post_subject LIKE '%ö%';
UPDATE phpbb_posts SET post_subject = REPLACE(post_subject, 'ü', 'ü') WHERE post_subject LIKE '%ü%';
UPDATE phpbb_posts SET post_subject = REPLACE(post_subject, 'Ä', 'Ä') WHERE post_subject LIKE '%Ä%';
UPDATE phpbb_users SET user_sig = REPLACE(user_sig, 'ß', 'ß') WHERE user_sig LIKE '%ß%';
UPDATE phpbb_users SET user_sig = REPLACE(user_sig, '´', '') WHERE user_sig LIKE '%´%';
UPDATE phpbb_users SET user_sig = REPLACE(user_sig, 'ä', 'ä') WHERE user_sig LIKE '%ä%';
UPDATE phpbb_users SET user_sig = REPLACE(user_sig, 'ö', 'ö') WHERE user_sig LIKE '%ö%';
UPDATE phpbb_users SET user_sig = REPLACE(user_sig, 'ü', 'ü') WHERE user_sig LIKE '%ü%';
UPDATE phpbb_users SET user_sig = REPLACE(user_sig, 'Ä', 'Ä') WHERE user_sig LIKE '%Ä%';
UPDATE phpbb_topics SET topic_title = REPLACE(topic_title, 'ß', 'ß') WHERE topic_title LIKE '%ß%';
UPDATE phpbb_topics SET topic_title = REPLACE(topic_title, '´', '') WHERE topic_title LIKE '%´%';
UPDATE phpbb_topics SET topic_title = REPLACE(topic_title, 'ä', 'ä') WHERE topic_title LIKE '%ä%';
UPDATE phpbb_topics SET topic_title = REPLACE(topic_title, 'ö', 'ö') WHERE topic_title LIKE '%ö%';
UPDATE phpbb_topics SET topic_title = REPLACE(topic_title, 'ü', 'ü') WHERE topic_title LIKE '%ü%';
UPDATE phpbb_topics SET topic_title = REPLACE(topic_title, 'Ä', 'Ä') WHERE topic_title LIKE '%Ä%';

also noch mal im Detail die Reihenfolge (angenommen man hat einen kompletten Dump in der neuen DB eingespielt und realisiert dass einiges nicht funktioniert):

  1. mysql4 -> mysql5 Upgrade Script Ausführen und SQL am Server exekutieren
  2. Die Länge der Spalte “bbcode_uid” in der Tabelle phpbb_posts auf 8 erhöhen
  3. komplette Spalte phpbb_posts trunkieren
  4. Dump nur für diese Tabelle wieder einspielen
  5. Encoder Fix SQL ausführen
  6. Fertig
Categories
Dev

Wechsel zu Netbeans 6.5

Brandneu ist das Final Release der neuen major Netbeans Version. Netbeans 6.5 bringt viele Neuerungen – vor allem für nicht Java Entwickler, welche die IDE auch für andere Sprachen nutzen wollen. Ich bin ja ein Anwender, der neben Java, Java Mobile Projekten vorrangig Dinge in php – neuerdings auch groovy – codet. Für meinen Anwendungsbereich bietet mir als das neue Netbeans alles was ich brauche in einer IDE. Hat den riesigen Vorteil, dass ich mich nicht permanent, wenn ich beispielsweise ein php Projekt mache neue Hotkeys merken muss und ständig falsche Funktionen in den unterschiedlichen IDEs suche.

War bis dato so, dass ich für meine php Dinge das Zend Studio für Eclipse verwendet hab. Das war auch ganz nett. Was mir aber Netbeans 6.5 in Bezug auf php bieten kann hat mich überzeugt. Einzig das profilling mach ich noch im Zend Studio. Die Grails Unterstützung ist die beste, die man momentan für eine IDE bekommen kann.

Also war der Wechsel beschlossene Sache. Verlief eigentlich alles reibungslos. Alle alten Projekte wurden perfekt übernommen. Das alte Problem bestand noch immer, dass meine Web Projekte die Server Zuordnung verloren haben (Wechsel von Glassfish 2 -> 3). War aber kein Problem das im Nachhinein zu konfigurieren. Nun hab ich endlich eine IDE für fast alles – danke Netbeans.

Categories
Dev

Google Ajax Lib API

Google hat ja gestern ihre AJAX Libary API vorgestellt. Im Prinzip ist diese API ja nichts anderes als ein Ersatz für die Speicherung der Libs am eigenen Server. Die API bietet dabei die bekanntesten Vertreter an:

  • jQuery
  • prototype
  • script.aculo.us
  • MooTools
  • dojo

Sie erlaubt den Zugriff auf die jeweiligen JS File einerseits über ein URL:


als auch über den Google AJAX Loader:
google.load("jquery", "1");

Den Vorteil den die AJAX Lib API mit sich bringt ist mit der oben angeführten Syntax, dass automatisch immer die letzte Version der Libary eingebunden wird. Ein manuelles Updaten der Files am eigenen Server entfällt dadurch völlig. Natürlich ist auch das einbinden einer bestimmten Version und ein komprimiertes File möglich:

google.load("jquery", "1.2", {uncompressed:true});

Für mehr Infos zur Funktionsweise der sehr simplen API gibts eine kleine Doku.

Categories
Dev

JS Port of Processing

John Resig is really the man. He just ported the processing language into a javascript api. For drawing the forms he is using the canvas object, so unfortunately the api won’t work in older browsers who don’t support it. Nevertheless awesome work.

Categories
Dev

Awsome JS Editor in Netbeans


Yeah, netbeans rocks that’s for sure. Look at this sophisticating autocoplete feature hitting netbeans in its new 6.1 release. Also have a look at the screencast of Roman Strobl explaining the key features of the new javascript editor.

Categories
Dev

JavaDeus08

Irgendwer der auch hingeht?