Monthly Archives: October 2009

A List of Awesome WordPress Blogs to Follow

Whether you’re a WordPress expert, beginner or simply a blogger running WordPress, WordPress MU, BuddyPress or any others, here’s a little list of WordPress blogs that you should definitely follow (not mentioning the WordPress Development Blog and Matt Mullenweg’s Blog, and maybe #wordpress on Twitter, I assume you’re following them since your first ever WordPress installation ;). These include themes, development tutorials, plugins, SEO and publishing tips, customization techniques and much more. Ordered by my preference.

Weblog Tools Collection

Over 15,000 subscribers, plugin and theme releases lists and news, WordPress video tutorials, code snippets and much more. Running around by the name of @weblogtooltips on Twitter. Here’s a quick list of some of their posts:

WP Recipes

With over 6,000 readers WpRecipes.com is one of my favourite blogs for “Daily recipes to cook with WordPress”, known as @catswhocode on Twitter. Here are some posts from WP Recipes:

WordPress Tavern

Sweet blog with tonnes of tips and tricks, WordPress events, also covering WordPress MU, BuddyPress and bbPress. @wptavern on Twitter.

WordPress for Beginners

If you’re a beginner in WordPress then you should definitely follow this blog. Very nice tutorials about customizing WordPress.

Lorelle on WordPress

For WordPress news, events. Not much tutorials here, but being up to date with what’s happening around WordPress is always a great idea. On Twitter: @lorelleonwp.

Theme Playground

Hosted by Ryan Imel Theme Playground is definitely a must-follow blog for WordPress themes & plugins, reviews, code snippets and giveaways.

WordPress Hacks

5000 readers of WordPress hacks enjoy blogging tips and tricks, wordpress guides, themes, plugins, frameworks and more! Known as @hackwordpress on Twitter.

Theme Lab

These guys haven’t got much readers – a few over a thousand, but the theme reviews they publish are so cool! Their latest “Theme Battle” series is awsome, plus they’ve got a list of nice WordPress resources every week. This is a must-subscribe, @themelab on Twitter.

WPMU Tutorials

Everything you need to know about WordPress MU and BuddyPress. Installation tips, modifications, hacks, tricks and explenations. Here’s the latest:

That’s about it, some other less popular (or less fortunate ;) blogs you may find interesting are:

And of course if you’ve anything to add to this list, please share via comments.



WordPress: Customizing WP-Syntax

I noticed a little bug in the WP-Syntax plugin for WordPress – the line numbers don’t match when using code with comments, well at least in Firefox 3.5. I realized it was caused by the italics where the line-height increased by approximately 1 pixel. It’s not that bad when you have a couple of comments in the code, but 60 lines of code with around 10 lines of comments completely broke my line numbers. I figured out WP-Syntax is configurable and here’s how I removed the italics from code comments:

add_action('wp_syntax_init_geshi', 'my_custom_geshi_styles');
function my_custom_geshi_styles(&$geshi) {
    $geshi->set_comments_style(1, 'font-style:normal;', true);
}
// Note that comments are okay now ;)

Place this in your functions.php file and refresh your page. More info about the other $genshi methods could be found in the Genshi Documentation.



Google Docs API: Client Login with PHP and Curl

A few days ago I started looking deeper into the Google Code APIs and threw a few experiments using the Google Documents List Data API. Unfortunately, the only library they have for the third version of their protocol is written in Java. There is a PHP wrapper for the first version of the protocol, but it totally depends on the Zend Framework. Here’s a little code snippet for logging into a Google Docs account (writely) using ClientLogin with Curl and PHP. The Auth string is stored into the $auth variable for later use.

// Construct an HTTP POST request
$clientlogin_url = "https://www.google.com/accounts/ClientLogin";
$clientlogin_post = array(
    "accountType" => "HOSTED_OR_GOOGLE",
    "Email" => "yourgoogle@email.com",
    "Passwd" => "yourgooglepassword",
    "service" => "writely",
    "source" => "your application name"
);

// Initialize the curl object
$curl = curl_init($clientlogin_url);

// Set some options (some for SHTTP)
curl_setopt($curl, CURLOPT_POST, true);
curl_setopt($curl, CURLOPT_POSTFIELDS, $clientlogin_post);
curl_setopt($curl, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);

// Execute
$response = curl_exec($curl);

// Get the Auth string and save it
preg_match("/Auth=([a-z0-9_\-]+)/i", $response, $matches);
$auth = $matches[1];

echo "The auth string is: " . $auth;

ClientLogin assumes you login once and use the auth string for all on-going requests (more info: ClientLogin – Google Code). Here’s a simple example of how to retrieve some data from a Google Docs account, show filename, author and file type. Make sure the simplexml php extension is installed and activated.

// Include the Auth string in the headers
// Together with the API version being used
$headers = array(
    "Authorization: GoogleLogin auth=" . $auth,
    "GData-Version: 3.0",
);

// Make the request
curl_setopt($curl, CURLOPT_URL, "http://docs.google.com/feeds/default/private/full");
curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
curl_setopt($curl, CURLOPT_POST, false);

$response = curl_exec($curl);
curl_close($curl);

// Parse the response
$response = simplexml_load_string($response);

// Output data
foreach($response->entry as $file) {
	echo "File: " . $file->title . "<br />";
	echo "Type: " . $file->content["type"] . "<br />";
	echo "Author: " . $file->author->name . "<br /><br />";
}

It seems though that Google Docs is purely for documents (spreadsheets and presentations) but not for actual files, as a JPEG I uploaded turned into a text/html type. It opens up in the text editor when viewing in Google Docs, and the nearest-to JPEG export format is PDF (just like all the other documents). So I guess there’s no way of reading and manipulating the raw image as if I would read and manipulate a file.

I came across a cool website which I believe the Googlers have made – Data Liberation:

Users should be able to control the data they store in any of Google’s products. Our team’s goal is to make it easier for them to move data in and out.

I’m working on a little project that involves image (and file) hosting, so the products I’m interested in are Google Docs and Picasa Web Albums. It seems that none of the two make it possible to store and work with files as if it was a flash disk or an FTP server. Google Docs is the closest one but there’s a huge limit on what kind of files you can upload and store. Picasa on the other hand is good for image storing, but the only way to export a set of images is to use their desktop software and Picasa Web, and of course no actual control over the files (edit, delete) via their Picasa Web API. If only it were a little bit closer to Amazon S3 …

Oh and you should probably use OAuth or AuthSub when working with Web Applications and Google APIs but anyways, this was just a quick example.



Inspired: Web Design Showcase October 2009

Browsing the Internet, reading Twitter streams, RSS feeds… I see billions of websites everyday (kidding) and there’s lots of stuff out there that inspires me everyday, so I’ve decided to run a new series called “Inspired” where I’ll post the most interesting stuff I come across (monthly, weekly, yearly, I don’t know yet, maybe I’ll close this down the very next day ;)

This is my first post in this series and I called it Web Design Showcase for October 2009. Since we’re talking about web design and design in general, I’ll keep this running in a gallery format, perhaps with a few comments for each entry (but not necessarily). I would also appreciate if you (the readers) would post a few links of something nice that you came across during the last few weeks, months, and perhaps you’ll make an entry for my next episode. But please, no offence, this is not a CSS gallery or anything, it’s stuff that I pick depending on personal tastes.

If you would like to visit any of the above websites just Google their names – they should come up eventually. I wouldn’t like to stuff the post with useless links and adverts ;) And yeah, the gallery looks terrific on Lightbox! Poor people that go blind searching for the “next” and “previous” buttons on Thickbox ;)



