Welcome to richardsweeney.com v4.0!

A warm welcome to the fourth incarnation of my website and blog. The site is (finally) now fully responsive (the previous incarnation was my very first attempt at responsive design) and the theme design is (obviously) my own. For those of you don’t know what ‘responsive’ means: the website adjusts to different screen sizes, reflowing content layout as required for better readability.

My goal this time round was (as well as creating a responsive site) to not use any WordPress or JavaScript plugins. This time I wanted to build everything myself. I’m delighted to say that I managed it all except for the plugin I use for server-side caching, which is not my area of expertise. WP Super Cache is such an excellent solution and so very easy to implement, so I used that.

So, what did I do then?!

Well, I build the contact form on the contact page. The form uses JavaScript validation (my own) and is submitted via AJAX. I used Akismet for spam protection on the server-side and a honey-pot* as an extra anti-spam measure. Works great.

I also wrote my own comment form script (see below this post!), which again uses Akismet for spam checking and simple JavaScript validation. Comments are submitted via AJAX.

Speaking of AJAX… I also wrote a custom pagination solution for my blog in AJAX. I used the HTML5 history API to push changes in page to the URL so all pages will have proper, linkable URLs. I freely admit here that I used Benjamin Lupton’s History.js to sort out all the rough edges of different browser implementations of the API!

Also on the blog page I use a custom excerpt function that’s a bit more versatile than WordPress’ built in the_excerpt().

I also wrote my own script in jQuery to fetch my Instagram feed (check out the right-sidebar/below this post). Fetched results from the Instagram API are cached in localStorage (where available) for speedy subsequent page visits. For good measure I also wrote the lightbox script used to enlarge the images. The twitter feed is also written in jQuery and all scripts are loaded asynchronously so that page load is not blocked.

That’s about it! It’s a great feeling to have such control over the entire contents & markup of a website. I ♥ WordPress.

*An input field in the form that is hidden from visitors via CSS. As it’s hidden, user’s won’t fill it out, but if form fields are filled out automatically (ie by a spam bot), it will help to show up spam.

WordPress: create a widget using code from a plugin class

I’m writing a new WordPress plugin: an audio player written atop the marvellous jPlayer. I wanted to give the user the option to add the audio player via a widget, but as my plugin was written OOP I wasn’t really sure how to register the widget using code from my plugin.

It turns out it wasn’t particularly difficult, but I couldn’t find any documentation about it online, so I figured I’d write this wee post, in the hope that it might come in useful for my fellow WordPressers!

My plugin code is written in OOP:

class MyCoolPlugin {
// All my methods + properties here
}
// Instantiate the class
$cool_plugin = new MyCoolPlugin();

The class contains a method to create the HTML that I want to use for both a shortcode and a widget.

class MyCoolPlugin {
  // Returns the HTML for a shortcode or widget
  function shortcode_widget() {
    return '<p>HTML rocks</p>';
  }
}
// Instantiate the class
$cool_plugin = new MyCoolPlugin();

Register my widget:

class CoolWidget extends WP_Widget {
  function CoolWidget() {
    // Instantiate the parent object
    parent::__construct( false, 'Cool Widget' );
  }
}

Then I can add the HTML from the shorcode_widget method of MyCoolClass like so:

class CoolWidget extends WP_Widget {
  function CoolWidget() {
    // Instantiate the parent object
    parent::__construct( false, 'Cool Widget' );
  }
  function widget($args, $instance) {
    // reuse my plugin's code
    global $cool_plugin;
    echo $cool_plugin->shortcode_widget();
  }
}

Nice. Saves me writing a bunch of code multiple times, which I guess is the main point of OOP!

JavaScript: how to select the first word(s) in a sentence

Recently I had to figure out a way to select the first 2 words in a sentence using JavaScript. I wanted to wrap them in a class so that I could give them some additional CSS styling. I figured it’d be mad easy, but it took a little bit of head scratching until I figured out at least one way to do it.

I’ve got an HTML element with an ID of ‘niceText’ that I’m looking to grab. I’ll save the string as a variable called ‘niceText’.

var niceText = $('#niceText').text();

I’ll also save the opening and closing spans I’m going to wrap the text in as variables like so:

var openSpan = '<span class="grey">', closeSpan = '</span>';

Next, we’ll use the native JavaScript split method. This makes an array out of a string – all you have to do is to specify the separator that’ll be used to divide the string. In this case the separator is a blank space, so we can write:

niceText = niceText.split(' ');

Our variable ‘niceText’ is now an array of strings (go ahead and use your console to take a peek at what’s happened to our variable).

Next we’ll add the span to the start of the array using the unshift method. It you’ve ever used the push method, this is very similar except that it adds elements to the beginning of the array instead of to the end.

niceText.unshift( openSpan );

Fab. We now need to add the closing span to the array. We can do this with the splice method. If you’re not sure how this method works, do have a good read of the docs as it can come in super handy when performing array surgery!

