Oct 1

I manage a number of wordpress blogs such as this one, and wordpress plugins can really improve the experience. Here are my five favourite wordpress plugins that I can’t live without!

1. Comments (DISQUS)

Wordpress’ built in commenting sucks. The DISQUS comment system replaces your WordPress comment system with your comments hosted and powered by DISQUS. You get user authentication, ranking, spam filtering, pingbacks and much much more when you install disqus. This is the first thing I install on any wordpress blog.

Get Plugin from Disqus.com

2. Twitter (Tweetable)

This plugin fully integrates Twitter with your WordPress blog. As well as automatically tweeting new blog posts, it also display your latest tweets in your sidebar and shows a tweetmeme counter on your blog posts. The perfect all-in-one solution for twitter + wordpress!

Plugin Page

3. FeedBurner (Flagrant Diregard)

This plugin detects all ways to access your original WordPress feeds and redirects them to your FeedBurner feed so you can track every possible subscriber.

Plugin Page

4. Syntax Highlighting (WP-Syntax)

If you have a blog where you often post code samples in your articles, it helps to have syntax highlighting for these sections. This plugin supports tons of languages and uses GeSHi for the parsing so it is well supported.

Plugin Page

5. SEO (All in One SEO Pack)

Out-of-the-box SEO for your Wordpress blog. Adds meta keywords and descriptions, optimises your page titles and urls, and stops duplicate urls being created.

Plugin Page

Let me know which plugins you can’t live without in the comments below!

Aug 5

What’s the Problem?

If you use HTML anchors on your webpages (for example http://www.example.com/index.html#anchor) and also embed flash files, beware of a flash player bug which might cause preloaders on your swf files not to appear!

Why does this happen?

This flash preloader bug (which is still unresolved) means that large swf files with preloaders will not show the preloader while the rest of the swf is loading, meaning you may see a blank box when waiting for the file to download completely.

Flash 6+ has had the support for named anchors within swf files, meaning that your flash file can set and read #anchor tags to jump between frames in your flash movie. When you have an unrecognized anchor tag in your URL, flash doesn’t know which frame to jump to, and therefore appears to jump to the first frame of the inner swf file, therefore skipping the preloader.

What’s the solution?

If the swf file and preloader are outside your control, you’ll simply have to remove any anchors from the original url, at least until Adobe issue a flash player fix.

If you do have access to the swf file and you’re using Flex 3, you can use the BrowserManagerShim class attached to this bug report.

If you’ve found any other general solutions, please let me know and I’ll update this post!

Jul 13

What is WeGot.tv?

I’ve been working on a web app in my spare time for a while called wegot.tv, which is intended to help people track their TV viewing online. I recently joined the team at Heyzap and my focus has shifted away from wegot.tv, so I’m looking for someone to pick up the reigns and take it forward!

You can see the current state of the the site at:
http://beta.wegot.tv

Here’s my user profile, with the TV shows I like and which episodes I’ve recently watched:
http://beta.wegot.tv/users/loopj

picture-3

The Grand Vision ;)

I designed wegot.tv for people who want to get more out of their tv viewing experience. I typically watch TV that’s streamed, downloaded or purchased rather than broadcast, and tracking which episode of my shows I last watched was becoming difficult and annoying, so that’s how wegot.tv started. You can select a bunch of your favourite shows, add them to your profile, and then mark each episode as watched as you viewed them. I also wanted to know when the next episode of my favourite shows would be available to download, so I built in a customised TV schedule.

My plan was to use the collected data about viewing preferences to recommend new tv shows to users, provide streamed episodes of their favourite shows right in the site (from hulu, bbc iplayer, etc) and to provide links to iTunes, Amazon etc to purchase episodes.

There are tons of possibilities and opportunities in this space, and given more time I would have loved to build them all!

How Can You Help?

I’m looking for someone who has a similar vision, and a passion for TV, who would love to take this project on and grow it. If you want to make this into a business that would be awesome, but even as a hobby it would be great to see something I started blossom into a popular site. I’m sure there’s at least one person out there apart from me who would find this useful!

I’d transfer ownership of the project (code, domains, art etc).

Tech Details

I built the site using the django framework, TV show data is fetched (with permission) from a great site called TheTVDB, I’m using a MySQL database, and various python scripts for scraping and data collection. I own wegot.tv and wegottv.com. All of the project code is in a subversion repository.

I’m Interested, What Now?

