Include posts by matching authors in your search results

Out of the box, WordPress’ search isn’t that great. It only returns posts based on a LIKE query against the post title or post content. Often, you’ll want it to match against other data associated with your post, possibly including the author, tags, post meta fields, etc. These queries can get complex to perform on the fly, however.

The following code snippet allows you to include posts by matching authors in your search results. We’re modifying any search queries to also include all posts whose author display name or user login matches the query. You can change this to be the author’s first name, last name, or other fields.

Updated May 17, 2012: Improved the user search so we don’t query for all users and search with PHP; instead, search against the users table.

/**
 * Include posts from authors in the search results where
 * either their display name or user login matches the query string
 *
 * @author danielbachhuber
 */
add_filter( 'posts_search', 'db_filter_authors_search' );
function db_filter_authors_search( $posts_search ) {

	// Don't modify the query at all if we're not on the search template
	// or if the LIKE is empty
	if ( !is_search() || empty( $posts_search ) )
		return $posts_search;

	global $wpdb;
	// Get all of the users of the blog and see if the search query matches either
	// the display name or the user login
	add_filter( 'pre_user_query', 'db_filter_user_query' );
	$search = sanitize_text_field( get_query_var( 's' ) );
	$args = array(
		'count_total' => false,
		'search' => sprintf( '*%s*', $search ),
		'search_fields' => array(
			'display_name',
			'user_login',
		),
		'fields' => 'ID',
	);
	$matching_users = get_users( $args );
	remove_filter( 'pre_user_query', 'db_filter_user_query' );
	// Don't modify the query if there aren't any matching users
	if ( empty( $matching_users ) )
		return $posts_search;
	// Take a slightly different approach than core where we want all of the posts from these authors
	$posts_search = str_replace( ')))', ")) OR ( {$wpdb->posts}.post_author IN (" . implode( ',', array_map( 'absint', $matching_users ) ) . ")))", $posts_search );
	error_log( $posts_search );
	return $posts_search;
}
/**
 * Modify get_users() to search display_name instead of user_nicename
 */
function db_filter_user_query( &$user_query ) {

	if ( is_object( $user_query ) )
		$user_query->query_where = str_replace( "user_nicename LIKE", "display_name LIKE", $user_query->query_where );
	return $user_query;
}

Allowing authors to set co-authors

In the WordPress.org forums, whoaloic asks:

I have a site with multiple authors.
I would like to allow authors who create a post or a page to give rights to other authors.
For now, only administrator and editor can do that.
Is there a solution?

Yep, totally doable. By default, Co-Authors Plus defaults to ‘edit_others_posts’ as the required cap for changing co-authors. With the following code snippet in your theme’s functions.php file, you can make that cap ‘publish_posts’ instead (which authors and above usually have).

/**
 * Filter the Co-Authors Plus current_user_can_set_authors() function
 * so that users with 'publish_posts' can set Co-Authors
 *
 * @author danielbachhuber
 *
 * @see https://github.com/danielbachhuber/Co-Authors-Plus/issues/8
 * @see http://wordpress.org/support/topic/plugin-co-authors-plus-allow-authors-post-to-give-access-to-other-authors
 */
add_filter( 'coauthors_plus_edit_authors', 'db_filter_coauthors_edit_cap' );
function db_filter_coauthors_edit_cap( $cap_result ) {
	global $coauthors_plus;

	$post_type = $coauthors_plus->get_current_post_type();
	if( ! $post_type ) return false;
	
	$post_type_object = get_post_type_object( $post_type );
	return current_user_can( $post_type_object->cap->publish_posts );
}

In preparing this snippet, I also opened a couple of issues in Github:

Show biographies for co-authors at the end of your post

In the WordPress.org forums, doubleedesign says:

I want to add the authors’ biographies to the end of each post.

Awesome… it’s pretty simple to do. Conceptually, what we need to do is load our co-authors, and then loop through printing the relevant information for each one.

You’ll want to put the following code snippet within The Loop in any template you’d like the bios to appear.

/**
 * Show multiple Co-Author biography fields at the bottom of a single post 
 * This snippet should be placed within The Loop
 */
if ( class_exists( 'coauthors_plus' ) ) {
	// Get the Co-Authors for the post
	$co_authors = get_coauthors();
	// For each Co-Author, echo a wrapper div, their name, and their bio if they have one
	foreach ( $co_authors as $key => $co_author ) {
		$co_author_classes = array(
			'co-author-wrap',
			'co-author-number-' . ( $key + 1 ),
		);
		echo '<div class="' . implode( ' ', $co_author_classes ) . '">';
		echo '<h4 class="co-author-display-name">' . $co_author->display_name . '</h4>';
		// Only print the description if the description exists
		if ( $description = get_the_author_meta( 'description', $co_author->ID ) )
			echo '<p class="co-author-bio">' . $description . '</p>';
		echo '</div>';
	}
}