Cloud Tips: Rediscovering Amazon CloudFront

So, three months later I realized I wasn’t using CloudFront at all! Huh? I took a deeper look at my Amazon Web Services bill last month and found out that I wasn’t even charged for CloudFront! But hey, I delivered all my static content through CloudFront distributions from S3 and I had a subdomain mapped to those distributions and everything was working fine (thought I).. Let’s see:

Amazon CloudFront delivers your content using a global network of edge locations. Requests for your objects are automatically routed to the nearest edge location, so content is delivered with the best possible performance.

Right, and that’s probably what they charge for in the CloudFront section, so the fact is that I haven’t been using it at all. Gathering all the static content from the so-called “origin server” is far from what CloudFront can do. What I’ve been using for the past few months is simply delivering content from my S3 server, which is also good, but “good” is not enough. I browsed throughout the AWS Management Console for hours and couldn’t find out what I was doing wrong, the server kept pulling the content from the origin. Then, finally I realized that after I’ve created a distribution I was given two addresses and as they said, one was the origin server, the second one was the CloudFront server (it’s a .cloudfront.net subdomain underlined red), thus the settings I got all wrong were at the DNS level, not the Management Console.

Cloud Tips: Rediscovering Amazon CloudFront

So I logged back to my registrar, found the DNS management options and switched my CNAMEs to the CloudFront domain instead of the origin bucket and hoped that everything works well. The very next day I got my very first bill for Amazon CloudFront – three cents! Hurray! I’m not sure if this is well written in the documentation for CloudFront and S3 (I doubt that people read them) but I have a few friends who have experienced the same problem and why the address of the origin bucket in the first place? Weird. The S3 Firefox Organizer groups both fields into one and that’s even more weird. Oh well, glad I sorted it out.



