I'll be at Google Developer Day 2011

Google Developer Day 2011I can’t believe this is the first post I’m writing here in September. I really have to do something with myself and my time management and in my defense I can only say Theme.fm is doing pretty good, but okay, this post is not about WordPress.

This post is about my favorite tech conference — Google Developer Day and this year will be my third year in a row in Moscow. I’m not expecting much this year since from last year I’ve stepped a little bit away from Google App Engine, although I’m still using it from time to time. What’s interesting this year is the “Social” track and of course Google+. I bet the room will be packed, just like Wave during it’s days ;)

Also interesting: VC Panel, Google+ Hangout Apps, Google+ APIs and of course the good time we’ll have with my friends, the food and drinks, amazing as usual. And let’s hope I get to see some of my “old friends” from Google ;) Make sure you poke me if you’re coming so we can chat and play video games during the breaks.

Meet Chromebook: Not Even a Desktop Background

You all know I’m a big fan of Google’s promotional videos, and here’s a really really nice one about their new Google Chromebook. Definitely one of the best promo video’s I’ve seen so far, and even better then Nexus One ;)

I’m not a big fan of Chrome OS but I do use Chromium for work and play, and I really love the idea of having no software. Salesforce, remember? And Larry Ellison on cloud computing: “If there’s no hardware or software in the cloud, we’re so screwed!” ;)

Learn more about Chromebook

Snippet: Nofollow for Tag Cloud in WordPress

Tag clouds are good, but in a previous post called WordPress & Google Analytics: Tracking Your Tag Cloud I admitted that they’re not very useful, and especially for search engines — which is the topic I’ll discuss today.

I’m not an SEO junkie or anything but I do have some knowledge of the basic rules, one of which is avoid duplicate content. Now fire up your blog homepage — you’ve a list of your latest posts. Open the tag archive of some popular tag — you’ve got that very same list there. So for sure we have to ask Google not to index the tag archives, but we also have to ask Google not to follow links to such archives on every page.

The first step is done using robots.txt and according to your permalink structure. Mine for instance is /tag/tag-name so in order to disallow Google and other search engines to index that, I add the following to my robots.txt file:

User-agent: *
Disallow: /tag/

Please note that this is not a guide to the best robots.txt for your WordPress blog, and in reality you have to disallow more than just the tag directory (archives, search results, etc).

The second step, which is mainly why I wrote this post, is a short snippet for your functions.php file, that attaches a rel attribute with a nofollow value to every link produced by the wp_tag_cloud built-in function. This looks very much like the code snippet I shared in my last post only with a different regular expression. The two can be combined. Here’s the snippet:

function my_wp_tag_cloud($return) {
	$return = preg_replace('/(<a )/', '1rel="nofollow" ', $return);
	return $return;
}
add_filter('wp_tag_cloud', 'my_wp_tag_cloud');

Not the best regular expression ever, but that should work on the major themes out there. It looks for the opening tag of the anchor and simply attaches rel=nofollow, as easy as that ;)

Now save that and go back to your blog, view the source (Ctrl+U) and verify that it didn’t break anything. Now all your links in your tag cloud are marked as nofollow, thus each page containing the tag cloud will give away much less link weight to your tag archive pages (according to Google’s PageRank algorithm), oh by the way Larry Page is now CEO ;)

Update: Also, as Nathan and Andrew mentioned in the comments, there’s a wp_rel_nofollow function available since WordPress 1.5.0, so you might as well use that directly:

add_filter('wp_tag_cloud', 'wp_rel_nofollow');

Works like a charm, but the manual technique I’ve shown earlier allows you to add other relations to links in the tag cloud, for instance archives, or attach tracking code to your links for Google Analytics (a snippet introduced in an earlier post).

Hope that helps you out in your SEO journey.

Using Google's URL Shortener (goo.gl) in WordPress

The Google URL Shortener API has been released this week so I came up with a short snippet that generates short goo.gl URLs. The script is quite simple, you can paste it in your theme’s functions.php file or create a plugin out of it, so without further ado:

