We use this blog to tell you what we’re currently up to. We often share solutions to technical problems if we think they might be useful…

I used to think that the hardest part of scaling a website from one webserver to two webservers was sharing the sessions between the machines to keep the users logged in whichever machine they were served by. I was pleasantly surprized that it is possible to accomplish sharing sessions between two servers by changing only 5 lines in the php.ini file (the session.save_handler and session.save_path).

Here is a solution for RHEL 5.5:

Read on…

Wordpress Logo

In WordPress 3.0, my WordPress logo image (on the left) broke. So I opened a bug and six weeks and 100 bug comments later, I have upgraded to 3.01 and it is working again. Thanks guys!

The reason why the logo image was broken was quite interesting(?)… In v3.0 WordPress automatically started auto-correcting Wordpress to WordPress (i.e. Word-lowercase-p-ress to Word-uppercase-P-ress) and because my image file name was called “WordpressLogo_blue-m.png”, the auto-correction was breaking the link. Auto-correction shouldn’t cause links to break and it seems that v3.01 fixes it.

The filter function that does this auto-correction is called “capital_P_dangit” – The WordPress guys are obviously pretty frustrated by this spelling mistake!

Old filter (v3.0):

function capital_P_dangit( $text ) {
       return str_replace( 'Wordpress', 'WordPress', $text );
}

New filter (v3.01):

function capital_P_dangit( $text ) {
        // Simple replacement for titles
        if ( 'the_title' === current_filter() )
                return str_replace( 'Wordpress', 'WordPress', $text );
        // Still here? Use the more judicious replacement
        static $dblq = false;
        if ( false === $dblq )
                $dblq = _x('“', 'opening curly quote');
        return str_replace(
                array( ' WordPress', '‘Wordpress', $dblq . 'Wordpress', '>Wordpress', '(WordPress' ),
                array( ' WordPress', '‘WordPress', $dblq . 'WordPress', '>WordPress', '(WordPress' ),
        $text );
}

Wordpress Logo

When I was building the property gallery for greekislandpropertyfinders I wanted to use a fancy javascript image gallery like Galleria, however I came across a problem with Galleria in that it couldn’t display more than one gallery on any page. It’s open-source so I used the source code to help write my own version and turned it into a WordPress plugin with the features I needed.

The plugin isn’t all that generalised, so I’m not sure it’ll be useful to many people but I think it’s a tool worth sharing.

Plugin features:

  • This plugin doesn’t change the WordPress media gallery admin interface – galleries are created and inserted into pages/posts as normal (i.e. using the media upload GUI + the
    [gallery]
    shortcode). WordPress authors won’t need to change or learn anything new.
  • The plugin makes efficient use of WordPress media (no front-end image resizing via CSS!) which means it doesn’t matter if one of your authors uploads a load of 3MB images to a gallery – it’ll still run fast.
  • The plugin doesn’t pre-download images that aren’t needed – it displays a loading spinner image when the user is waiting for a image on load.
  • Should be easy to style the gallery in your own way – uses CSS classes and IDs.
  • The user can click on the main image to cycle through the gallery.
  • Uses jQuery for cross-browser hover fade effects.
  • Small JS footprint: 2854 bytes.
  • Outputs valid XHTML (unlike the default WordPress gallery!).

Screenshot of the plugin:

Screenshot of Bitvolution-image-galleria plugin

Click to enlarge

Demo of plugin: www.greekislandpropertyfinders.co.uk/what-we-are-finding.

Download the plugin from the WordPress.org plugin directory.

Screenshot of Page Speed in Firebug
I find the Page Speed tool from Google extremely helpful for optimising my websites. I have a tip which can save time if your website is failing the “Optimize Images” test. Using the in-built Smush.it is one option but if most of your images are jpegs, you can achieve the same result and save time using a command line tool called jpegtran with the -optimise parameter to do lossless compression and the -copy none parameter to strip out image meta-data.

Disclaimer: As with any image processing always keep a copy of the original images.

To install jpegtran in Ubuntu, do:
sudo apt-get install libjpeg-progs

  • To optimise a single jpeg image:
    jpegtran -copy none -optimise -outfile image.jpg image.jpg
  • To optimise all jpegs in the current directory:
    for img in `ls *.jpg`; do jpegtran -copy none -optimise -outfile $img $img; done
  • To optimise all jpegs in the current directory and all child directories:
    find . -name “*.jpg” -print0 | xargs -0 -I filename jpegtran -copy none -optimise -outfile filename filename