I really want to find someone who will take this project somewhere, as it would be a shame to see this work and idea go to waste. If you think this is you, get in touch.

Hit the comments below and tell me a little about yourself and your vision for the site if you were to take it over, leave a way to contact you and I’ll be in touch!

Alternatively, send an email to wegottv at loopj.com.

Jul 6

What’s the Problem?

If you take regular backups using mysqldump, you’ll know that backing up a large database can often take a few minutes to complete. What most people don’t think about when creating these type of backups, is that restoring your database from mysqldump backup files takes much much longer.

How Can I Speed Up This Process?

By setting a couple of flags before you import your database dumps, you can dramatically speed up the restore process:

SET autocommit=0;
SET unique_checks=0;
SET foreign_key_checks=0;

Since we disabled auto-commit, we’ll also need to manually commit at the end of the restore:

COMMIT;

Since we are restoring an entire database, we can speed things up by disabling unique checks and foreign key checks. Also, by committing everything at the end of the restore, rather than as the restore is in progress we get significant additional speed increases.

When Should I do This?

You could manually set these flags when restoring your database, but I prefer to add these lines into the backup as it is created.

For example, this bash script will add the speedup lines straight into your backup .sql file:

#!/bin/bash
echo "SET autocommit=0;
SET unique_checks=0;
SET foreign_key_checks=0;" > backup.sql
mysqldump -u myuser --password=mypassword mydatabase >> backup.sql
echo "COMMIT;" >> backup.sql

I hope this is useful to someone! Let me know in the comments if you have any further optimisations.

May 23

Introduction

I’ve recently started work on a Rails project after working on many Django apps in the past couple of years and I’d like to share my experiences and gripes from my transition. Rather than attempting to analyze all the pros and cons of each framework, I’m going to try to focus on the transition pain points.

Python vs. Ruby (Perl’s Ugly Sister)

Python and Ruby are quite similar languages and I’m not going to compare them in any serious depth. Both have their relative merits and I find both languages easy to work in. The one complaint I have about Ruby is that it borrows far too much from Perl. I’ve done a fair bit of scripting in Perl, and most people agree with me that Perl scripts of any substantial size quickly become very difficult to maintain.

Ruby is a great language but it tries to provide similar syntax and constructs to Perl, while duct taping all of Ruby’s own powerful features on too. This makes the Ruby syntax look like someone emptied all the symbols from the keyboard into a shotgun and shot them into your face.

Another irritating habit Ruby borrowed from Perl is having multiple ways of doing the same thing when simple having one way would be fine.

Say what you will about Python’s whitespace rules, but Python code is easy to read and consistent, and generally there is a single correct way of doing things.

As I mentioned earlier though, I do like Ruby, and one of the awesome features is Ruby’s blocks. Blocks are basically Ruby’s way of implementing closures and they are extremely flexible and powerful. In Python, to do something similar you’d use lambdas or list comprehensions.

Views Versus Templates

In the Rails world, the layer which generates the final markup sent to the browser is called the View layer. In a Rails View, you can chuck as much rails code as you like in amongst your markup.

Some of the early sites I worked on many years ago were written in PHP, which had the same idea. Rails views and PHP both allow the developer to mix markup and code together in the same file. When making PHP sites, you quickly learn that this is a terrible idea and quickly becomes a maintenance nightmare. One of the best things I ever did in my PHP days was to start using a PHP templating library, such as Smarty.

By restricting the template layer to simple constructs, like Smarty and Django both do, the developer is forced to keep business logic and complex constructs separate from the markup, which makes maintaining and changing the markup in future a piece of cake.

When it comes to markup reuse, the two frameworks are quite evenly matched. Django has template inheritance, which I think is a very elegant solution to the age old problem of sharing common markup, whereas Rails solves this problem using “Layouts”. Both frameworks also support template inclusion and “partials”.

Multiple Apps in a Project

When developing web projects, there are many situations where you need to have 2 very different applications which may need to access some of the same data. In the django world, you create a project and a project may contain multiple applications. Application B can use the ORM classes defined in application A’s model layer if it so chooses.

In rails, there is no such distinction between project and application. If you want to share model layer objects between code, your best bet is to have all the code in the same application. If you wish to logically seperate your applications, you can do so by creating 2 seperate rails projects, but it is not easy (or recommended) to share the models between the 2 projects. Another option is to have a controller per logical application, but this quickly leads to huge amounts of code in each controller.

