Hit or Miss

How to manage your site with Blogger, PHP, and XML

How to manage your site with Blogger, PHP, and XML

This tutorial is a modification (i.e. plagiarism) of Paul Bausch‘s Blogger, XML, ASP tutorial.

BONUS! Syndicating your blog over the telephone with the VoiceXML Tutorial.

The Basics

This document will show you how to use Blogger (a free weblog service) to store your site information in XML and then transform that XML into HTML on your server using PHP.

Why would I want to do this?

“What could you possibly be thinking?” you may say. “That sounds complex!” But this method gives you the convenience of publishing with Blogger and the flexibility of XML. After implementing an XML version of your site, you’ll be able to easily add features to your site that Blogger doesn’t offer. It also allows you to have more precise control over the look and feel of your site. It’s like having all of the power of server-side scripting with a database, without the database.

Requirements:

To implement the PHP code examples I have here, you’ll need to have access to a server running PHP 4.0 and have the prax.php file from PRAX (PHP Record-oriented API for XML) residing in the same directory as all the files we discuss below. If you’re running an older version of PHP without XML support, you could try using Jose Gonzalez’s Blogger/XML/PHP code, which uses brute force to go through the XML and display the HTML.

However, you could write the server-side code in just about any language you’re comfortable with on any platform. That’s the beauty of XML.

Word of Caution:

I am far from being a professional programmer. The following bits of code seem to work for me with my server (running Red Hat 7.0), but I can’t predict how they will work on your system. Hopefully, readers will add some comments below concerning any needed modifications for other set-ups.

Creating the XML entry files

The first step is creating an XML format to use for your site. I set up the following format for my team blog, Web Queeries. The <blog> section holds information about each post, grouped together in <day> sections. Each post is contained in the <body> tag. With extended information about each post (id, time posted, author) stored as attributes of the tag. The <head> section will hold any extended information I might need. It’s all then included under the <xblog&gt.

In your Blogger settings, you’ll want to change the blog filename to current.xml. All of your other settings can stay the same.

Next, you’ll need to set up your Blogger template to output XML instead of HTML. Use the following text as your blog template:

<?xml version=”1.0″ ?> <xblog> <head> <title>Title of My Blog</title> <description>A description of my blog.</description> <url>http://www.my-site.com</url> </head> <blog> <Blogger> <BlogDateHeader> <day date=”<$BlogDateHeaderDate$>”> </BlogDateHeader> <entry> <id><$BlogItemNumber$></id> <permalink><$BlogItemArchiveFileName$></permalink> <time><$BlogItemDateTime$></time> <author><$BlogItemAuthor$></author> <author_email><$BlogItemAuthorEmail$></author_email> <url><$BlogItemURL$></url> <body><![CDATA[<$BlogItemBody$>]]></body> </entry> <BlogDateFooter> </day> </BlogDateFooter> </Blogger> </blog> </xblog>

This will output a file that looks like this (If you’re not running IE 4+, you’ll need to save this file to your hard drive and open it in an editor to see it).

Note that we’re storing the post bodies in a CDATA section. This will allow you to store “bad” HTML in there. We’ll be transforming it with PHP on the server-side, so you won’t need to worry about this part being parsable.

Creating the XML Archive files

You’ll also need to come up with an XML format that holds the archive index information. Blogger stores two variables with each archive entry: the file name and the date range name. Here is a sample format that will store those two bits of information.

<?xml version=”1.0″ ?> <xblog> <Blogger> <archive> <archive_file><$BlogArchiveLink$></archive_file> <archive_title><$BlogArchiveName$></archive_title> </archive> </Blogger> </xblog>

Modify the archive index file name to be archive.xml.

Creating index.php

Next, we’ll need to create an index.php file which will interpret the XML of the entry files and display it on the screen as HTML.

The following bit of code does several other things as well:

The file looks for a template.php file (residing in the same directory), so that you can make all of your pages look the same.

The file also defaults to looking at the current.xml file for the entries, unless it is passed the varible archive which contains the name of the archive XML file.

<?php include(“template.php”); Print_Header(); if ($archive) { $file = $archive; } else { $file = “current.xml”; } # Include the RAX library include( “prax.php” ); # Create new RAX objectS $rax = new RAX(); $rec = new RAX(); # Open the XML document $rax->openfile($file); # Select the individual record delimiter $rax->record_delim = ‘entry’; # Start parsing the XML document $rax->parse(); # Read the first record $rec = $rax->readRecord(); while ( $rec ) { $row = $rec->getRow(); $body = $row[“body”]; $author = $row[“author”]; $author_email = $row[“author_email”]; $author_url = $row[“author_url”]; $id = $row[“id”]; $permalink = $row[“permalink”]; $time = $row[“time”]; print “<a name=$id></a>n”. “<b>$time</b>nn”. “<blockquote>n”; print “$body<p>nn”; print “<font size=-1 color=#666666>”. “Posted by <a href=mailto:$author_email>”. “$author</a> | <a href=index.php?archive=$permalink#$id>link me</a>.”. “</font><p>n”. “</blockquote>nn”; $rec = $rax->readRecord(); } Print_Footer(); ?>