If you need to optimise various image formats, there is a PHP CLI tool called smusher which uses Smush.it and can work recursively on directories. Might be worth a look. It would be nice if Smush.it had a API – their FAQ mentions they are working on it.

Greek Island Property Finders Screenshot

We have just finished and published greekislandpropertyfinders.co.uk which is a modified clone of http://www.heidijoycegardens.com.

Technical details of site:

Screenshot of problem with too big tag

On this WordPress theme, the sidebar is quite small (only 220px) and the default WordPress tag cloud widget was producing tags that were clipped in a ugly manner. By default, the WordPress tag cloud widget has a maximum font size of 22px so I was looking for a way to reduce it.

Note: If you are not a theme editor, you might find it easier to just install a suitable tag cloud plugin, e.g. Configurable Tag Cloud (CTC).

The WordPress tag cloud widget already allows you to specify various options including the largest font size, e.g. <?php wp_tag_cloud('largest=18'); ?> so we only need to create a new widget that overrides the default widget and then unregister the default widget so there aren’t two widgets with the same name in the “Available Widgets” dashboard page. We can register our own widget using register_sidebar_widget and we can unregister the default tag cloud widget using unregister_widget('WP_Widget_Tag_Cloud');.

This is the code you need – put it in the functions.php file in your WordPress theme folder:

add_action("widgets_init", array('Tag_cloud_withLimitedFontSize', 'register'));

/** Widget - Override the default WordPress tag cloud BUT cap the largest font size to 18 (instead of 22)\
 because at 22 some tags don't fit in the sidebar. */
class Tag_cloud_withLimitedFontSize
{
  function widget($args){
    echo $args['before_widget'];
    echo $args['before_title'] . 'Tags' . $args['after_title'];
    echo wp_tag_cloud('largest=18');
    echo $args['after_widget'];
  }

  function register()
  {
    register_sidebar_widget('Tag Cloud', array('Tag_cloud_withLimitedFontSize', 'widget'));
    unregister_widget('WP_Widget_Tag_Cloud');
  }
}

If there’s a better way to do this, please let me know.

Microchip as a bug

A website that I was working on suddenly started crashing Firefox 3.6 on my PC (Ubuntu 9.10, 64bit). I’m talking a full out hang with 100% CPU usage and a frozen mouse and keyboard and the only way to recover is to remote login from a 2nd PC and kill the Firefox process.

I found the cause of the crash and it was a single line of recently added CSS code at the top of the websites stylesheet: body { opacity: 0.9999; }

So, if you run a website, be careful of non-100% opacity when it affects many elements. I have hosted a page that reproduces the issue and found a bug that tracks the issue: #279890. This CSS is also a problem on Windows – it causes text to blur horribly in IE 7 in some situations.

What is that CSS for anyway? Firefox 2.0 on Macs used to have a problem where text could dim or get bold or flicker when a animated effect that changed the opacity of an element was used. It was caused because the use of a opacity filter triggered the Gecko rendering engine to switch from the operating system’s method of anti-aliasing to its own internal method. Whenever opacity dropped below 100% the mode switched and resulted in a defect such as a flicker or blink. The fix was simple – all that was needed was to add body { -moz-opacity: 0.9999; } to the stylesheet because it would force Firefox to use a consistent text rendering method.

Hack == Bug

PeoplePerHour Economy

I’ve just finished a new webpage called PeoplePerHour Economy that was written about in the mainstream tech press (see bottom half of article):

Screenshot of Peopleperhour marketplace page

Technical details:

  • The charts and graphs are implemented using the Google Charts API – a simple and extremely efficient method of producing charts.
  • The charts (and chart data) are cached over a 24 hour period to take some load off the webserver. The caching is done by some simple PHP code – memcached seemed overkill.
  • The UK map is implemented using a 3rd-party image map with polygon co-ordinates specifying each county. The hover-over highlighting is done using a JQuery plugin called mapHighlight.
  • The “Job-o-meter” is implemented using a JQuery plugin called jOdometer customised to format the number with commas and animate the digits with some easing. I have made the customisations available via a github fork.