URL Routing

In Django, you design the URLs for your application using regular expressions, a skill in every programmer’s toolbox (or at least it should be). In Rails you do these mappings using Ruby. Anyone who knows how to write regular expressions can instantly write url matching/capture expressions in Django.

Schema Migration

One thing Rails used to be much better at than Django was database schema migration. This is a feature built into Rails, but Django developers used to have to write manual schema migration scripts to transition their databases. These days though, there are numerous choices for easy schema migration for Django projects, my favourite being South. This is an area where Django really had to play catch-up though, and the various stable projects which have emerged to supporting migration are indicative of the maturity of Django as a whole.

Conclusion

Django and Rails both have their strong points and are similar in many ways, but certain fundamental philosophies differ, especially the Convention vs Configuration side. They are both great frameworks, and transition issues aside I look forward to working more with Rails in the future. Let me know what you think in the comments section below!

May 6

Overview

TheTVDB.com is user contributed TV show and episode database which is used by many popular home theatre applications, such as XBMC to look up details of TV shows.

I’ve written a simple Python interface to their Programmer’s API which makes it possible for developers to extract the TV data they need from TheTVDB with minimal effort.

Let me know if you find this useful, or you use it in any real projects!

Dependencies

This module uses cElementTree (available in Python 2.5+) to traverse XML, so you’ll need Python 2.5 available. Alternatively if you have an older version of Python you can install cElementTree or ElementTree yourself, and modify the import line at the top of the file.

Usage

I’m not going to go into great detail about the interface because the module is fairly self explanatory, but here are a few of the main functions:

Classes

There are 2 classes, the Show class and the Episode class. Most functions in this API return either a Show object, an Episode object, or a list of IDs. I’m not going to document all of the properties in each object as these are visible in the module itself, but you’d usually access the public variables directly, e.g. episode.overview.

Functions

  • get_matching_shows(show_name)
    Returns a list of tuples (id, name) of all matching shows in thetvdb
  • get_show(show_id)
    Get the show object matching this show_id.
  • get_episode(episode_id)
    Get the episode object matching this episode_id.
  • get_show_and_episodes(show_id)
    Get the show object and all matching episode objects for this show_id.
  • get_updated_shows(period)
    Get a list of show ids which have been updated within this period (day/week/month).
  • get_updated_episodes(period)
    Get a list of episode ids which have been updated within this period (day/week/month).
  • get_show_image_choices(show_id)
    Get a list of image urls and types relating to this show.

License

I’m releasing this under the GPL2 license. If you reuse it or improve it, please let me know!

Download

http://loopj.com/thetvdbapi/thetvdbapi.py

Apr 25

Version 1.1 Released!

  • Updated the license to jQuery standard GPL/MIT dual license
  • Moved the plugin to github by popular demand
  • Escape and tab keys now work (Thanks Dirk Bergstrom)
  • Can use settings.minChars to specify how many characters need to be type before a search is started (Thanks Dirk Bergstrom)
  • Can now prepopulate the list by settings settings.prePopulate with an array of {id: n, name: blah} (Thanks Nathan Edminster)
  • Can now change the name of the query param using settings.queryParam (Thanks Elijah Insua)
  • Can now preprocess the returned search results by specifying a settings.onResult function (Thanks Elijah Insua)
  • Can now set the content-type of returned data using settings.contentType (Thanks Elijah Insua)
  • Can now specify the maximum number of tokens allowed using settings.tokenLimit (Thanks Chris Dary and Paul)
  • Can now grab results from anywhere in the json using settings.jsonContainer (Thanks Richard G)
  • Can now fetch results using POST as well as GET with settings.method = “POST” (Thanks ellisgl)

Overview

This is a jQuery plugin to allow users to select multiple items from a predefined list, using autocompletion as they type to find each item. You may have seen a similar type of text entry when filling in the recipients field sending messages on facebook.

Features

  • Intuitive UI for selecting multiple items from a large list
  • Layout controlled fully in CSS, easily customisable
  • Result caching reduces server load
  • No images required, just the plugin’s .js file and some CSS
  • Handles json search data for autocompletion
  • Smooth animations when results load
  • Select items using the mouse or keyboard

Screenshots

Vertical list style item selection
Vertical list style item selection

Facebook style item selection
Facebook style item selection

Demo

A live demo of the token input is available here.