If you don’t want to name this file index.php, you will need to change some of the code contained in this and the following files.

I’ll be honest — this XML parser script doesn’t work exactly like I would like it to. It’s currently not using the data found in the <head> section of the current.xml (or archive) file.

Also, I would like to be able to get access to the date variable in the day tag, so I could separate posts by the days they were published. But here is a simple workaround you can use. Set the time format in your settings to “DD/MM/YYYY HH:MM:SS PM” and then substitute the following code into index.php above.

list($date, $time) = split(” “, $time, 2); print “<a name=$id></a>n”; if ($date != $lastdate) { print “<b>$date</b>nn”; $lastdate = $date; }

Creating template.php

This file (template.php) will allow you create a standard look for all of your pages. Pretty simple.

<? // print everything above the content of your page function Print_Header() { ?> <html> <head><title>NAME OF YOUR BLOG</title></head> <body> <h1>NAME OF YOUR BLOG</h1> <p><a href=”index.php”>Current Entries</a> | <a href=”archive.php”>Archives</a> | <a href=”rss.php”>XML-RSS file</a>.</p> <? } // print everything below the content of your page function Print_Footer() { ?> <p><a href=”http://www.blogger.com”><img width=88 height=31 hspace=5 src=”blogger.gif” border=0 alt=”[Made with Blogger]”></a></p> </body> </html> <? } ?>

Creating archive.php

This file (archive.php) will display links to your archived entries. You’ll probably notice it’s pretty similar to index.php.

<? include(“template.php”); Print_Header(); print “<h3>Archives</h3>nn”; # Include the RAX library include( “prax.php” ); # Create new RAX objectS $rax = new RAX(); $rec = new RAX(); # Open the XML document $rax->openfile(“archive.xml”); # Select the individual record delimiter $rax->record_delim = ‘archive’; # Start parsing the XML document $rax->parse(); # Read the first record $rec = $rax->readRecord(); while ( $rec ) { $row = $rec->getRow(); $archive_file = $row[“archive_file”]; $archive_title = $row[“archive_title”]; print “<a href=index.php?archive=$archive_file>$archive_title</a>.<br>n”; $rec = $rax->readRecord(); } Print_Footer(); ?>

Creating a search function

It is fairly easy to add a search function to your weblog. First, you will need to add the following code somewhere in your template.php file.

<form action=”index.php”> <input type=text name=search size=15> <input type=submit value=”search”> </form>

Next, you will need to replace your index.php file with the following code.

<?php include(“template.php”); Print_Header(); if ($archive) { $files[0] = $archive; } else { $files[0] = “current.xml”; } if ($search) { $files[0] = “”; $x = 0; $handle=opendir(‘.’); while (false!==($file = readdir($handle))) { if (eregi(“.xml”, $file) && ($file != “current.xml”) && ($file != “archive.xml”)) { $files[$x] = $file; $x++; } } closedir($handle); rsort($files); } # Include the RAX library include( “prax.php” ); for ($x = 0; $x < sizeof($files); $x++) { # Create new RAX objectS $rax = new RAX(); $rec = new RAX(); # Open the XML document $rax->openfile($files[$x]); # Select the individual record delimiter $rax->record_delim = ‘entry’; # Start parsing the XML document $rax->parse(); # Read the first record $rec = $rax->readRecord(); while ( $rec ) { $row = $rec->getRow(); $body = $row[“body”]; $author = $row[“author”]; $author_email = $row[“author_email”]; $author_url = $row[“author_url”]; $id = $row[“id”]; $permalink = $row[“permalink”]; $time = $row[“time”]; if ((($search) && (eregi($search, $body))) || (!$search)) { list($date, $time) = split(” “, $time, 2); print “<a name=$id></a>n”; if ($date != $lastdate) { print “<b>$date</b>nn”; $lastdate = $date; } print “<blockquote>n”. “$body<p>nn”. “<font size=-1 color=#666666>”. “Posted by <a href=mailto:$author_email>”. “$author</a> | <a href=index.php?archive=$permalink#$id>link me</a>.”. “</font><p>n”. “</blockquote><br>nn”; } $rec = $rax->readRecord(); } } Print_Footer(); ?>

This will allow you to search for single words or phrases in the text of the blog entries. If you know a little bit of PHP, it should be easy to create a search feature that would, for example, display all posts from a certain writer in a group blog or display all posts between two dates.

