Unit test WordPress plugins like a ninja (in progress)

Unit testing a plugin can be easy, but if the plugin needs dashboard configuration or has dependencies on other plugins, it can quickly go off the tracks. And if you haven’t setup Travis integration, you’re missing out. Activate Travis CI To start with, go sign in to Travis now and activate your repos for testing. If you’re […] » about 300 words

How to identify context inside the WordPress dashboard

On wp-hackers, Haluk Karamete asked:

on admin pages, how can I detect that the current admin is dealing with a cpt?

Andrew Nacin answered:


[But] this will also specify a post type when it’s a taxonomy being edited. To filter that out, ensure that get_current_screen()->base == 'post', which is [true] for edit.php, post-new.php, and post.php (for all post types).

Haluk didn’t elaborate on the cause of the question, but the answer is very good advice for those seeking to conditionally enqueue JS and styles only for specific post types.

Detect MySQL’s “too many connections” error

WordPress appears to continue with execution even when MySQL refuses connections/queries after init. Here’s a comment in the MySQL docs suggesting how to detect the condition in raw PHP:

$link = mysql_connect("localhost", "mysql_user", "mysql_password");
if (mysql_errno() == 1203) {
  // 1203 == ER_TOO_MANY_USER_CONNECTIONS (mysqld_error.h)
  header("Location: http://your.site.com/alternate_page.php");

Just a note to myself, but I wonder if there’s opportunity here.

Speeding up MySQL joins on tables with TEXT columns, maybe

The thing about WordPress’ DB schema is that TEXT and VARCHAR content is mixed in the posts table (to say nothing of the frustrations of DATETIME columns). That’s not such a problem for a blog with a few hundred posts, but it’s a different matter when you have a few hundred thousand posts. And it wouldn’t even […] » about 500 words

Testing apply_filters() times

Testing how long it takes to assign a variable versus assigning through WordPress’ apply_filters(). Filters are core to WordPress, but I haven’t yet looked at the total number of apply_filters() calls used throughout the code. The answer to this question is that calling a non-existing filter before assignment is about 21 times more costly than […] » about 300 words

On wp_enqueue_scripts and admin_enqueue_scripts

An argument has erupted over the WordPress actions wp_enqueue_scripts and admin_enqueue_scripts vs. init. One of the points was about specificity, and how wp_enqueue_scripts and admin_enqueue_scripts can reduce ambiguity. I didn’t realize I had strong opinions on it until the issue was pressed, but it turns out I think wp_enqueue_scripts and admin_enqueue_scripts are unnecessary and unfortunate additions […] » about 300 words

Happy New Scriblio!

The most recently released, stable version of Scriblio is marked 2.9-r1 and was last updated in June 2010. You can be forgiven for thinking development had ceased in the interim. Today, however, I’m proud to introduce a completely new Scriblio, re-written from the ground up to take advantage of the latest features of WordPress and eliminate the mistakes […] » about 600 words

How WordPress Taxonomy Query URLs Could Be More Awesomer

(Updated, see below) WordPress 3.1 introduced some awesome new taxonomy query features, and the URL parsing allows some rudimentary syntax to query multiple terms and choose if the query is OR’d or AND’d. The URL syntax is as follows: A comma (,) between terms will return posts containing either term (logical OR), like this http://maisonbisson.com/post/tag/wordpress,mysql/ . A […] » about 300 words

Sara Cannon On Responsive Web Design At WCSF

Sara Cannon‘s talk on responsive web design (resizing the page to suit different client devices) was spot on. Her slides are below, but she also recommends this A List Apart article on the matter, as well as Less Framework and 1140 CSS Grid (especially as alternatives to 960.gs).

WordPress nocache_headers() vs. Nginx

Typically, you can call WordPress’ nocache_headers() function when you don’t want content to be cached. Typically, but when you’re serving from behind Nginx as a reverse proxy, consideration must be paid.

It’s a year old now, so I shouldn’t have been surprised by it, but this thread on the Nginx forums explains that Cache-Control: private headers are meaningless when Nginx is being used as a reverse proxy:

nginx completely ignores the ‘private’ keyword and will cache your document regardless.

The recommendation is for the upstream app to send an X-Accel-Expires: 0 header.

The easy fix? Add a filter to nocache_headers() that inserts the additional header:

add_action( 'nocache_headers' , 'my_nocache_headers' , 1 );
function my_nocache_headers( $headers )
	$headers['X-Accel-Expires'] = 0;
	return $headers;

WordPress comments_template() and wp_list_comments() Performance

This thread on memory usage while executing WordPress’s comments_template() raised my awareness of performance issues related to displaying comments on posts in WordPress. The first thing to know is that all the comments on a given post are loaded into memory, even if the comments are paged and only a subset will be displayed. Then comments_template() calls update_comment_cache(), […] » about 500 words

WordPress MU/MS Empty Header and Broken Image Bug Fixed

I just switched to a new server and found myself struggling with empty HTTP headers and broken or partial images. The problem is the memcache extension for PHP and WordPress MU/WordPress multisite’s need to reinstantiate the wp-cache after determining the correct blog for a given request.

Versions of the memcache extension prior to 3.0 go wrong somehow and it shows up when you try to do an HTTP HEAD request on a page (the result is empty) or enable X-SendFile support for WP MU/MS’ file handling (all the files and images in the media library will break). Upgrading to the the 3.x version (in beta since 2007) fixes the problem.

You may have to uninstall the old version before installing the beta, and installing the beta via PECL requires adding “-beta” to the package name. Here are the commands:

pecl uninstall memcache
pecl install memcache-beta

Improving Will Norris’ Open Graph Plugin

Will Norris put together a nice WordPress plugin to place Open Graph metadata on the page. Today I patched it to address a few bugs I and others have found.

The patch switches functions that depended on globalizing $post to use $wp_query->queried_object and similar.

opengraph_default_url() is changed to try get_permalink() only when is_singlular() is true. Otherwise it uses the blog’s base URL. This isn’t perfect, but it’s better than having the front page and all tag/category/archive pages report their og:url as being the permalink for the first post on the page.

As suggested here, I changed the opengraph_default_description() to use the post’s excerpt if is_singular() and the post includes an excerpt.

I changed opengraph_default_image() to test if the theme supports post thumbnails before calling has_post_thumbnail() to avoid the Fatal error: Call to undefined function has_post_thumbnail() errors.

I submitted it as a bug report in the plugins Trac, but I don’t check there for tickets on my own plugins, so you might apply the patch yourself.

Speed WordPress MultiSite With X-Sendfile For Apache

Like WordPress MU before, MultiSite implementations of WordPress 3.0 use a script to handle image and other attachment downloads. That script checks permissions and maps the request path to the files path on disk, then reads the file out to the web server, which sends it to the browser. That approach has some inefficiencies, and […] » about 400 words

Migrating From WordPress MU To WordPress 3.0 Multi Site

I’ve been running a few instances of WordPress MU for a while now, so I was more than a little anxious about the merge of the MU functionality into the core of WordPress. It’s a good thing, but sometimes such dramatic changes pose rocky challenges.

Not so in this case.

Pete Mall blogged about it in May, and I’m happy to say that I followed those instructions (summary: upgrade, it will work) to upgrade both this site and Scriblio.net recently. The biggest challenge I faced was in migrating my SVN checkout (not discussed in Pete’s post, but people who install via FTP or use the auto upgrader don’t need to worry about this), and Pete noted the only gotcha that I might have encountered: changing the .htaccess to use a different file that had been used in WPMU.

I tested the migration on this site, and it rocked so much that I decided to go forward with upgrading the other site, even though WP3.0 hasn’t been formally released yet. Rock n roll.

Cleaning Up Category Relationships In A WordPress Scriblio Site

A few lines of SQL I used to clean up a Scriblio site. It’s probably useless to anybody but me. I’m not suggesting anybody else use this code, as it will result in changed or deleted data.

Update the post author for catalog records (identified because they have a specific post meta entry):

UPDATE wp_8_postmeta
JOIN wp_8_posts ON wp_8_posts.ID = wp_8_postmeta.post_id
SET post_author = 15
WHERE meta_key = 'scrib_meditor_content'

Get the categories attached to every catalog record (except the “catalog” category):

SELECT tr.object_id , tr.term_taxonomy_id
FROM wp_8_term_relationships tr
JOIN wp_8_posts p ON p.ID = tr.object_id
WHERE tr.term_taxonomy_id IN (
	SELECT term_taxonomy_id
	FROM wp_8_term_taxonomy
	WHERE taxonomy = "category"
	AND term_id != 30
AND post_author = 15
ORDER BY tr.object_id , tr.term_taxonomy_id

Using the above list of object ids and term taxonomy ids, build a series of queries like the following to delete them:

DELETE FROM wp_8_term_relationships WHERE object_id = 12275 AND term_taxonomy_id = 271872 ;

Insert a catalog category relationship for all catalog records:

INSERT INTO wp_8_term_relationships
SELECT p.ID , '271871' , '0'
FROM wp_8_posts p
LEFT JOIN wp_8_term_relationships tr ON p.ID = tr.object_id AND tr.term_taxonomy_id = 271871
WHERE post_author = 15
AND tr.term_taxonomy_id IS NULL