4

Particleground: a jQuery plugin for background particle systems

Lately I’ve noticed a few sites using JavaScript particle systems as animated backgrounds. I was curious about the technique so I created Particleground, a jQuery plugin that creates a similar effect.

particleground

The particle system can be fine tuned using several configuration options, including a parallax effect which is controlled by the mouse on desktop computers or the gyroscope on smart devices. Particleground works in any browser that supports HTML5 canvas.

See a demo

Download

View on Github

0

The Web Designer’s Bookshelf

I have just launched a new personal project called The Web Designer’s Bookshelf, which is a curated archive of articles about web and interface design.

wdb-header

Here’s the blurb:

As an industry we are obsessed with technical implementation. We write endlessly about front-end processes or the latest CSS and JavaScript techniques, but by focussing so much of our attention on technical concerns we have squeezed design issues out of the conversation.

The Web Designer’s Bookshelf is my attempt to rectify this imbalance. The site is an archive of articles that examine the history and craft of web and interface design, and related design disciplines, in a critical and thought provoking fashion.

Unlike technical articles, which date quickly, writing about design principles tends to have a longer shelf life. My hope is that the articles collected here will be of lasting interest to designers of all persuasions, and contribute to an ongoing conversation about the interactive design discipline.

Visit The Web Designer’s Bookshelf website, subscribe to the newsletter or follow @webdesbookshelf on Twitter.

0

A super minimal functions.php file

In my last post I talked about strategies to organize your WordPress theme’s functions.php file by following object-oriented programming principles. If you prefer to stick with a procedural coding style, here is a simple way to keep your functions.php file lean and mean.

Simply save each hooked function in a separate file, then use PHP includes to import them into functions.php:

require_once('includes/custom_excerpt_length.php');
require_once('includes/another_function.php');
require_once('includes/a_third_function.php');
// etc.

It doesn’t get much more minimal than that!

In this example our custom_excerpt_length.php file might look like this:

function custom_excerpt_length () {
  return 10;
}
add_filter('excerpt_length', 'custom_excerpt_length');
0

Organize your WordPress functions.php file

WordPress tutorials will often advise you to copy and paste code snippets directly into your theme’s functions.php file. That might seem harmless enough, but if you keep adding functionality in an arbitrary fashion your code can quickly become unmanageable. In this post I will share some strategies for keeping your functions.php file tidy and making it easier to maintain.

Keep the global space clean

One problem with the typical functions.php file – and, it could be argued, with WordPress generally – is that variables and functions are declared in the global scope. That means you risk naming conflicts with functions and variables declared elsewhere in your own code, in plugins, or in the WordPress core.

As an example, suppose you create a function named get_post_slug in functions.php. Now let’s imagine that in the future a function with the same name is introduced to the WordPress core. Your function declaration will now throw a fatal error:

Fatal error: Cannot redeclare get_post_slug()

To avoid naming collisions you could prefix your function names to make them unique – for example yourthemename_get_post_slug – but a more robust approach is to encapsulate your theme’s logic in a class.

A typical hooked function looks like this:

function custom_excerpt_length () {
  return 100;
}

add_filter('excerpt_length', 'custom_excerpt_length');

Here is that same functionality encapsulated in a class:

class YourThemeName {
  function __construct() {
    add_filter('excerpt_length', array($this, 'custom_excerpt_length'));
  }

  function custom_excerpt_length () {
    return 100;
  }
}

$yourthemename = new YourThemeName();

Because the custom_excerpt_length function is a class method it no longer has global scope, and the $yourthemename variable ensures that our theme’s logic has a single point of access. (Note: You should change YourThemeName and $yourthemename to something unique to your theme.)

You might have noticed that the second parameter passed to add_filter is an array, with $this as the first value. This tells WordPress to use a class method as a callback. You can read more about the different types of callbacks in the add_filter documentation.

Theme setup

Most themes have some setup code that needs to run straight away. Let’s add an init method to our class to handle this job:

class YourThemeName {
  function __construct() {
    add_action('after_setup_theme', array($this, 'init'));
    // Register action/filter callbacks here...
  }

  function init() {
    // All theme initialization code goes here...
    register_nav_menus(
      array(
        'header-menu' => __('Header Menu', 'yourthemename')
      )
    );
  }

  // Action/filter callbacks go here...
}

$yourthemename = new YourThemeName();

Any functionality you want hooked to the after_setup_theme action can go in the init method. In the example above we registered a navigation menu.

Utility methods

In addition to WordPress action/filter hooks your theme class can also provide utility methods, which can be accessed from templates.

Here is a simple utility method to get the ID of a category by supplying its name:

