Heaven! Finally managed to get a couple of php scripts working to my satisfaction for my blog suite; suite being the operative word. Of course, it’s powered by Movable Type (you mean there’s anything else? … more on that anon) and while I really love MT (reasons, too, anon), what I really wanted was much more organisation and hierarchical structuring than just a single blog.
The categories feature didn’t really do it for me; not enough anyway. You still had a single page with all kinds of stuff on it and I’ve found hunting through blogs can be really tedious.
What I thought was this: I’d have a set of blogs. Each blog covers one major area of interest: thus, politics, history, art, books/language, humour, food & wine, and so on. The posts in each blog are categorised. The geekspeak blog, for example, deals with technology and the categories include email, blogging etc. This is kind of neat and tidy — you don’t end up looking in posts on history and Dubya for stuff on blogging and PHP.
THE COLLATION PROBLEM
The real trick was, however, to default the first main blog (blog_id= 1) into a non-blog blog. That is, it’s a blog for the purposes of configuration in MT, but that’s all. It has a single page (the main index file) no archives and no entries are made to this blog. Instead, this blog pulls material from the other blogs. In short, I have a multi- blog MT installation, with one parent blog and the rest as ‘feeder’ blogs from which the parent blogs pulls its material.
THE MULTIPLE BLOG SCENARIO
So far so good; but, immediately, trouble. How do you get the parent blog to constantly refresh its material? What I wanted was this:
THE EXISTING SOLUTIONS IN MOVABLE TYPE
MT does have some solutions in the form of MT plugins , notably from David Raynes. His Other Blog has some of these features.
Unfortunately, it has two significant limitations: first, it demands that the blog on which it is used (the target blog, in this case my home page ) must be rebuilt to correctly reflect the updates on the source blogs. Second, it completely cracks up when dealing with any sort of archive. It just won’t work outside an index template.
That’s not good. So, I dug deeper and found two more plugins: David Raynes’ own Whole System and Stepan Riha’s Global Listings plugin. I didn’t try either because I figured that almost anything that is an MT plugin must demand a rebuild; and that I most certainly don’t want.
Both are said to be similar to a straight PHP script (not an MT Plugin) from the amazing Scripty Goddess. She has an absolute cracker of a MT hack, called the Multiple Blog Updates List. Her script page also references two other PHP solutions for ordered updates and a portal tutorial, both worth checking out. I looked at these briefly and didn’t like them. The ordered updates thread uses Server Side Includes and shtml files, which I wanted to avoid since they don’t directly reference the mysql database; and the portal tutorial also seems to rely quite a lot on MT Tags (maybe I’m wrong, but that’s the impression I got).
TWEAKING THE SCRIPTY GODDESS
:-) That’s in a lighter vein, I hope she won’t mind the caption. Anyway, I took the SG script and it worked all right, but I realized soon enough that it needed major tweaking. In its original form, it has at least these limitations:
I rewrote large chunks of the script, and now I use this:
<?
//connection info
include ("/users/mcavity.com/httpdocs/connect.php");
//for each of the selected blogs (2, 3, 4) in mt_blog, find and display in descending order the most recent post in mt_entry.
$alldata = array();
$alldates = array();
$blogcount=0; // keep track of number of blogs
$blogarray = "SELECT blog_id, blog_site_url, blog_name, blog_description FROM mt_blog WHERE NOT (blog_id = 1)";
$resultblog = mysql_query($blogarray) or die (mysql_error());
while ($rowblog = mysql_fetch_array($resultblog)) {
$burl = ($rowblog['blog_site_url']);
$bname = ($rowblog['blog_name']);
$bdesc = ($rowblog['blog_description']);
$rowarray = "SELECT entry_created_on, entry_id, entry_blog_id, entry_title FROM mt_entry WHERE (entry_blog_id = (".$rowblog['blog_id'].")) ORDER BY entry_created_on DESC";
$resultid = mysql_query($rowarray) or die (mysql_error());
if (mysql_num_rows($resultid) > 0) {
$count=0;
while ($rowid = mysql_fetch_array($resultid)) {
// if ($count>0) { break; }
$maxarray = "SELECT entry_title, entry_blog_id, entry_id, entry_created_on, entry_excerpt, entry_text, entry_text_more, trackback_blog_id, trackback_created_on, trackback_entry_id, trackback_url FROM mt_entry, mt_trackback WHERE entry_id = ".$rowid['entry_id']." and trackback_entry_id = entry_id ORDER by trackback_created_on DESC";
$resultmax = mysql_query($maxarray) or die (mysql_error());
while ($rowmax = mysql_fetch_array($resultmax)) {
$ids = array($rowmax['entry_id']);
$blogid = ($rowmax['entry_blog_id']);
$tburl = ($rowmax['trackback_url']);
$date = ($rowmax['entry_created_on']);
$title = ($rowmax['entry_title']);
$excerpt = ($rowmax['entry_excerpt']);
$text = ($rowmax['entry_text']);
$textmore = ($rowmax['entry_text_more']);
//saves the data int alldata array for use outside of the while loop
$alldates[$blogcount++] = $date;
$alldata[$blogcount++] = array('bname'=>$bname, 'blogid'=>$blogid, 'burl'=>$burl, 'bdesc'=>$bdesc, 'ids'=>$ids, 'title'=> $title, 'excerpt'=>$excerpt, 'text'=>$text, 'textmore'=>$textmore, 'tburl'=>$tburl);
}
$count++;
}
}
}
array_multisort($alldates, SORT_DESC, $alldata);
for ($i=0;$i<=5; $i++) {
//separate date created on up between year, month, and date
$year[$i] = substr($alldates[$i], 0, 4);
$month[$i] = substr($alldates[$i], 5, 2);
$day[$i] = substr($alldates[$i], 8, 2);
if ( $alldata[$i]['text']>""):
echo '<div class="update">', date( " F j, Y", strtotime($alldates[$i])), ' : ', 'In ';
echo '<a href="', $alldata[$i]['burl'], '" target=" _blank" title="', $alldata[$i]['bdesc'], '">', $alldata[$i]['bname'], '</a></div>';
echo '<div class="title">', '<a href="', $alldata[$i]['tburl'], '" target="_blank" title="', $alldata[$i]['title'], '">',$alldata[$i]['title'], '</a></div>';
echo '<div class="excerptsyn">', $alldata[$i] ['excerpt'], '</div>';
if ( $alldata[$i]['textmore']>""):
echo '<div class="blogbodysyn">', $alldata[$i]['text'], '<a href="',$alldata[$i]['tburl'], '"target="_blank" title="', $alldata[$i]['bdesc'], '">', ' [ More ] ', '</a>', '< /div>';
else:
echo '<div class="blogbodysyn">', $alldata[$i]['text'], '</div>';
endif;
echo '<div class="dividerline">',' ', '</div>';
echo '<div class="divider">',' ', '</div> ';
else:
break;
endif;
}
?>
Basically, this does several nifty things.
I added a little refinement in the printing section: if there is an extended body, it insets [more] with a permalink http reference tag; and if there isn’t a an extended body, it just prints the main text entry.
I’m sure it can be improved and made more efficient by someone who knows PHP well (I’m really a newbie at this, just got into it a few weeks ago and I’m not even a computer jock, just an ornery lawyer) but it works well for me. If you’re using it, remember to remove all the class="whatever" tags and add your own — these only reference my CSS file entries. Incidentally, you can embed MT tags into the print section, too, but what that does is yet another saga.
THE SIDEBAR REARS ITS HEAD
So far so good. But there endeth the saga not. I also want a method of pulling the blog names, with their URLs, and the top five entries in each blog and sticking these into a little side-bar for navigation. I wanted this to serve the purpose of a navigation bar or menu (you add a blog, it must show up) and must, again, refresh itself.
MTOther blog failed totally because of the demand for a rebuilt. I tried other solutions and got some really bizarre results. Then, on the footing that the simplest solution is often the best, I just used a PHP list command coupled with a while command:
<?
//connection info
include ("/users/mcavity.com/httpdocs/connect.php");
$result = mysql_query("SELECT blog_id, blog_site_url, blog_name, blog_description FROM mt_blog WHERE (blog_id > 1) ORDER BY blog_name ASC");
while (list($blog_id, $blog_site_url, $blog_name, $blog_description) = mysql_fetch_row($result)) {
echo '<div class="oblog">+ ', '<a href="', $blog_site_url, '" target="_blank" title="', $blog_description, '">', $blog_name, '</a></div>';
$entryresult=mysql_query("SELECT entry_title, entry_blog_id, entry_id, entry_excerpt, trackback_entry_id, trackback_url FROM mt_entry, mt_trackback WHERE ((entry_blog_id = $blog_id) AND (entry_id = trackback_entry_id)) ORDER BY entry_title ASC");
while (list($entry_title, $entry_blog_id, $entry_id, $entry_excerpt, $trackback_entry_id, $trackback_url) = mysql_fetch_row($entryresult)) {
if (mysql_num_rows($entryresult) < 6):
echo '<div class="oblog2">? ', '<a href="', $trackback_url, '" target="_blank" title="', $entry_excerpt, '">', $entry_title, '</a></div>';
else:
break;
endif;
}
}
?>
What this does is that it first gets all the blog names and lists them alphabetically. So, you add a new blog, it gets added at once. Next, immediately after listing the blog (the WHILE statement) it gets a list of entries where the entry blog id matches the blog id (which it just printed) and where the entry id has a matching trackback id (to get the permalink). Then it prints the sequence of those entries subject to a cap of 5 (the ending if statement where the row count of the entryresult is < 6): your last 5 entries.
THE REAL TRICK
And here’s the trick. Don’t use the MTInclude tag for these php chunks — again that forces rebuilds. Instead use the simple php include statement <? include("full/path/to/file") ?> so that it automatically builds these list with every page load.
Happy, happy day! Perfect. Time to go grab that big bowl of cappucino. Yes! Where am I using this? On this site, of course, but also, with a variant, on the Bombay Bar Association website. Future plans include websites for the Mohile Parikh Center and the Bombay Environmental Action Group.
Postscript: Having done all that, I knocked it off. Frankly, I went back to a single blog system — I like the bookmarklet feature and, for a personal blog, it just wasn’t worth the effort struggling with multiple blogs.