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!

A suggested fix for the dreaded FOUT

As a keen typography fan I tend to rely heavily on the use of web fonts for my sites. I generally use Typekit to deliver my fonts, but it does tend to take a little while for the browser to download and display my beautiful fonts.

I noticed that if I simply place the typkit required script tags in the header of my site, it will block my site from loading until the font(s) have been downloaded, leaving visitors with a blank screen for a second or so. With a fast connection it’s not the end of the world in my book, but recently I tried experimenting a little with how to minimize this inconvenience to the user.

First, I tried putting the typekit script tags in the footer of my document, instead of the header. This stopped the delay in the site from loading, but it also caused a ‘Flash of Un-styled Text’ (or FOUT for short), where the fallback font(s) were shown as the web fonts were being downloaded. This can look really messy, especially if you’re using fonts for which there isn’t really any suitable fallback.

It’s a common problem and I’ve seen a couple of solutions offered, but I came up with what I think is quite an elegant solution.

Typekit fonts are delivered via JavaScript that provide event listeners that can tell you whether a font is active, is loading, is inactive or has been loaded. Typekit suggest a solution on their blog at http://blog.typekit.com/2010/10/29/font-events-controlling-the-fout/, but the loading of your site can still be delayed as you wait for the fonts to download and if you put the script tags in your footer, you can still suffer the FOUT. Blurgh.

My solution is to (and bear with me here before you scream ‘but what if JavaScript is disabled!’) hide all the text elements in my CSS by setting their opacity to 0, so as to completely avoid any FOUT. I do this like so:

h1, h2, h3, h4, h5, h6, p, ul, ol, dl, span, a {
opacity: 0;
-webkit-transition: opacity 0.4s ease-in;
-moz-transition: opacity 0.4s ease-in;
-o-transition: opacity 0.4s ease-in;
transition: opacity 0.4s ease-in;
}

Obviously you may well have more elements of text that should be hidden, such as blockquotes, cites etc. I’ve also added some CSS3 transitions, so that when the web fonts have finished loading they’ll fade in smoothly (this in itself is really quite a nice effect) rather than just being spat out! I then added the following to my CSS:

.wf-active h1, .wf-active h2, .wf-active h3, .wf-active h4, .wf-active h5, .wf-active h6, .wf-active p, .wf-active ul, .wf-active ol, .wf-active dl, .wf-active span, .wf-active a {
opacity: 1;
}

The .wf-active class is added to the <html> tag of my document via JavaScript when the font has finished loading. If we set the opacity here to 1 then our web fonts will be displayed and not our fallback fonts.

The problem with this method is obviously that it relies on JavaScript. If users view the site with JavaScript disabled, the wf-active class won’t be added to the <html> tag and the fonts will remain invisible. My solutions is to add the following to my document head after our other CSS files have been included.

<noscript><style>h1, h2, h3, h4, h5, h6, p, ul, ol, dl, span, a {
opacity: 1;
} </style></noscript>

This will overwrite our previous declaration where we set the opacity to 0 and therefore make our fallback fonts visible to the user without JavaScript.

The other problem with this method if the Typekit fonts are not available, or if the browser does not support web fonts. In this case, you could also use the .wf-inactive class which Typekit adds to the <html> tag in either of these cases and set the opacity to 1 like so:

.wf-inactive h1, .wf-inactive h2, .wf-inactive h3, .wf-inactive h4, .wf-inactive h5, .wf-inactive h6, .wf-inactive p, .wf-inactive ul, .wf-inactive ol, .wf-inactive dl, .wf-inactive span, .wf-inactive a {
opacity: 1;
}

As far as I can see this pretty much covers all bases, but I may well have missed something here and am very happy to have this pointed out to me!

Easy PayPal Custom Fields Plugin

I’ve just my first WordPress plugin that uses custom fields to make creating a PayPal button super-easy.

I wanted to learn more about PHP and the inner workings of WordPress and I also needed a solution for my clients to add PayPal functionality to their sites without having to remember complicated shortcode syntax. Whilst shortcodes in WP are a fantastic feature and are easy to implement for the developer, I find they can often confuse my clients who often can’t even find square brackets on their keyboards!

Having said that: In order to have full flexibility on the placement of this mystical button, you can select to insert it at the top or bottom of a post or – via a shortcode – anywhere you like in the post.

On the settings screen, the user can select on which type of post (including custom post types) the plugin should be displayed. It’s also possible to enter default settings which can subsequently be changed for individual posts where necessary – this might come in for sites with multiple users.