Wordpress LogoToday, I found out about a WordPress plugin called Elastic (http://elastictheme.org/, download link) which is a WYSIWYG theme editor for WordPress.

It looks like a very promising technology to make it easier to develop WordPress themes. I’m interested in re-useable modules so, if I develop something interesting for one client, I can re-use the same something for a different client with 1-click (therefore being able to quote them a reduced price). Plugins and widgets achieve this to some extent but Elastic aims to make the same possible at a more fundamental level.

Wordpress LogoA typical use case for a hidden page might be so you can store your website licensing agreement or image attribution links without having it explicitly in the main navigation links – most folk link to their licensing agreement in the footer.

If you want to have a page on your self-hosted WordPress website that is accessible via a URL but not directly linked or advertised on the site, you have several options:

  1. Use a plugin such as “Exclude Pages“.
  2. If your pages are displayed via a sidebar widget, you can go to the widget settings page in the WordPress admin section and use the “exclude” field to hide a page ID.
  3. Save the page as a “draft” but never publish it. Even though it’s not live, you can still access the page if you type the direct URL to the page. e.g. http://yourblogurl/?page_id=69.
  4. Modify the wp_list_pages function in your current theme:
    • If you know you don’t use any sub-pages on your site, you can hide any page you want by making it a sub-page of the homepage and then display your menu using: <?php wp_list_pages('depth=1'); ?>
    • To exclude a page with id 69, use: <?php wp_list_pages('exclude=69' ); ?> If you do this you can automatically hide additional pages by making them a sub-page of the hidden page.
  5. Create a new file in the theme directory. It will be accessible via http://yourblogurl/wp-content/themes/yourthemename/yoursecretpage.php. If you want to use regular wordpress functions in the secret page, include the following on line 1: <?php require_once(dirname(__FILE__) . '/../../../wp-blog-header.php'); ?>

Note: WordPress does have a “Private” checkbox that you can tick in the visibility section of the publish options. However, private pages will not be accessible via any URL.

Look at the difference between these two 50px headers that use the Georgia font:

Windows/Ubuntu font comparison - Georgia

The top one is from IE8 on Windows Vista, whereas the bottom one is from Firefox 3.0.15 on Ubuntu 9.04. On Windows, the text is clearly less pleasant on the eye? It is has jagged edges, has a pixel or two cut off the end of the ‘s’ and is 17 pixels less wide.

This is the styling code:

#logo h1 {
font-family:Georgia, Arial, sans-serif;
font-size:50px;
font-weight:normal;
letter-spacing:-0.05em;
line-height:normal;
}

Read on…

In a previous tutorial we went through some tedious steps to generate 3 images that could be used to create a page shadow. The great thing about the GIMP is that anything you can do with a mouse and keyboard, you can also do via script.

We will generate the following images automatically:

Demo of what we will generate

Why script it?

  • It allows us to tweak settings and quickly re-generate the image to see the results. For example, we can ask ourselves, “I wonder what it’d look like if the shadow was a bit bluer?”
  • We can automatically generate multiple images (including, for example, a image suitable for a CSS sprite).
  • We can can adapt and re-use the scripts for different websites. For example, one website might use square angular edges, but another might use rounded corners – so you can adapt to use rounded corners in the background image by changing 1 line of the generation script.
  • Mice are evil – why involve a mouse when all we need is a keyboard?

Read on…

In this tutorial we are going to create a very basic “blank canvas” webpage which has a central white cut-out with a drop shadow effect. Our “page” will be 960px wide, floated in the center of the browser window:

Tutorial end product

aBlankCanvas
Click to enlarge

Real-world example

a non-blank Canvas
Click to enlarge

Read on…

I’ve just finished a revamp of the PeoplePerHour.com hompage:

Previous Design

Screenshot of previous design

New Design

Screenshot of new design

The new design was needed to give space to spotlight “featured” projects (which are a new addition to the site). I think the homepage should stand out a bit more now because it’s more striking?

If you are making a WordPress theme you owe it to the user of your theme to make sure image alignment works as expected. Most of the Visual Editor formatting buttons use inline CSS which won’t be affected by the theme but this is not the case with the alignment buttons in pages/posts when applied to images.

The red labels show what Visual Editor buttons I’m talking about:

Wordpress visual editor image alignment buttons

Read on…

The following list is 10 favourite pieces of software which I’m thankful for every single day:

  1. 10. Meld file difference viewer
  2. 9. JQuery javascript framework
  3. 8. Trac project management platform
  4. 7. MythTV digital video recorder
  5. 6. Gimp image manipulation program (I know this is part of GNU but hey ho)
  6. 5. WordPress publishing platform
  7. 4. Firefox web browser
  8. 3. Ubuntu operating system
  9. 2. Linux kernel
  10. 1. GNU projectGnome Desktop (but also all the rest: e.g. gcc, glibc, gtk, emacs and the GPL)