function googl_shortlink($url, $post_id) {
	global $post;
	if (!$post_id && $post) $post_id = $post->ID;

	if ($post->post_status != 'publish')
		return "";

	$shortlink = get_post_meta($post_id, '_googl_shortlink', true);
	if ($shortlink)
		return $shortlink;

	$permalink = get_permalink($post_id);

	$http = new WP_Http();
	$headers = array('Content-Type' => 'application/json');
	$result = $http->request('https://www.googleapis.com/urlshortener/v1/url', array( 'method' => 'POST', 'body' => '{"longUrl": "' . $permalink . '"}', 'headers' => $headers));
	$result = json_decode($result['body']);
	$shortlink = $result->id;

	if ($shortlink) {
		add_post_meta($post_id, '_googl_shortlink', $shortlink, true);
		return $shortlink;
	}
	else {
		return $url;
	}
}

add_filter('get_shortlink', 'googl_shortlink', 9, 2);

For the tech people I’ll explain what I’m trying to do here. So first of all we don’t want to shorten links on draft posts as that could be a waste of resources, so we return an empty string. The magic with get_post_meta and add_post meta in the middle and at the end of the function are done for caching purposes — we don’t want to send too many requests to the Google API so let’s keep the already shortened links in the post’s custom fields. This may be annoying in the UI so you might want to add an underscore in the meta key (“_googl_shortlink”) which will make it invisible to the UI.

Next up, I retrieve the permalink of the published post, since we don’t want to shorten an already shortened URL which is that ugly one by WordPress. I use that permalink in an HTTP request to Google’s API using WordPress’ WP_Http object. Note that I’ve added the Content-Type header, which is required by Google, otherwise it’ll return an error. I decode the result body using json_decode (you need PHP 5.2 or later to do this) and if there’s a valid id, which is the shortened URL, I save it to the post’s meta and return the shortlink. If something went wrong, I return the original WordPress’ short URL.

So, clicking on the “Get Shortlink” button in your admin UI will now produce a Goo.gl shortened link to your post. Neat eh? You can also use short links in your theme, somewhere in The Loop:

echo "Shortlink: " . wp_get_shortlink();

Goo.gl Analytics

Right, you might want to see your short links’ analytics at some point. Well, Goo.gl shortened links are all public and their analytics are public too, so all you have to do is browse to goo.gl/info/code where code is the 5-6 alphanumeric digits attached to your shortened URL at the end.

For convenience I wrote a little snippet that would output the short URL and a link to it’s analytics page in your posts list screen inside the admin panel. Below is the code that should go to your functions.php file or plugin file:

function googl_post_columns($columns) {
	$columns['shortlink'] = 'Shortlink';
	return $columns;
}

function googl_custom_columns($column) {
	global $post;
	if ('shortlink' == $column)
	{
		$shorturl = wp_get_shortlink();
		$shorturl_caption = str_replace('http://', '', $shorturl);
		$shorturl_info = str_replace('goo.gl/', 'goo.gl/info/', $shorturl);
		echo "<a href='{$shorturl}'>{$shorturl_caption}</a> (<a href='{$shorturl_info}'>info</a>)";
	}
}

add_action('manage_posts_custom_column', 'googl_custom_columns');
add_filter('manage_edit-post_columns', 'googl_post_columns');

I wrote about custom columns in a post called Custom Post Types in WordPress 3.0, which should give you a general idea of what’s going on here. For more details visit the WordPress Codex.

That’s about it! Yeah, I know there’s some stuff that can be improved here, like smooth error handling, but it’s up to you to implement it. For more info check out the Google URL Shortener Getting Started page. A good place for experiments with Google’s APIs is Google APIs Console.

The plugin-version of this code is available at the WordPress plugin directory: Goo.gl for WordPress. Thank you for reading and retweeting ;)

Review: Nexus One, Android & Software Freedom

The first time I mentioned I wanted a Nexus One phone was on January 21st, 2010. That’s almost a year ago and I was ready to trade in my iPhone for a Google phone. This Christmas I made myself a present and got that Nexus One from some “not so legal” Internet store here in Moscow. I guess they’re (Nexus One & Nexus S) not yet or ever will be certified for the Russian market, so I had a hard time finding one, but I did, and I’m glad I did.

I was an iPhone 3G user for over a year and was quite satisfied with everything that it offered. I didn’t jailbreak it, updated the iOS frequently and used the free applications from the App Store. That’s right, I never spent a cent on software for my iPhone, since most applications had an ad-driven free version available, and I’m quite greedy — I can’t remember the last time I payed for software.