While Everyone’s Been Waiting for WordPress 2.9

I’ve been using it! Okay, so I’m not going to talk about all the great stuff coming up in 2.9, all the bugs they’ve fixed, all the features they’ve added, no. I’d just like to tell you about my experience running a step ahead of everybody else. When WordPress has made the switch from 2.7 to 2.8 I’ve decided to risk it and take the 2.9 path. I’m not sure why everybody’s talking about that new beta testers plugin being released, but I bet that a “beta tester” or at least somebody who wants a ride at the 2.9 branch do know how to use their FTP client. More advanced “testers” do this via shell. Oh come on, I mean how difficult could it be to locate one single file, download it, edit and upload back to your server? I could bet $20 that it’s way faster than installing that plugin.

Anyways, back to my WordPress 2.9. Nightly updates are being released every day, I make sure to update at least once every two weeks. And everytime I felt the blog apocalypse coming, although I do have daily server backups, but downtime to me is so crucial. The best part of it is that I’ve never seen anything crash, really, all the plugins are working like a charm, my theme has (almost) never been broken, so I hope it stays that way. In case you’re experiencing any problems, make sure you report to the plugins and themes authors, and do state you’re running a development version, I’m sure they’ll note it down and get back at you a few weeks before the release ;)

So what’s the big deal about running ahead? Well, if you’re a WordPress plugin developer then you know what the big deal is. Whenever an update comes out you see your plugins crashing and malfunctioning and “a few weeks” may not be enough sometimes, though WordPress warns about checking all the plugins compatibility before upgrading, theme compatibility, blah blah blah. Users don’t do that. They upgrade and that’s it. If your plugin stopped working, they go find themselves one that’s okay. There, you’ve just lost a client.

When running a step ahead you’ve got all the time to test and debug your work and get it ready for the upgrade. But why not locally? Motivation, motivation, motivation. Whenever something doesn’t work locally, you go have a snack, lie on the couch, watch some tv, play some video games.. I could go on. When your online blog stops working, you sit all night and fix it. Well at least that’s what I do ;) but be careful not to forget about back compatibility, as you don’t want to be stuck at 2.9 while it hasn’t yet been released, and everybody running 2.8 get those nasty error messages! Also be careful playing with the new features and try to stick to the current stable release as much as possible.

One more interesting thing about using a higher branch than the stable, is that when the WordPress guys find out a critical bug in the current stable (just like in 2.8.3 for instance) there’ll be loads of people searching for 2.8.3 blogs and trying to hack them of whatever, but yours wouldn’t count ;) perhaps breaking a development version would be too easy for them “hackers” ;)

Anyways, I hope the testing goes well, 2.9 is released and I’ll finally be able to make my switch to 3.0, which is already marked in the WordPress Core Trac Roadmap. I’ve tried switching the branch to 3.0 today but with no luck, back to 2.9-rare after the nightly upgrade.

So, good luck may the power of WordPress be with you! ;)



WordPress: The template_redirect Hook Returns 404

This is a real quick one. I’ve started using the W3 Total Cache plugin a few days ago which I’m totally satisfied with. Unlike the WP Super Cache plugin, W3TC can keep the caches in memory via memcached, serve the static content through CDNs. The guys at W3 Edge promised to add Amazon CloudFront compatibility which I’m very excited about. As we all know (I guess) Mashable is running WordPress, and guess what! They’re using W3 Total Cache too, so if they could trust those guys, then I’m totally in. Their support over Twitter is awesome, you don’t even have to look for them! Just tweet your problem mentioning “W3 Total Cache” or “W3TC” – they’ll find you via search and help you solve whatever your issue is.