function get_category_id ($cat_name) {
  $term = get_term_by('name', $cat_name, 'category');
  return $term->term_id;
}

If you include that method in your theme’s class you can now access it from a template like so:

$yourthemename->get_category_id('category-name');

Group your functions by type

Rather than arranging callback function in a haphazard fashion, grouping them by type makes them easier to find.

As we saw earlier all of your theme’s filter/action callbacks are registered in the class constructor, and all setup logic is placed within the init method. I also like to group all my action callback functions together, my filter callback functions together and my utility methods together.

class YourThemeName {
  function __construct() {
    add_action('after_setup_theme', array($this, 'init'));
    // Register action/filter callbacks here...
  }

  function init() {
    // Theme setup code goes here...
  }

  // Action callbacks go here...

  // Filter callbacks go here...

  // Utility methods go here...
}

Comment your code

It might go without saying, but well written comments make your code easier to read and comprehend. Well structured comments can go a long way toward organizing your functions.php file.

/**
 * Get the category id from a category name
 *
 * @param string $cat_name The category name
 * @return int The category ID
 */
function get_category_id ($cat_name) {
  $term = get_term_by('name', $cat_name, 'category');
  return $term->term_id;
}

Use a plugin for site-specific functionality

While it may be tempting to dump all your site’s custom functions into your functions.php file, it is good practice to encapsulate site-specific logic in a separate functionality plugin. In addition to long term maintenance benefits, this separation of concerns streamlines your functions.php file by offloading some of its functionality to a plugin.

There have been many good articles written about what belongs in a functions.php file and what belongs in a functionality plugin, but I think Curtis McHale sums it up nicely:

The only deciding factor in where you put your code is the life of the functionality. Will you still need to have that portfolio custom post type the next time you redesign your site? If the answer is yes then you should be building a plugin with the code. If the answer is no, then put the code in you theme functions.php.

Example functions.php file

If you employ the strategies I have outlined in this post I hope you will find that your functions.php file is better organized and easier to manage. Here is an example of how the final file might look:

/**
 * YourThemeName
 */
class YourThemeName {
  /**
   * Constructor
   */
  function __construct() {
    // Register action/filter callbacks
    add_action('after_setup_theme', array($this, 'init'));
    add_filter('excerpt_length', array($this, 'custom_excerpt_length'));
  }

  /**
   * Theme setup
   */
  function init() {
    // Register navigation menus
    register_nav_menus(
      array(
        'header-menu' => __('Header Menu', 'yourthemename')
      )
    );
  }

  /**
   * Filter callbacks
   * ----------------
   */

  /**
   * Customize post excerpt length
   *
   * @return int The new excerpt length in words
   */
  function custom_excerpt_length () {
    return 100;
  }

  /**
   * Utility methods
   * ---------------
   */

  /**
   * Get the category id from a category name
   *
   * @param string $cat_name The category name
   * @return int The category ID
   */
  function get_category_id ($cat_name) {
    $term = get_term_by('name', $cat_name, 'category');
    return $term->term_id;
  }
}

// Instantiate theme
$yourthemename = new YourThemeName();
3

Center and crop thumbnails with CSS

Here is a handy CSS centering technique I first noticed in the WordPress media library, where it is used to centre and crop irregularly sized thumbnails within a square container.

cropped-thumbnails

The technique uses CSS3 transforms, so it works in all modern browsers, including IE9 and above.

<div class="thumbnail">
  <img src="landscape-img.jpg" alt="Image" />
</div>
<div class="thumbnail">
  <img src="portrait-img.jpg" class="portrait" alt="Image" />
</div>
.thumbnail {
  position: relative;
  width: 200px;
  height: 200px;
  overflow: hidden;
}
.thumbnail img {
  position: absolute;
  left: 50%;
  top: 50%;
  height: 100%;
  width: auto;
  -webkit-transform: translate(-50%,-50%);
      -ms-transform: translate(-50%,-50%);
          transform: translate(-50%,-50%);
}
.thumbnail img.portrait {
  width: 100%;
  height: auto;
}

The technique works by positioning the image so that its top left corner is in the centre of its container. Then, a 2D translation moves it up and left by half its own width.

The key here is that the percentage values passed to the translate function are relative to the element, not its container, as would be the case if we were to manipulate the element’s top and left properties instead.

View a demo

Note that the portrait format image has the class portrait, so that we can correctly scale it to fill its container.

So there you go. A really simple CSS technique for centering and cropping thumbnails.

18

Paginating an Advanced Custom Fields Repeater