Usage

  • Make sure you have jquery script included on your page
  • Include jquery.tokeninput.js on your page
  • Include one of the provided stylesheets, or make your own
  • Create a server-side script (php/rails/django anything goes) to generate the search results.
    The script itself can fetch data from wherever you like, for example a database or a hardcoded list, but it must do the following:

    • Take exactly one GET parameter named “q” which will contain the query string. E.g. http://www.example.com/myscript?q=query
    • Output JSON search results in the following format:
      [{"id":"856","name":"House"},
       {"id":"1035","name":"Desperate Housewives"},
       {"id":"1048","name":"Dollhouse"},
       {"id":"1113","name":"Full House"}
      ]
  • Turn text inputs into tokeninputs using jQuery and point them to your results script:
    <script type="text/javascript">
    $(document).ready(function () {
      $("#my-text-input").tokenInput("/url/to/your/script/");
    });
    </script>
  • A list of selected item ids is created inside the original text entry, process them as usual when the form is submitted.

License

This plugin is released under a dual license. You can choose either the GPL or MIT license depending on the project you are using it in and how you wish to use it.

Download

Quick Download

Please don’t use these links directly in your scripts, I might change their location at any time. Instead, download them and use your own local copy.

Github Project

If you would like to contribute to this plugin, check out the github repository here:
http://github.com/loopj/jQuery-Tokenizing-Autocomplete-Plugin/tree/master

Jun 16

CSS veterans will probably already know this, but here’s a fix to a problem which has been bugging me for ages.

Problem:

If you have something like:

<div>
    <img src=... />
</div>

You may see a gap below the image on some browsers, a gap which cannot be removed by setting the padding/margins to 0:

Solution:

<img> tags are rendered using display: inline by default, which means they act and flow like text does on a page. In order to stop spaces being added (caused by spaces next to the img tag in your html), you should set your img to use display: block.

<img style="display: block" src="..." alt="" />

This means your image will no longer act like flowing text and will no longer have a gap below it!

Caveats:

Changing from display: inline means your img tag will ignore things like text-align: center, and other alignments specific to displaying elements inline.

Image credit: buhsnarf on flickr

Jun 13
The Original Microblogger
icon1 James Smith | icon2 Blogging | icon4 June 13th, 2008| icon3Comments

I’ve just been reading an article about the diarist Robert Shields, who sadly passed away last year, describing his amazing “condition”.

Robert was thought to have hypergraphia, an overwhelming urge to write, and detailed every action of his life meticulously in a collection of diaries. The entries chronicled every 5 minutes of his life.

Every mundane, boring detail, such as the following gem:

July 25, 1993
7 am: I cleaned out the tub and scraped my feet with my fingernails to remove layers of dead skin.
7.05 am: Passed a large, firm stool, and a pint of urine. Used five sheets of paper.

It struck me how similar this was to the actions of heavy twitter users (I will refrain from mentioning specific names!), tweeting every insignificant detail of their lives.

Twitter’s growth problems aren’t a new phenomenon either, Robert too suffered from service scaling issues as his diaries piled up to fill 94 cartons.

These diaries are now in the safe hands of Washington State University, but won’t be released to read for another 49 years. I can barely contain myself.

Robert Shields was a true pioneer. I salute you!

May 1

At the end of March, Jude and I bumped into Vincent and Eugene from intruders.tv at Minibar London where I mentioned that it was a shame we couldn’t really get to any of the cool web conferences going on in Europe, at which point Vincent mentioned they were looking for someone to do some interviews at The Next Web 2008 conference in Amsterdam the following week. Go to Amsterdam, the party capital of Europe, and interview some of the hottest people in the tech world. Hell yes.

So following in the illustrious footsteps of Immad, we grabbed the camera, flew over to Amsterdam and tried to interview the best people we could find. Who knew it would be so easy!

The first major interview we got was with Kevin Rose of digg.com fame and talked to many more people throughout both days, it seems that if you have a camera and you ask politely for an interview, people are more than happy to oblige.

It was great fun, an awesome way to meet people and make great friends and contacts.

So check out intruders.tv if you haven’t been there before, and especially check out the interviews we did :)

Kevin Rose (digg.com, diggnation, revision3, pownce)

Jessica Mah (Entrepreneur, blogger)

Werner Vogels (Amazon.com)

Adeo Ressi (thefunded.com)

Stefan Fountain (soocial.com)

Khris Loux (js-kit.com)

David Prager (revision3.com)

Gary Cige (zilok.com)

« Previous Entries