The button is also customizable with 2 themes to choose between (dark and light) with custom text for the button, or it’s possible to simply display a regular large or small PayPal button (either ‘Buy Now’ or ‘Donate’).

The plugin will encrypt your PayPal username so that it can’t be harvested for spam by the evil spam robots of Mordor.

This plugin is created for WordPress 3.x and currently only supports ‘Buy Now’ and ‘Dontate’ functionality. Download it via the WordPress plugin repository.

Please don’t forget to rate the plugin if you like it and if you feel generous enough to lend a few shillings towards further development I would be most grateful.

Update: I’ve managed to fix an issue where WordPress would suddenly remove the PayPal info attached to the post and the button would disappear. I’ve updated the repository with the fixed version – if you’re using an older version I strongly recommend that you update as soon as possible!

Screenshots:

The Options Page


Adding the button to a new post:


WordPress 3.0 custom queries, post types and taxonomies

There’s been a few really great articles recently published about the new custom posts features in the WordPress 3 Beta, most notably Justin Tadlock’s excellent article and an equally enlightening post on wpengineer.com. I’ve had some fun experimenting a little with the new possibilities opened up to me with this new functionality but I very quickly came up with a problem that took quite a bit of head scratching to solve, namely how to filter my query to a custom post type by taxonomy – akin to displaying all the blog posts within a specific category, I wanted to be able to display all my custom posts in my custom taxonomy (read category).

Using code grabbed from the above articles and the codex I had successfully created a new custom post type. Here’s the code for your functions.php file. As per the codex example, let’s call it ‘books’.

function new_post_type() {
register_post_type( 'books',
array(
'labels' => array(
'name' => __( 'Books' ),
'singular_name' => __( 'Book' )
),
'public' => true,
)
);
}
add_action( 'init', 'new_post_type' );

All of this functionality is clearly explained in either of the articles I mentioned (as well as a more detailed discussion of the various options – the purpose of this article is just to demonstrate how to perform a custom query on a new custom post type with a custom taxonomy.

Right, now I can retrieve my new post type by passing the following parameter to the query. This code should be placed outside of the loop (it’s a loop itself!) in whichever page you’d like it to appear.

<?php
$yell = new WP_Query(array('post_type' => 'books'));
while ($yell->have_posts()) : $yell->the_post();
?>

<h2><?php the_title(); ?></h2>

<?php the_content(); ?>

<?php endwhile; wp_reset_query(); ?>

Now, I want to add a custom taxonomy to my custom post type: I want to do is to be able to categorize books by genre. I can do this by adding the following code to my functions.php file:

function create_book_taxonomies() {
// Add new taxonomy, make it hierarchical (like categories)
$labels = array(
'name' => _x( 'Genres', 'taxonomy general name' ),
'singular_name' => _x( 'Genre', 'taxonomy singular name' ),
'search_items' => __( 'Search Genres' ),
'popular_items' => __( 'Popular Genres' ),
'all_items' => __( 'All Genres' ),
'parent_item' => __( 'Parent Genres' ),
'parent_item_colon' => __( 'Parent Genre' ),
'edit_item' => __( 'Edit Genre' ),
'update_item' => __( 'Update Genre' ),
'add_new_item' => __( 'Add New Genre' ),
'new_item_name' => __( 'New Genre Name' ),
);
register_taxonomy('Genres',array('books'), array(
'hierarchical' => true,
'labels' => $labels,
'show_ui' => true,
'query_var' => true,
'rewrite' => array( 'slug' => 'genres' )
));
}
add_action( 'init', 'create_book_taxonomies', 0 );

Awesome – now I can add a new ‘genre’ to my books – this is akin to adding a new category to your posts. Let’s say that I now add 2 genres: ‘sci fi’ and ‘thriller’. I can now filter my query to query one of my newly created genres.

<?php
$yell = new WP_Query(array('post_type' => 'books', 'genres' => 'sci fi'));
while ($yell->have_posts()) : $yell->the_post();
?>

<h2><?php the_title(); ?></h2>

<?php the_content(); ?>

<?php endwhile; wp_reset_query(); ?>

At the moment it seems that you can’t filter the query further (as you can for posts) by adding an equivalent to:

'category__in' => array(2,6)

Namely:

'genres__in' => array(2,5)

Which seems – to me at least – a real missed opportunity (it never made it into the core, I’m told), but there may yet be some crafty plug-in authors with a work-around. Here’s hoping!