If you’d like other co-author details to appear as well, like their avatar for instance, you can modify the output within the foreach loop.

Scripting my application launch process

Every day for work, there’s several applications I always use. The other day, I put together a quick and dirty bash script for opening all of them at once.

I’m terribly inexperienced at this, so don’t poke fun, only offer good suggestions for improvement…

#!/bin/bash

# Open all of the requisite applications
echo 'Opening Chrome'
`open /Volumes/Macintosh\ HD/Applications/Google\ Chrome.app/`
echo 'Opening Skype'
`open /Volumes/Macintosh\ HD/Applications/Skype.app/`
echo 'Opening Sparrow'
`open /Volumes/Macintosh\ HD/Applications/Sparrow.app/`
echo 'Opening Linkus'
`open /Volumes/Macintosh\ HD/Applications/Linkinus.app/`
echo 'Opening Adium'
`open /Volumes/Macintosh\ HD/Applications/Adium.app/`

Show matching terms in your search results

WordPress’ internal search isn’t all that great out of the box, as I’ve discussed before. For instance, tags and categories aren’t included in the search query; as such, if your post is tagged “apple”, but there is no mention of “apple” in the title or post content, the post won’t be included in your search results.

One partial workaround is to search taxonomy terms against your query and include those in your results. I did this previously with the CUNY J-School’s tech website:

You can have something similar with the code snippet below.

<?php
/**
 * Show matching terms for a given search query
 * Best placed under the_search_form() in search.php 
 */
global $wp_query;
// Only show the matching terms on the first page of results
if ( $wp_query->query_vars['paged'] <= 1 ) {
	$args = array(
		'search' => get_search_query(),
		'orderby' => 'none',
	);
	// You can change the first argument to an array of whatever taxonomies you want to search against
	$matching_terms = get_terms( array( 'post_tag', 'category' ), $args );
	if ( count( $matching_terms ) ) {					
		echo '<div class="all-matching-terms">Looking for? ';
		$all_terms = '';
		foreach ( $matching_terms as $matching_term ) {
			$all_terms .= '<a ';
			if ( $matching_term->description )
				$all_terms .= 'title="' . esc_attr( $matching_term->description ) . '" ';
			$all_terms .= 'href="' . esc_url( get_term_link( $matching_term, $matching_term->taxonomy ) ) . '">' . esc_html( $matching_term->name ) . '</a>, ';
		}
		echo rtrim( $all_terms, ', ' );
		echo '</div>';
	}
}

Co-authors in your RSS feeds

In the WordPress.org forums, razorfrog asks:

Short of editing core WordPress code, is it possible to display the multiple authors in the site’s RSS feed?

Of course there is! From the source code, we know the RSS feed template uses the_author() to display the post’s byline information. Furthermore, the_author() echoes get_the_author() which is a filterable function. Filters allow us to programmatically change values used in a function. What we need to do is write a short snippet to produce the co-authors byline when an RSS feed is requested and Co-Authors Plus is activated.

The snippet is as follows, and can be placed in your theme’s functions.php file or a standalone MU plugin.

/**
 * Co-authors in RSS and other feeds
 * /wp-includes/feed-rss2.php uses the_author(), so we selectively filter the_author value
 */
function db_coauthors_in_rss( $the_author ) {

if ( !is_feed() || !function_exists( 'coauthors' ) )
   return $the_author;

return coauthors( null, null, null, null, false );
}
add_filter( 'the_author', 'db_coauthors_in_rss' );

Disable new site creation email notifications for WordPress multisite

In multisite, WordPress 3.0.5 will send new site creation email notifications to the site admin by default. There’s also no super admin option to disable them. Fortunately, a short code snippet in /wp-content/mu-plugins/ achieves the same effect:

function db_remove_new_site_notification_email( $blog_id, $user_id, $password, $title, $meta ) {
return false;
}
add_filter( 'wpmu_welcome_notification', 'db_remove_new_site_notification_email' );

Behind the scenes, we’re hijacking a filter in wpmu_welcome_notification() to invalidate the method and disable the email. With this approach, the option to email the network administrator is still functional.

Easiest way to add Git to your WebFaction account

wget http://kernel.org/pub/software/scm/git/git-1.7.2.3.tar.gz
tar -xvf git-1.7.2.3.tar.gz
cd git-1.7.2.3
./configure --prefix=$HOME
make
make install

If you’re reading this in the future, you may want to use the most recent version of Git. Instructions via the always helpful WebFaction support team