Hide WordPress Post from All Queries

Problem: you want to create a variation of a page but you don’t want it to show up on the home page or in any archives or anything. You just need a direct link so you can share it with someone.

Solution:

add_action('pre_get_posts', 'hide_hidden_posts');
function hide_hidden_posts($query) {
  if ( is_admin() ) {
    return $query;
  }

  if ( is_single() AND $query->is_main_query() ) {
    return $query;
  }
  $ids = wp_cache_get('hidden_posts', 'posts');
  if ( !$ids ) {
    global $wpdb;
    $ids = $wpdb->get_col("SELECT post_id FROM {$wpdb->prefix}postmeta WHERE meta_key = 'hide_post'");
    wp_cache_set('hidden_posts', $ids, 'posts');
  }
  $query->set('post__not_in', $ids);
  return $query;
}

This function will modify all WordPress’ frontend queries to exclude any posts with a custom field “hide_post”, except in the case that the query is the main query on a single post page.

Caveat: This will only be functional for plugins and themes using the WP_Query api. Custom queries will not be modified.

WordPress $current_user Global Changed in WordPress 3.3

WordPress has been slowly changing their global $current_user object and the changes in WordPress 3.3 broke my Simplr Registration Form Plus plugin and probably a few others. For any other developers trying to investigate why usermeta field values disappear it is because:

global $current_user;

This was used to return an object containing not only the primary user fields but all the meta fields as well. So if you set a user meta field called “age” you could simply do:

global $current_user;
if($current_user->data->age > 21) {
  // the do some adult stuff;
}

But this shortcut is no longer available to developers and for good reason. As a general rule code should be efficient, meaning it does only what it has to. To load even the most superflous meta fields every time you access the basic user object is a waste of resources.

So good for WordPress, they are improving. But there are likely others like me who figured if WordPress was going to give me the info, then I was going to use it. And like me they’ll have to spend all day tracking down everywhere they used this shortcut and fixing it. Ugh.

WordPress Hack: Turning Off BuddyPress Notifications By Default

By default BuddyPress has all sorts of email notifications turned on. This is great unless you have a big site with lots of activity and site-wide discussions. Then new users start getting pinged repeatedly on discussions they don’t want to follow or don’t even know they are apart of! So you may want BuddyPress to turn the notifications off by default. But there’s no clear way to do this in the admin. Well, here’s the golden function.

add_action('bp_core_signup_user','bp_set_notification_default',100,1);
  function bp_set_notification_default($user_id) {
    $keys = array('notification_activity_new_mention','notification_activity_new_reply','notification_friends_friendship_accepted','notification_friends_friendship_request','notification_groups_admin_promotion','notification_groups_group_updated','notification_groups_invite','notification_groups_membership_request','notification_messages_new_message','notification_messages_new_notice');
    foreach($keys as $key) {
      update_user_meta($user_id,$key,'no');
    }
}

Please note that this function is hooked to bp_core_user_signup which means existing users still have to manually turn off notifications. But you could easily run this function on an array of user_ids to change the defaults for existing users.

WordPress Hack #3

Here’s a function that really should be in WordPress core by now. And maybe it is and I just can’t find it. But to get the source url for a post thumbnail you have to hack. Here it is:

/** 
**
** Parameters: 
** Size (optional): The width/height of the source image. Accepts either a string designating the WordPress image size, ( i.e. "thumbnail", "full","medium") or an array containing a custom size, i.e.  array(250,250) . Defaults to full size
**/
function get_post_thumbnail_url($size = 'full') {
global $post;
$src = wp_get_attachment_image_src( get_post_thumbnail_id($post->ID), $size, false, '' );
echo $src[0];
}

WordPress Hack #1: Global Meta Variable for Custom Fields

This is the first in what I hope will be a series of posts on “WordPress Hacks”, simple code you can add to functions.php to make your life as a developer a little easier.

Ever get tired of typing get_post_meta($post->ID, $meta_key, $true); to fetch even the simplest of WordPress custom field values. Try this.

add_action('the_post','setup_meta_var');
function setup_meta_var() {
global $wp_query,$meta;
$vals = get_post_custom($data->ID);
foreach($vals as $k => $v) 
{
if(count($v) > 1):
$meta[$k] = $v;
else:
$meta[$k] = $v[0];
endif;
}
}

What this dandy little function does is automatically assign a post or page’s custom values to a global variable call $meta.

To use your custom field values now, you simply have the do echo the meta_key like so:

global $meta;
echo $meta['meta_key'];

If there is more than one value for that custom field, you will simply need to do a standard foreach loop.

global $meta;
foreach($meta['meta_key'] as $m) {
echo $m;
}

Update: Hey, I realized that in the code snippet I pasted here I was setting a $type variable. That was a relic of the custom script this code was taken from … so please ignore.