I opened up the Nexus One box and figured that Facebook and Twitter applications were pre-installed, gorgeous! So I instantly tweeted, and posted a photo and the fact that it has a flashlight surprised me. I then found out it came with a 4GB SD card, which is awesome. Yeah, my iPhone had 16 gigs but you can get a 16 GB SD card for around $130 when you run out of the 4GB.

Next up was my e-mail and contacts. Honestly I was a little scared here, since as soon as I added my Gmail account, my phone had all my contacts, and not only! It linked my Twitter and Facebook contacts to my Google ones, and then I installed Skype, and there too, everything was linked and merged, so there’s no longer copying contacts from SIM cards, syncing by connecting to your PC and what not. This is definitely more user-friendly than Apple, way to go Google. And there’s more! When I started texting, Google’s dictionary recognized all the names from my contacts, so I never had to spell my or my girlfriend’s last name again — input three letters and voila!

Then I took a few hours to explore the Android Market. I never knew they had such a place, which could have made me miss my iPhone, but they did, and it was quite easy to navigate around, since it looked very much like the App Store on iPhone. I didn’t try the paid apps but I did give a go at a few dozen free and ad-driven ones, including Angry Birds ;) The Market syncs very well, giving instant applications updates when they’re available.

Next thing to surprise me was Google Voice Recognition, they got their TV ads running around here in Russia. It’s not as good as the TV says, but they get most of the stuff right. There are some language configurations which have to be done in order to recognize both English and Russian. I got that working when writing text, but not Google Voice Search, which keeps giving me junk in English when I speak Russian. Anyways, that’ll be fixed I’m sure.

Battery. Definitely better than the iPhone 3G here, and could be boosted even better with some utilities from the Market. Just make sure you don’t have Sync, Wifi and 3G turned on when you don’t really need them. Multimedia? Ah you’ll love Android if you’d like to read books, watch videos or listen to music, iPod? Meh!

Below is a list of applications that I, as a novice Android user recommend. Some might be pre-installed on your phone. Can’t get you direct links to these, but searching by names in the Android Market will get you going:

  • Foursquare — obviously!
  • Google Reader — still waiting for Feedly for Android, but this is okay I guess.
  • Chrome to Phone — I don’t use it much, but certainly a time-saver.
  • Dropbox — sync files and multimedia to the cloud.
  • ConnectBot — an easy to use SSH/telnet client. Good way to reboot your servers when in the metro ;)
  • Adobe Reader — books save you from being bored.
  • MySettings — quickly turn on and off stuff like sync, wifi, rotate and other settings.
  • OI File Manager — surely one of the best file managers for Android.
  • Thinking Space — create neat mindmaps on the fly and export them to various formats to email, Dropbox, etc.
  • WordPress — of course, it’s where I’m writing this post from ;)

There are also a bunch of interesting widgets, one of which is the Google Analytics Widget that can display pageviews or visitors directly on your home screen. Nice thing to check out waking up in the morning haha ;)

So anyways, the bottom line is yeah — I fell in love with Android. I’m not really looking forward to getting the Nexus S model, although I believe it’s better than Nexus One, and it’s been to outer-space too, but Nexus One is really a first, so I’ll sell that for a couple of thousand after a couple of decades. Besides, I think HTC’s better than Samsung anyway ;)

How to Track Your Social Links with Google Analytics

Quick and easy one. See the links to my social profiles on your right? I’ve been displaying those for years, but I never knew if they were ever clicked on, and if they were, which ones are the most popular ones? Perhaps I have to get rid of some of them, and make other brighter to get more attention? Or maybe simply switch places and keep the most relevant ones on the top left?

After thinking for a while, I figured out that Google Analytics can help me solve this in no time. I heard about Event Tracking with Google Analytics quite some time ago, and I was actually using it to find out how many people were clicking the “more widgets” link in my sidebar (not much), but this time it’s about tracking outgoing links to your social profiles and not only — you can use this technique to track any outgoing links, just make sure you keep it simple.

First things first: go through the Event Tracking guide on Google and make sure you understand what’s going on in theory. Then find out a good javascript code or jQuery selector to bring your social links together, mine is:

jQuery(".social a[rel=me]")

Then use that code to assign an onclick event to each of the social links:

