Category Archives: wordpress

Monitoring multiple WordPress sites for comments using Yahoo Pipes

As the de facto blogging geek in the family, I’m keeping an eye on my blog and three other (mostly inactive) blogs:

I need to monitor comments that slipped through spam filtering, WordPress version updates, and so on. Fortunately, I don’t have to regularly come up with content for all four!

I wanted to make it easier to check comments on multiple sites. Instead of checking each site regularly or configuring them to send me e-mail (too much e-mail!), I used Yahoo Pipes to combine the blog comment feeds from each site into one main feed. Then I added that feed to iGoogle, along with gadgets for weather, calendar, and mail. Tada! Dashboard.

Do you manage multiple WordPress blogs? How do you stay on top of them?

Working with the Editorial Calendar plugin for WordPress; on scheduling posts

In preparation for our trip to the Philippines, I’ve been spreading posts out over several days instead of posting multiple entries a day. The Editorial Calendar WordPress plugin makes it easy to move posts around by dragging and dropping. Here’s what it looks like in the administration screen:


When I installed it, I found out that I needed to reinstall my JQuery library (must’ve been out of date?). After that, it worked fine.

On one hand, I feel a little odd scheduling posts so far out. Do these posts lose something of their ability to help me find my way back to moments? I write less during the weeks when I’ve queued many posts; less urgency, so I capture less of the day-to-day moments.

On the other hand, if posting in advance helps me write and lets me capture and share thoughts that might’ve languished in my private notes file, I guess that’s okay. At least this tool makes it easy to reschedule posts when something more interesting catches my eye.

The next step for blogging awesomeness would be to choose topics that I want to learn more about – a proper editorial calendar of concepts! – and use that to direct my learning. Some of our upcoming projects lend themselves very well to this, so it will come in due course.

Anyway, this Editorial Calendar plugin is handy. If you post regularly, you might want to check it out:

Getting the WordPress Lifestream plugin to work on my blog

I’ve been thinking about including a digest of Twitter, Delicious bookmarks, Google Reader shared items, and other social activity in my weekly review. This lets me include the information in my archive, and it gives people more opportunities to bump into things I found interesting.

It took a bit of hacking, but I eventually got the Lifestream plugin for WordPress to work, with the help of another webpage and some source code diving. Here’s the code that powers this lifestream page:

<?php $options = array('limit' => 50); $events = $lifestream->get_events($options); foreach ($events as $event) { echo '<li>'; $label_inst = $event->get_label_instance($options); if ($event->feed->options['icon_url']) { echo '<img src="' . $event->feed->options['icon_url'] . '" alt="(' . $event->feed->options['feed_label'] . ') \ "> '; } echo '<a href="' . $event->data[0]['link'] . '">' . $event->data[0]['title'] . '</a> (' . date('D, M j, Y', $event->data[0]['date']) . ')'; echo '</li>'; } ?>

$event->render had been giving me problems, so I specified my own output format. It didn’t automatically pick up icon URLs, so I specified the URLs myself. (Bug: the settings get lost if you re-configure the feed.) The plugin seems to be broken out of the box, but there are enough pieces in there for a geek to make things work.

Because I don’t want to use up two of my one-post-a-day slots on weekly reviews, I’m leaving it as a web page that I can review and manually copy into my weekly review post instead of automatically publishing something.

You can see it in action in last week’s review.

Work in progress. Hope this helps!

Holy cow, that was a lot of mail. So sorry!

I was checking out a few things on my blog today, and I came across my WordPress Post Notification administration page. “Hmm,” I said. “I seem to have misconfigured this.” No e-mail had been sent out since August 2009. I figured out that the configuration directory didn’t have write permissions, enabled it, and went on with the rest of my day.

In the evening, I checked my personal mail on my iPod Touch. Inbox…

323 unread messages. That wasn’t right. I read the e-mail subjects. Holy cow, my blog had sent out every single one of my posts in the past half-year.

Granted, the only people on the list had double-opted-in, but still. I’d be annoyed if that many messages showed up in my inbox too, instead of one at a time.


First step: Control the damage. I moved post-notification out of the way, automatically disabling the plugin.

Second: Figure out the impact. 50 e-mail addresses left. Two nasty-notes.

Third: Gingerly re-enable the plugin after removing the locking directory.

Fourth: E-mail everyone an apology.

Fifth: Write about what happened. Tradeoff: Personal embarrassment versus possibility of saving other people from doing this kind of stuff. Worth it.

Looking at the bright side (because there always is a bright side)… At least I’m learning this now instead of later. And with my blog instead of a customer site. And with a smaller list instead of a megafan community. And… umm… it’s e-mail instead of text messages. Which has happened before. I was writing a Perl script that sent messages, and I had a bug, and there was an infinite loop, and poof! there went the balance on my prepaid card.


I’m sorry.

WordPress admin screen tweaks

A few months ago, I decided to experiment with publishing (mostly) one post a day, scheduling posts to go out at 8 AM. That’s been working well for me, although I now have a backlog of 22 scheduled posts (as of March 11), and I keep reshuffling my queue because I want to post some things sooner.

I started using the Manage Posts page a lot. I checked the dates in the queue and used quick-edit to move posts around. I double-checked missed posts (grr). I looked up posts that got scheduled at 8 PM instead of 8 AM.

And then I decided to code in a whole bunch of things that would make life a little bit easier for me. =) I got rid of columns I didn’t use, increased the number of posts per page, added a few custom columns, and styled things differently. Kaizen: relentless improvement!