Hands down my favourite WordPress plugin is Elliot Condon’s Advanced Custom Fields, and it’s made even more powerful by the Repeater Field add-on. But a Repeater can get unwieldy when it contains a large number of items, and you might find yourself wanting to paginate the results when you display them to the user. Here’s a technique for doing that.

In this example we will paginate a Repeater image gallery mapped to a custom field named image_gallery with a sub field named image which contains an image object. Our Repeater will be displayed on a page at the URL /gallery.

10 images will be displayed per page, and pagination links will allow the user to navigate between the gallery’s pages at pretty URLS such as /gallery/2/, /gallery/3/ and so on.

Continue reading

3

WordPress custom fields not saving? PHP’s max_input_vars may be to blame.

On two occasions recently I have run into a problem where WordPress custom fields were disappearing after a post was edited. The first time I noticed this odd behaviour was on a site using the Advanced Custom Fields Repeater add-on for an image gallery. Each gallery item contained an image field along with several meta data fields, and once the gallery grew significantly large new items stopped being created. All of the existing gallery items would save successfully, but newly created fields would disappear when the post was updated.

The second time I encountered disappearing data was on a WooCommerce installation using the Per Product Shipping module. This module requires shipping costs to be entered individually for each country (why, WHY?) and as a consequence each product had a large number of custom fields. Surprisingly it wasn’t the shipping costs that were disappearing, but the product attributes – size, colour and so forth. This had disastrous effects, since when the attributes disappeared the linked product variations were removed too, along with the product prices.

In both cases data would only disappear on the production web server. When I worked on the sites locally custom fields would save as expected, so I was fairly certain that the server configuration was to blame. No errors were being displayed within WordPress or in my server logs so I initially focussed on MySQL, since the bug seemed to stem from a failure to write to the WordPress database. That line of enquiry proved fruitless, but thankfully I came across a thread on the Advanced Custom Fields forum which mentioned PHP’s max_input_vars setting as a potential culprit.

max_input_vars was introduced in PHP 5.3.9, and limits the number of $_POST, $_GET or $_COOKIE input variables that PHP will accept. Further variables are truncated from the request. The default value for max_input_vars is 1000, which means that if your form has has more than 1000 inputs, any additional values will be lost. Since each custom field is an input in the WordPress editor, plugins like Advanced Custom Fields Repeater and Per-Product Shipping make it possible to exceed the 1000 input limit.

You can increase max_input_vars in your php.ini file:

max_input_vars = 3000

or in an .htaccess document:

php_value max_input_vars 3000

After doing that you should find that you can once again save a large number of custom fields.

51

Automated git deployments from Bitbucket

Git may not have been designed as a deployment tool, but for small projects it can do the job quite nicely. What makes Git deployments attractive is how frictionless the process is: make some changes to your project, merge them into your production branch, push the commit to a remote repository and like magic the changes are live! Git knows which files need to be changed or deleted, so you don’t have to think about it. If you’re already using git to version control your project then you probably won’t even need to modify your existing workflow, once the initial setup is done.

I use Bitbucket for hosting my private repositories, and have recently implemented a deployment process that integrates with Bitbucket’s POST hooks feature. There are basically three things you need to do to make this work:

  • Set up SSH keys so your server can talk to Bitbucket
  • Clone your Bitbucket repository on your web server
  • Setup a hook on Bitbucket and an associated deployment script on your server

Here’s what your deployment workflow will look like once we’re done:

  • Develop your website locally
  • When you’re ready to deploy, commit your changes and push them to Bitbucket
  • When Bitbucket receives the commit it will notify a deployment script on your server
  • The deployment script will fetch the changes into a cloned repository on your server, and checkout files to your public web directory

Continue reading

4

The true cost of H&FJ’s web font platform

Chris Bowler from the Campaign Monitor team has written an interesting comparison between Typekit and Hoefler and Frere-Jones’ new cloud.typography web font service. If you’ve been sizing up clouds.typography, or didn’t know that H&FJ has (finally) launched their much anticipated web font platform, go read his post.

hjf-clouds-578w

One thing that Chris didn’t touch on, but I think is relevant to the comparison, is that H&FJ’s annual subscription fees don’t actually give you access to their full range of fonts, just five font families:

Join Cloud.typography and get your first five webfont packages FREE

If you want access to more than five families then any additional fonts need to be purchased separately – currently H&FJ’s popular Gotham family costs $149 for a web font license, or $299 for a web and desktop license.

Continue reading

72

TweetPHP: Display tweets on your website using PHP

If you’ve ever wanted to display your latest Twitter tweets on a website, TweetPHP lets you do that using PHP. TweetPHP is a rewrite of my old Twitter RSS feed parser, which stopped working when Twitter phased out their v1 API.