jQuery(".social a[rel=me]").click(function() {
    /* some code goes here */
});

And finally add the magic Google code which does two things: A, tells the Google Analytics servers that your links was pressed and B, slows down the browser relocation for a few milliseconds so that A has a little bit more time. I know slowing down your website doesn’t sound right, but I guess that this is the only way to track visitors with low internet speed (do you have any of those?) Below is the full code that I use on my blog, you can use that as is, but keep in mind that you’ll have to modify your jQuery selector in order to match your website structure:

jQuery("div.social a[rel=me]").click(function() {
	_gaq.push(['_trackEvent', 'Social', 'Profile', jQuery(this).attr('href')]);
	setTimeout('document.location = "' + jQuery(this).attr('href') + '"', 100);
	return false;
});

As you can see, I push the event into the Social category with a Profile action, and then also pass the href attribute of the object that was clicked (a social profile in our case.) All this is then visible in your Google Analytics reports under the Content – Event Tracking section. It’s up to you how you name these, but I’m thinking globally, thus having a Social category which can house Profile clicks, and then extend it to track Share events like Facebook Likes, Retweets, etc.

Hope this helps you sort some things out and gives you a better feel of what Google Analytics is capable of. There’s much more to learn, and Google’s Manuals are there to help you. Don’t be afraid to experiment, and keep your eyes on the javascript debugger console (Chrome or Firefox) as that’s usually the first place to look at when things go wrong.

Thanks for reading and sharing. Hope you have a great New Year party, or hope you did if you’re reading this in 2011 already ;) Cheers!

App Engine: JSON Objects in the Google Datastore

Following up on my previous post about Python Objects in the Google Datastore where I’ve shown an easy way of storing any python object inside the Google Datastore by pickling it. Pickling works fine and it can literally store functions, classes and class instances in the datastore which is great, but as I discussed earlier, JSON could work too, so here I’ll introduce a similar approach at storing JSON objects (strings, lists and dictionaries) inside Google.

The problem with pickling objects is that they’re very difficult to maintain. Google provides a front-end for their Datastore where you can run GQL queries, watch statistics and even manage data on the fly. Since pickled objects are stored in bytes as opposed to JSON strings, I figured that when editing an entity using the Google admin, pickled objects tend to break, since the values sent back to the server by your browser are usually strings. I haven’t found a good way around this yet (update: I did find a way), which is why I temporarily switched to JSON, which is easier to edit and maintain.

Here’s the draft code I’m using to store JSON objects in Google App Engine, which I called (surprise) JsonProperty:

from django.utils import simplejson
from google.appengine.ext import db

class JsonProperty(db.TextProperty):
	def validate(self, value):
		return value

	def get_value_for_datastore(self, model_instance):
		result = super(JsonProperty, self).get_value_for_datastore(model_instance)
		result = simplejson.dumps(result)
		return db.Text(result)

	def make_value_from_datastore(self, value):
		try:
			value = simplejson.loads(str(value))
		except:
			pass

		return super(JsonProperty, self).make_value_from_datastore(value)

Note that Google still runs Python 2.5 hence the simplejson library is only available through the django.utils package (it ships with Python starting from version 2.6).

So the logic is quite clear here, we use dumps and loads to dump and load strings from and to the Datatstore. Perhaps it’s lacking some code in the validate method, we do after all need to check if the given value is convertible to JSON and then raise an exception if not. But I’ll leave that to the next version of this snippet, as I’m currently only using it to prototype stuff and maintain small and medium-sized projects — so do use this at your own risk ;)

As a usage sample you can take this simple code which can be run from the App Engine console:

class MyEntity(db.Model)
    name = db.StringProperty()
    obj = JsonProperty()

my_obj = {'key-1': 'value-1', 'key-2': 'value-2'}
entity = MyEntity(name="my-name", obj=my_obj)
entity.put()

entities = MyEntity.all()
entities = entities.fetch(10)
for entity in entities:
    print entity.obj # outputs the dictionary object

And don’t forget that you can manually browse the Datastore using your App Engine dashboard and see how such entities are actually stored.

I wrote about performance in that previous post, but honestly, I didn’t have the time to measure it, so if you guys do feel free to leave your benchmark results in the comments section. Some graphs would be cool too. Oh and thanks for retweeting!