Just in case I find this useful in the future, or someone else wants to do something similar:

 * @package Sacha_Chua
 * @author Sacha Chua
 * @version 0.1
 * Feel free to use this under the GNU General Public License v3 
 * or the Creative Commons Attribution License
 * This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  GNU General Public License for more details.
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <>.
Plugin Name: Sacha Chua's fixes
Plugin URI:
Description: Tweaks to make my life easier
Author: Sacha Chua
Version: 0.1
Author URI:

add_filter('manage_posts_columns', 'sacha_manage_posts_columns');
add_action('manage_posts_custom_column', 'sacha_manage_posts_custom_column');
add_action('admin_head', 'sacha_admin_head');
add_filter('edit_posts_per_page', 'sacha_edit_posts_per_page');
define('POSTS_PER_PAGE', 50);

 * Increase posts per page to at least POSTS_PER_PAGE
function sacha_edit_posts_per_page($page) {
  return ($page < POSTS_PER_PAGE) ? POSTS_PER_PAGE : $page;
 * Resize the columns
function sacha_admin_head() { ?>
  <style type="text/css">
  .column-time { width: 150px; }
  .column-categories { width: 300px }
  .column-status { width: 100px }
  .scheduled { color: green } 
<?php }
 * Remove the tags column
function sacha_manage_posts_columns($defaults) {
  $defaults['status'] = __('Status');
  $defaults['time'] = __('Date');
  return $defaults;

 * Show the time if it's not 8 AM, and show the status and date
function sacha_manage_posts_custom_column($column_name) {
  global $post;
  switch ($column_name) {
    case 'status':
      if ( '0000-00-00 00:00:00' == $post->post_date) {
      } elseif ('publish' == $post->post_status) {
        echo '<div class="published">' . __('Published') . '</div>';
      } elseif ('future' == $post->post_status) {
        $time_diff = time() - get_post_time('G', true, $post);
        if ( $time_diff > 0 ) {
          echo '<strong class="attention">' . __('Missed schedule') . '</strong>';
        else {
          echo '<div class="scheduled">' . __('Scheduled') . '</div>';
      } else {
        _e('Last Modified');
    case 'time':
      if ( '0000-00-00 00:00:00' != $post->post_date) {
        $t_time = get_the_time(__('g:i A'));
        if ($t_time == '8:00 AM') {
          $t_time = '';
        $t_date = get_the_time(__('Y/m/d'));
        print $t_date . ' ' . $t_time;

Next step might be to make a plugin that automatically handles scheduling for me. Or even rearranging my queue… Hmm… =)

WordPress tweak: Proper navigation for date.php

I can’t be the only person who’s ever wanted proper navigation on WordPress date.php archive pages. By this, I mean that if you’re browsing, say, and you’re on the first page, there should be a way for you to get to 2008.

So I spent a couple of hours hacking that in. This even skips non-existent years/months/days. Tweak and enjoy.

Minor notes: It jumps to the first page of the other year/month/day, so the results aren’t strictly chronological. Going to 2008 from 2009 will show you the blog posts from January 1 instead of the last posts of 2008. Since I display a huge list of posts and I only use one page, that’s fine with me.

  $y = mysql2date('Y', $wp_query->posts[0]->post_date);
  $m = mysql2date('m', $wp_query->posts[0]->post_date);
  $d = mysql2date('d', $wp_query->posts[0]->post_date);
  $display = mktime(0, 0, 0, $m, $d, $y);
  if (is_year()) {
    $format = 'Y';
    $prev_display = mktime(23, 59, 59, 12, 31, $y - 1);
    $next_display = mktime(0, 0, 0, 1, 1, $y + 1);
    $url_format = 'Y';
  } elseif (is_month()) {
    $prev_display = mktime(23, 59, 59, $m, 0, $y);
    $next_display = mktime(0, 0, 0, $m + 1, 1, $y);
    $format = 'F Y';
    $url_format = 'Y/n';
  } elseif (is_day()) {
    $prev_display = mktime(23, 59, 59, $m, $d - 1, $y);
    $next_display = mktime(0, 0, 0, $m, $d + 1, $y);
    $format = 'F j, Y';
    $url_format = 'Y/n/j';
  $paged = get_query_var('paged');
  if ($paged < 2) { // No previous pages; navigate by date instead
    $past = $wpdb->get_row("SELECT UNIX_TIMESTAMP(MAX(post_date)) AS post_date
FROM $tableposts WHERE post_date <= FROM_UNIXTIME($prev_display) AND post_status='publish'");
    if ($past->post_date) {
      $prev_text = '&laquo; ' . date($format, $past->post_date);
      $prev_link = get_bloginfo('url') . '/'
        . date($url_format, $past->post_date);
  if ($paged >= $wp_query->max_num_pages) { // No next pages
    $future = $wpdb->get_row("SELECT UNIX_TIMESTAMP(MIN(post_date)) AS post_date
FROM $tableposts WHERE post_date >= FROM_UNIXTIME($next_display) AND post_status='publish'");
    if ($future->post_date) {
      $next_text = date($format, $future->post_date) . ' &raquo;';
      $next_link = get_bloginfo('url') . '/'
        . date($url_format, $future->post_date);
  $title = date($format, $display);
  <div class="navigation">
    <div class="left">
      <?php if ($prev_text) { ?>
        <a href="<?php print $prev_link ?>"><?php print $prev_text ?></a>
      <?php } else { ?>
        <?php previous_posts_link('&laquo; Older posts'); ?>
      <?php } ?>
    <div class="right">
      <?php if ($next_text) { ?>
        <a href="<?php print $next_link ?>"><?php print $next_text ?></a>
      <?php } else { ?>
        <?php next_posts_link('Newer posts &raquo;'); ?>
      <?php } ?>
    <div style="clear: both"></div>
  <h1><?php print $title ?></h1>