If you want to use the “Purisa Light” font on your Linux hosted website, you can follow the following steps:

  1. Copy the font file from your desktop machine to your webserver. On Ubuntu the “Purisa Light” font file is located at /usr/share/fonts/truetype/thai/Purisa.ttf. e.g:
    scp /usr/share/fonts/truetype/thai/Purisa.ttf <username>@<webhost>:/<pathToWebsite>/fonts/Purisa.ttf
  2. Add the font face to your stylesheet:
    @font-face {
        font-family: 'Purisa';
        src: url('fonts/Purisa.eot'); /* For IE */
        src: local('Purisa'),
             url('fonts/Purisa.ttf') format('truetype');
    }
    
  3. Now you should be able to use it in your site pages. e.g.
    <div style="font-family:Purisa,arial">
    This should be in the "Purisa Light" font...
    </div>
    
  4. BUT, we’re not done yet because unfortunately, IE does not support TrueType (ttf) fonts – only Embedded Open Type (eot) fonts.
  5. Download ttf2eot from http://code.google.com/p/ttf2eot/ – it is a open-source font format converter.
  6. Extract it to your home directory. Then build it:
    cd ~/ttf2eot-0.0.2-2
    sudo apt-get install build-essential
    make
    
  7. Convert the font:
    ./ttf2eot < /usr/share/fonts/truetype/thai/Purisa.ttf > Purisa.eot
  8. Copy it to your website, e.g
    scp /usr/share/fonts/truetype/thai/Purisa.eot <username>@<webhost>:/<pathToWebsite>/fonts/Purisa.eot
  9. Now it should work on IE. If you don’t have time to convert this font, you can grab mine – use “view source” to find the URL from the stylesheet.

@font-face is a HTML5 feature supported by Safari 3.1+, Firefox 3.5+, Opera 10+ and IE 4+. At the time of writing Google Chrome currently doesn’t support @font-face (but the beta version does so it won’t be long).

This post was inspired from an excellent article called @font-face in Depth.

What is a “Amazon Carousel”? It is a advert showing a bunch of items you can buy on Amazon:

Amazon put a limit on the number of items in a carousel. However, if you have more than 10 items, you can use a little javascript to select 10 at random so a different set are shown on each page view.

This is some javascript that randomises an array of ASIN numbers:

var asinArray = new Array('0874477182', '0764138057', '0764136321', '0375428569', '0375764313', '037576433X', '0375428607', '141955252X', '141955039X', '0874477565', '0874477727', '037576593X', '0375429115', '0375765891', '0375765883', '0375429093', '0375429077', '0375429123', '0375429085', '0953265978', '0856609781', '1402209592', '0375428720', '0312366914', '0142003085', '0374525137', '0143112821', '0099479028', '1932080309', '0140620184', '0141185570', '014023750X', '014103534X', '0312361785');
document.write('Normal : ' + asinArray + '<br />');
asinArray.sort(function(){return (Math.round(Math.random())-0.5); });
document.write('Random : ' + asinArray + '<br />');

To select 10 from the randomised array:

if (asinArray.length > 10)
 asinArray.length = 10;
document.write('Random 10: \'' + asinArray.join(',') + '\'<br />');

To apply this to the Amazon Carousel:

<script type='text/javascript'>
var asinArray = new Array('0874477182', '0764138057', '0764136321', '0375428569', '0375764313', '037576433X', '0375428607', '141955252X', '141955039X', '0874477565', '0874477727', '037576593X', '0375429115', '0375765891', '0375765883', '0375429093', '0375429077', '0375429123', '0375429085', '0953265978', '0856609781', '1402209592', '0375428720', '0312366914', '0142003085', '0374525137', '0143112821', '0099479028', '1932080309', '0140620184', '0141185570', '014023750X', '014103534X', '0312361785');
asinArray.sort(function(){return (Math.round(Math.random())-0.5); });
if (asinArray.length > 10)
	asinArray.length = 10;
var asinText = "'"+asinArray.join(',')+"'";
var amzn_wdgt={widget:'Carousel'};
amzn_wdgt.tag='<your Amazon id>';
amzn_wdgt.widgetType='ASINList';
amzn_wdgt.ASIN=asinText;
amzn_wdgt.title='New Video Game titles from Amazon';
amzn_wdgt.width='600';
amzn_wdgt.height='200';
amzn_wdgt.marketPlace='GB';
</script>
<script type='text/javascript' src='http://wms.assoc-amazon.co.uk/20070822/GB/js/swfobject_1_5.js'>
</script>

Next Page »