Anyways, that being said, after writing my post announcements to Twitter via Twitter Friendly Links some peeps shouted out that I was returning 404 errors on all of my short links. Strange, thought I, as I was able to see everything fine. Looking at the settings of the plugin I realized that I, as a logged in user, weren’t looking at cached pages, so I turned that off and guess what! I got those 404s. Creepy! After a little talk over Twitter and IM with the guys at W3 Edge, I started to look through the caching plugin code. It’s so well-written and I’ve actually learned a couple of techniques out there! Anyways, the reason I was getting 404s was because W3 TC looked at the $wp_query object and it’s $is_404 variable, which I don’t know why (Frederick from W3 Edge mentioned a redirection issue with WordPress) was returning true on all of my Twitter friendly links!

I figured out that the template_redirect hook (which is not documented in the WordPress Codex at all) didn’t quite do what I wanted it to. The easiest way out was adding a couple of lines before the redirect actually happened:

global $wp_query;
$wp_query->is_404 = false;

And guess what, it worked! This may be not the smartest decission but hey, it’s working! One more workaround would be adding a regular expression to the W3 Total Cache page settings, exclude “[0-9]+/?$” which would not cache any .com/1234 queries, but that’s not so reliable for a couple of reasons. First, why not cache if we can cache? And second, what if we’re using Twitter Friendly Links in alphanumeric mode? That would mean “[0-9a-zA-Z]+/?$” which would probably match for all the other top-level pages, thus we’re losing all the benefits from caching. Meh!

I guess this is not the only place where the template_redirect action would return a 404. Some plugins that define their own permalinks through the template_redirect hook (WP Polls for poll results for instance, not sure though) will also get 404s if they don’t set it to false in $wp_query. Many wordpress websites have profile pages which are not actual pages in the database, but are handled through the template_redirect action for .com/profile_name sort of permalinks which is indeed cool. I’m actually planning on using it with one of my upcoming projects and I’m really glad I sorted it out.

So the big shoutout goes to W3 Total Cache and the W3 Edge team!



Automated Twitter Bot in PHP: Remote Control

Hope you’ve all read the first part of this series – Create Your Own Automated Twitter Robot in PHP and got your own prototype up and running. Today we’ll be adding a remote control feature to our robot. It’ll be working through direct messages and running in crontab every 5 minutes or so. You can extend this as far as you want (adding retweet capabilities, follow/unfollow, direct messaging other people, etc) but we’ll stick to simple status updating in this post, might cover the others later on.

So, direct messaging the robot’s twitter account with the text “update status text” would make him tweet “status text” to the public timeline. Remember we had three branches of actions – feed, reply and rthx? Let’s add a fourth one and call it dm. This branch will simply scan through the account’s latest direct messages, find those sent by you and tweet them out loud. Again, as I said in the first tutorial, this is simply a prototype, just to get things up and running. You’ll have to polish this off for actual use and yeah, storing the access keys, dm_since_id, etc on disk is not such a good idea, you should probably use the database. Here’s the code:

// The id of the latest read direct message will be stored in
// a file called dm_since_id, just like mentions_since_id
// in the previous examples
$since_id = @file_get_contents("dm_since_id", true);
if ($since_id > 0) { }
else { $since_id = 1; }

// Retrieve the direct messages into $dms and parse the xml string
$dms = $oauth->OAuthRequest("http://twitter.com/direct_messages.xml" ,
	array("count" => 10, "since_id" =>  $since_id), "GET");
$dms = simplexml_load_string($dms);

// If it's valid read the latest id and store into dm_since_id
if (count($dms))
{
	$last_id = ($dms->direct_message[0]->id > $since_id) ?
		$dms->direct_message[0]->id : $since_id;
	file_put_contents("dm_since_id", (string)$last_id, FILE_USE_INCLUDE_PATH);
}