As I want to wrap the first 2 words in my sentence, I’m going to add the closing span as the 4th item in the array. The first item is now my opening span, then comes the two opening words, then my closing span. The second value in splice indicates how many values, if any, to remove from the array. We’re not removing any, just adding, so this will be equal to 0.

niceText.splice( 3, 0, closeSpan );

Next I’ll turn the array back into a string using join. Like split, join accepts a value for the separator, only this time, the separator is what will be printed between every array item. As this is just a sentence, we want to add a space between the words, so we can write:

niceText = niceText.join(' ');

Finally I’ll add the string to my HTML element like so:

$('#niceText').html( niceText );

That’s it! Here’s the whole function.

jQuery( function($){

   /* Get the text of the element I'm after */
   var niceText = $('#niceText').text(),
      openSpan = '<span class="grey">', closeSpan = '</span>';

   /* Make the sentence into an array */
   niceText = niceText.split(' ');

   /* Add span to the beginning of the array */
   niceText.unshift( openSpan );

   /* Add  as the 4th value in the array */
   niceText.splice( 3, 0, closeSpan );					

   /* Turn it back into a string */
   niceText = niceText.join(' ');					

   /* Append the new HTML to the header */
   $('#niceText').html( niceText );

});

If you’re not already using jQuery in your site, it might be a bit much to add it for just this tiny function! Rather, you can simply replace

var niceText = $('#niceText').text();

with

var niceText = document.getElementById('niceText').textContent;

and

$('#niceText').html( niceText );

with

document.getElementById('niceText').innerHTML = niceText;

Grand stuff. Hope it comes in useful!

How to split your WordPress posts into two columns

The other day, whilst merrily making a website for an ensemble called Tesserae, I needed to figure out how to display my posts in 2 columns, side by side. In this case, the posts were a custom post type biographies that I used to display the various members biographies on the site.

It wasn’t hard to do, here’s the code I used to display half of the posts:

<?php // Get the number of posts in the custom post type 'biographies'
$count = wp_count_posts( 'biographies' ); ?>

Let’s say the total number of posts is 7.

<?php // Divide the number of published posts by 2 and round up in case we get a fraction
$num_biogs = ceil( $count->publish / 2 ); ?>

This would give us 4. We must round up this number otherwise, we’d get 3.5 and that’s no good!

<?php // Now use this number for the showposts parameter in our query
$biogs = new WP_Query( 'post_type=biographies&showposts=' . $num_biogs );
while ( $biogs->have_posts() ) : $biogs->the_post();
// the_title(); the_content(); etc
endwhile; wp_reset_query(); ?>

And the remaining posts:

<?php // Now use the variable $num_biogs as the offset parameter in another query
$biogs = new WP_Query( 'post_type=biographies&showposts=-1&offset=' . $num_biogs );
while ( $biogs->have_posts() ) : $biogs->the_post();
// the_title(); the_content(); etc
endwhile; wp_reset_query(); ?>

Obviously this is only the PHP, and you’re going to need some HTML there to actually use this! I just floated a couple of <div>s side by side, then popped the first block of code inside the left-hand <div> and the 2nd chunk in the 2nd <div>.

You can see the finished product at http://tesserae-la.com/who/

jQuery mobile events firing multiple times and what to do about it

I’m currently working on my very first iPhone app. I decided I’d build it in HTML5, CSS3, JavaScript and wrap it up all cosy and warm with the amazing PhoneGap. I also decided early on to use jQuery mobile as my framework for the project, because I’m so familiar with jQuery itself. It’s been quite a ride so far and I’ve learnt a LOT!

I soon found out that dynamic content and jQuery mobile is not the easiest of pairings, but I think I’ve found a good solution to the most common problems I encountered and figured it’d be cool to share them with whomsoever might have a use for them.

One of the issues I found with my code early on was that on subsequent visits to a page, events would be fired an increasing number of times. What was happening was that I was binding events to the pagebeforeshow event – I though I had to this, because most of the content I was adding to the page was dynamic and would be updated on subsequent page visits. I did this:

$('#my-page').bind('pagebeforeshow', function(){
  // Add dynamic stuff to the page here, then...
  $('input').bind('change', function(){
    // Do something when this happens
  });
});

This worked for the dynamic content, although I still had to remove my inserted content on pagehide as jQuery mobile saves the page in memory, which drove me to the brink of madness on more than one occasion, but hey. On change, the input event was duly triggered on my first visit to the page (and only once, as I expected), but on my second visit to the page, the event was triggered twice, then 3 times etc. Eek!

The solution was not difficult, it just took a while to figure out. I still added my dynamic stuff to the page using the pagebeforeshow event, but I just added the event listener for my input to pageinit instead. As most of the event listeners were bound to elements that were inserted dynamically, I had to use live instead of bind. In the end my code looks something like this:

$('#my-page').bind('pagebeforeshow', function(){
  // Add dynamic stuff to the page here
}).bind('pageinit', function(){
  $('input').live('change', function(){
    // Do something when this happens
  });
});

That solved it. I might detail how I add and remove dynamic content to the page using pagebeforeshow and pagehide. If it might be of use to anyone, do let me know if so!