Syndicating your blog via XML-RSS

Okay, here’s where we really get to a huge payoff that makes all this complicated XML worth it. The following file (rss.php) creates XML-RSS formated output that can syndicate the content of your blog to other places. For example, you could register your blog as a channel at xmltree or my.userland.com.

This will output a file that looks like this (Again, if you’re not running IE 4+, you’ll need to save this file to your hard drive and open it in an editor to see it).

<?php header(“Content-Type: text/xml”); header(“Pragma: no-cache”); print “<?xml version=”1.0″?>nn”; print “<!DOCTYPE rss PUBLIC “-//Netscape Communications//DTD RSS 0.91//EN””. ” “http://my.netscape.com/publish/formats/rss-0.91.dtd”>nn”; print “<rss version=”0.91″>n”; ?> <channel> <title>NAME OF YOUR BLOG</title> <link>http://www.your-site.com</link> <description>this is the description of your blog</description> <language>en-us</language> <? # Include the RAX library include( “prax.php” ); # Create new RAX objectS $rax = new RAX(); $rec = new RAX(); # Open the XML document $rax->openfile(“current.xml”); # Select the individual record delimiter $rax->record_delim = ‘entry’; # Start parsing the XML document $rax->parse(); # Read the first record $rec = $rax->readRecord(); while ( $rec ) { $row = $rec->getRow(); $body = $row[“body”]; $author = $row[“author”]; $author_email = $row[“author_email”]; $author_url = $row[“author_url”]; $id_num = $row[“id”]; $permalink = $row[“permalink”]; $time = $row[“time”]; # this gets rid of any html tags in your body of the entry $body = strip_tags($body); # this gets rid of quotes and quotation marks, which can upset the xml format $body = ereg_replace (“‘”, “”, $body); $body = ereg_replace (‘”‘, “”, $body); # this splits (hopefully) the first sentence of your post off to serve as a # a title to the entry list ($title, $description) = split (‘[.!?][[:space:]]’, $body, 2); if (!ereg(“.”, $title)) { $title = $title.”.”; } print “<item>n”; print “<title>”.$title.”</title>n”; print “<link>http://www.your-site.com/?archive=$permalink#$id_num</link>n”; print “<description>”.$description.”</description>n”; print “</item>nn”; $rec = $rax->readRecord(); } ?> </channel> </rss>

Again, this bit of code isn’t fail proof. It tries to cut off the first sentence of your post to use as a title to the entry (by looking for . ? or !), but will not work properly if you have abbreviations (like vs.) in your first sentence. C’est la vie! Nothing’s ever perfect.

Links to the files used

I’ve been asked to put all the files used above into a .zip file, but I prefer not to do that because I’m continuing to make updates and corrections to the code. But I will provide the following links to the source files. Just right-click on the link and select Save to Disk.

And finally, for this whole thing to work, you need to save this file in your directory.

Conclusion and Ackowledgments

XML is a very flexible format for storing your blog. If you have the ability to do some server-side scripting, you can extend Blogger in new ways. For example, on Web Queeries I’ve been able to develop my own comments system using PHP & MySQL.

This is just the beginning of an system that you can build to suit your own needs. Good luck and happy XML-blogging!

Thanks to all the wonderful people at Pyra for making Blogger such a cool tool (maybe someday they’ll make some more t-shirts).

9 responses so far (Respond)

Gravatar

Does this work?

Mike | 15 Jun 2005
Gravatar

Hmmm I’d like to get the php for the comment section!

Mike | 15 Jun 2005
Gravatar

Just wondering. In the index.php file…how the conditional statement work so that if you click on an “archive” it goes to that xml file instead of the current xml file? It seems you declared the $archive variable, but nothing is assigned to it? confused.

Keith | 6 Jul 2005
Gravatar

I dont think this tutorial works anymore..

for one the Prax website is dead…

DrDel | 11 Nov 2005
Gravatar

How can i become a saint?

Merwin Pack | 30 Jan 2007
Gravatar

does this mean, you can create your own template using this? Ugh… all of this seem new to me… could u explain what i needed to download first… PHP, etc… coz when i clicked the PHP site, it has like many downloads to choose from… I’m confused..

veear | 2 May 2008
Gravatar

I haven’t tried this yet, but am looking forward to giving it a go soon. I have made Blogger 1.0 and 2.0 templates but haven’t tried publishing in XML.

Can you use the Blogger 2.0 widgets when you publish in XML to an external server, or does it need to be hosted by Blogger?

Jonah Dempcy | 2 Jun 2008
Gravatar

Does this work?

Mike | 4 Nov 2009
Gravatar

This does not really work any more that much, although geeks would still love to do their own thing. With blogger, there are tons of templates to download now that you dont need to worry on making one your own.

Pimpz | 4 Jun 2012