// Loop through the messages
foreach ($dms->direct_message as $dm)
{
	// Make sure you're the sender
	$sender = $dm->sender->screen_name;
	if ($sender == "kovshenin")
	{
		// What should we do
		if (strtolower(substr($dm->text, 0, 7)) == "update ")
		{
			// Construct the message, tweet and wait a few seconds
			$message = substr($dm->text, 7);
			$oauth->OAuthRequest('https://twitter.com/statuses/update.xml',
				array('status' => $message), 'POST');
			echo "Tweeting: " . $message;
			sleep(rand(5,30));
		}

		// Add more actions here
	}
}

Read through the comments in the code and you should be able to get the idea. The direct messages Twitter API method is documented here. Test it out a few times through your SSH client by sending a direct message to your robot with the text “update Updating my status” or whatever, then run:

# php robot.php dm
Tweeting: Updating my status

If everything works fine you might as well add the action to your cron, say 5 minutes:

*/5 * * * * php /home/youruser/twibots/robot.php dm

And done! Your robot is now remote controlled. A few suggestions to more advanced remote controlled operations would be:

  • Retweet capabilities by regular expression
  • Adding and removing feed sources, prefixes and postfixes
  • Turning on and off other operations (feeding, replying, rthxing)
  • Adding people to “reply ignore lists” (ones that talk to your robot too much)
  • Adding people to “rthx ignore lists” (ones that retweet too much, twitterfeed for instance)

I think that’s enough for a start, oh and please don’t build dumb and annoying spammish robots. Stick to intelligent, smart twibots! ;)

Upd. Continued: Twitter Robot in PHP: Twibots Draft



Cloud Tips: Automatic Backups to S3

In a previous post about backing up EC2 MySQL to an Amazon S3 bucket we covered dumping MySQL datasets, compressing them and uploading to S3. After a few weeks test-driving the shell script, I came up with a new version that checks, fixes and optimizes all tables before generating the dump. This is pretty important as mysqldump will fail on whatever step would cause an error (data corruption, crashed tables, etc), thus your uploaded to S3 archive would be kind of corrupt. Here’s the script:

filename=mysql.`date +%Y-%m-%d`.sql.gz
echo Checking, Fixing and Optimizing all tables
mysqlcheck -u username -p password --auto-repair --check --optimize --all-databases
echo Generating MySQL Dump: ${filename}
mysqldump -u username -p password --all-databases | gzip -c9 > /tmp/${filename}
echo Uploading ${filename} to S3 bucket
php /ebs/data/s3-php/upload.php ${filename}
echo Removing local ${filename}
rm -f /tmp/${filename}
echo Complete
<pre>

There you go. If you remember my previous example I stored the temporary backup file on Amazon EBS (Elastic Block Storage) which is quite not appropriate. Amazon charges for EBS storage, reads and writes, so why the extra cost? Dump everything into your temp folder on EC2 and remove afterwards. Don't forget to make changes in your upload.php script ($local_dir settings). Also, just as a personal not and to people who didn't figure out how to upload archives with data to S3, here's another version of the script which takes your public_html (www, htdocs, etc) directory, archives it, compresses and uploads to an Amazon S3 bucket:

<pre>filename=data.`date +%Y-%m-%d`.sql.gz
echo Collecting data
tar -czf /tmp/${filename} /ebs/home/yourusername/www
echo Uploading ${filename} to S3 bucket
php /ebs/data/s3-php/upload.php ${filename}
echo Removing local ${filename}
rm -f /tmp/${filename}
echo Complete

Oh and have you noticed? Amazon has changed the design a little bit, and woah! They’ve finally changed the way they show the Access Secret without a trailing space character! Congrats Amazon, it took you only a few months.



Create Your Own Automated Twitter Robot in PHP

The ultimate guide to creating your own personalized twitterfeed clone! Kidding… Actualy this is just a mockup, a simple prototype, which is way too fresh for any actual use. We’ll take this forward step by step. I’m not going to give out all my sources but I’ll guide you through authentication, rss lookup, parsing, thanking for retweets, and shooting random stuff at people that mention your robot.

Here’s a brief list of features we will implement:

  • Runs in console, no HTTP access
  • Authentication via OAuth, tweeting via OAuth
  • RSS lookup, parsing, forming tweets in bound of 140 characters including a postfix (hashtag or RT)
  • Tweeting ‘thank you for retweeting’ to users that retweet the robot
  • Following people that retweet the robot
  • Acting strange on users that mention the robot

All this is going to be setup on a linux box running crond and acting every 15 minutes or so. Are you ready? Let’s do it!

Continue reading