Press This Reloaded: Version 1.0

The Press This bookmarklet is neat, but it would be a lot neater if it used the regular post editing screen interface.

It turns out, this was quite easy to do from a plugin. So, this is version 1.0, a proof of concept, if you will. See the overview for more info.

Custom Sortable Columns

This summer I’ve been busy with my GSoC project, which involved making columns sortable on list-type screens in the WordPress administration area. Yesterday, that work was included in trunk, so if you’re on the bleeding edge (3.1-alpha), you should see something like this:

Sortable post columns

That’s all very nice, you say, but how do I make sortable columns of my own? First, let’s make a plain, old, non-sortable column:

// Register the column
function price_column_register( $columns ) {
	$columns['price'] = __( 'Price', 'my-plugin' );
 
	return $columns;
}
add_filter( 'manage_edit-post_columns', 'price_column_register' );

Nothing new here. We’re just using a well-known hook to add a Price column on the posts screen. Then, with another hook, we’re displaying the value, which is stored in a custom field in this case:

// Display the column content
function price_column_display( $column_name, $post_id ) {
	if ( 'price' != $column_name )
		return;
 
	$price = get_post_meta($post_id, 'price', true);
	if ( !$price )
		$price = '<em>' . __( 'undefined', 'my-plugin' ) . '</em>';
 
	echo $price;
}
add_action( 'manage_posts_custom_column', 'price_column_display', 10, 2 );

Now comes the interesting part:

// Register the column as sortable
function price_column_register_sortable( $columns ) {
	$columns['price'] = 'price';
 
	return $columns;
}
add_filter( 'manage_edit-post_sortable_columns', 'price_column_register_sortable' );

We first need to tell WordPress that this is a sortable column. As you can see, the hook name is very similar to the one we used to register the column in the first place. 1

There’s just one more thing we need to do. Since WordPress doesn’t know how to handle ‘orderby=price’, we’ll have to teach it, by altering the query variables:

function price_column_orderby( $vars ) {
	if ( isset( $vars['orderby'] ) && 'price' == $vars['orderby'] ) {
		$vars = array_merge( $vars, array(
			'meta_key' => 'price',
			'orderby' => 'meta_value_num'
		) );
	}
 
	return $vars;
}
add_filter( 'request', 'price_column_orderby' );

We’re basically telling it to order by the ‘price’ custom field we displayed before. 2

And that’s all there is to it. This is how it should look:

Result

Here’s the full code, for convenience: https://gist.github.com/906872

Update: With the CodePress Admin Columns plugin you can manage admin columns through a GUI.

Notes:

  1. The first ‘price’ represents the internal column name, while the second is the value sent to the ?orderby= query variable.
  2. More info on meta_value_num.

Query Multiple Taxonomies: Version 1.3

The latest version of the plugin brings a new ‘dropdowns’ mode to the Taxonomy Drill Down widget. I’ve also added a few filters so you can further customize the appearance, without modifying plugin files. They can be found in query-multiple-taxonomies/widget.php.

new widget interface

Also, a single widget handles multiple taxonomies now. Hovering over a taxonomy will show you the post types it’s associated with.

If you’re currently using an older version, you will have to re-add the widget after upgrading.

On the template side of things, all taxonomy archives (multiple or not), now go to taxonomy.php, instead of multitax.php. Also, is_multitax() now accepts an array of taxonomy names to check against:

if ( is_multitax( array( 'colour', 'shape' ) ) ) {
  // Both the colour and shape taxonomies were queried
}

Last but not least, the plugin has been better integrated with the WP_Query class, fixing a number of bugs in the process. For example, besides query_posts(), you can also use new WP_Query(...) now.

Posts 2 Posts: Version 0.3

There was an interesting discussion on wp-hackers about how best to store many-to-many relationships between posts.

The conclusion was that custom fields are probably the worst solution. While creating a custom table is the most straightforward way to do it, using a custom taxonomy has the most benefits. The most important one is that, when done right, no hand-written SQL is required.

So, this version of the plugin uses a hidden taxonomy to store the connections between posts.

If you were using an older version of the plugin, go to /wp-admin/?migrate_p2p to migrate your connections. You should probably make a database backup beforehand, just in case.

Besides that, the parameter order for p2p_get_connected() and p2p_list_connected() were changed. See all the API changes.

Prevent blog authors from editing comments

By default, a user with the ‘author’ role can edit any comment made on any of his own posts. This is alright when you only have a handful of trusted authors.

In most cases though, you will want to allow authors to only edit their own comments. Here is a little snippet that achieves that (requires WordPress 3.1 or newer):

If you want to prevent authors from editing even their own comments, just remove this line from above:

if ( $comment->user_id != $user_id )

Posts 2 Posts: Version 0.2

You now have the ability to create multiple connections of the same type from the admin. This was the most requested feature and you should thank Patrik Bóna for providing the initial implementation.

the new metabox

The API functions have also changed (and are now documented), so you might want to take another look at them. I’ve also added a new helper function called p2p_list_connected().

Conviction, it turns out, is a luxury of those standing on the sidelines.

A Beautiful Mind

Query Multiple Taxonomies: Version 1.2

Fewer queries

Instead of doing a separate query for each taxonomy, the plugin now does a single combined query, using a proposed API.

Custom Post Type Support

Custom post types go very well with custom taxonomies, so the Taxonomy Drill-Down widget now has a post type dropdown.

Correct Template

This version doesn’t mess with category and tag templates anymore. In earlier versions, when you would go to /category/example, it would attempt to load the multitax.php template file, instead of category.php etc.