Features

  • Works with Twitter API v1.1
  • Tweets are cached to avoid exceeding Twitter’s API request rate limits
  • A fallback is provided in case the twitter feed fails to load
  • Retweets and @replies can be optionally ignored
  • A configuration parameter allows you to specify how many tweets are displayed
  • Dates can optionally be displayed in “Twitter style”, e.g. “12 minutes ago”
  • You can customize the HTML that wraps your tweets, tweet status and meta information

Download

TweetPHP is available on Github

Usage

To interact with Twitter’s API you will need to create an API KEY, which you can create at: https://dev.twitter.com/apps

After creating your API Key you will need to take note of following values: “Consumer key”, “Consumer secret”, “Access token”, “Access token secret”

Those values can be passed as options to the class constructor, along with the Twitter screen name you wish to query:

require_once('TweetPHP.php');

$TweetPHP = new TweetPHP(array(
  'consumer_key'              => 'xxxxxxxxxxxxxxxxxxxxx',
  'consumer_secret'           => 'xxxxxxxxxxxxxxxxxxxxx',
  'access_token'              => 'xxxxxxxxxxxxxxxxxxxxx',
  'access_token_secret'       => 'xxxxxxxxxxxxxxxxxxxxx',
  'twitter_screen_name'       => 'yourusername'
));

Then you can display the results like so:

echo $TweetPHP->get_tweet_list();

Options

Options can be overridden by passing an array of key/value pairs to the class constructor. At a minimum you must set the consumer_key, consumer_secret, access_token, access_token_secret and twitter_screen_name options, as shown above.

Here is a full list of options, and their default values:

'consumer_key'          => '',
'consumer_secret'       => '',
'access_token'          => '',
'access_token_secret'   => '',
'twitter_screen_name'   => '',
'cache_file'            => dirname(__FILE__) . '/cache/twitter.txt', // Where on the server to save the cached formatted tweets
'cache_file_raw'        => dirname(__FILE__) . '/cache/twitter-array.txt', // Where on the server to save the cached raw tweets
'cachetime'             => 60 * 60, // Seconds to cache feed (1 hour).
'tweets_to_display'     => 10, // How many tweets to fetch
'ignore_replies'        => true, // Ignore @replies
'ignore_retweets'       => true, // Ignore retweets
'twitter_style_dates'   => false, // Use twitter style dates e.g. 2 hours ago
'twitter_date_text'     => array('seconds', 'minutes', 'about', 'hour', 'ago'),
'date_format'           => '%I:%M %p %b %d%O', // The defult date format e.g. 12:08 PM Jun 12th. See: http://php.net/manual/en/function.strftime.php
'date_lang'             => null, // Language for date e.g. 'fr_FR'. See: http://php.net/manual/en/function.setlocale.php
'format'                => 'html', // Can be 'html' or 'array'
'twitter_wrap_open'     => '<h2>Latest tweets</h2><ul id="twitter">',
'twitter_wrap_close'    => '</ul>',
'tweet_wrap_open'       => '<li><span class="status">',
'meta_wrap_open'        => '</span><span class="meta"> ',
'meta_wrap_close'       => '</span>',
'tweet_wrap_close'      => '</li>',
'error_message'         => 'Oops, our twitter feed is unavailable right now.',
'error_link_text'       => 'Follow us on Twitter',
'debug'                 => false

Caching

Caching is employed because Twitter rate limits how many times their feeds can be accessed per hour.

When the user timeline is first loaded, the resultant HTML list is saved as a text file on your web server. The default location for this file is: cache/twitter.txt

You can change this file path by setting the cache_file option. For example, to set a path from your root public directory try:

$_SERVER['DOCUMENT_ROOT'] . '/path/to/my/cache/dir/filename.txt'

Debugging

If you are experiencing problems using the plugin please set the debug option to true. This will set PHP’s error reporting level to E_ALL, and will also display a debugging report.

Here are a few tips to help you solve common configuration issues:

tmhOAuth response code: 0

If your debugging report shows the error “tmhOAuth response code: 0″, you can find out more about this error message in the tmhOAuth github README. Dario also offers this solution: “My server didn’t like the the two __DIR__ constants in the tmhOAuth.php file, hard-coded them and it all works now.”

unserialize error

If you receive the PHP warning “[function.unserialize]: Error at offset 0 of 49 bytes”, it might be the case that you have magic quotes enabled in your PHP configuration.

Credits

– Feed parsing uses Matt Harris’ tmhOAuth
– Hashtag/username parsing uses Mike Cochrane’s twitter-text-php