Introducing Soapberry for Ackee

Update: this plugin was originally called Ackee WP but has been renamed to Soapberry to comply with the trademark policy for plugins. The plugin can now be found on under the slug Soapberry.

As part of my desire to own my data, I haven’t used Google Analytics for the past few years. In that time I’ve been curious about my site statistics but knew when I resumed collecting data I wanted to do so in a way that respected the privacy of my visitors.

This year I started a search for self-hosted tracking solutions and came across a lightweight node application, Ackee. After looking at a few other options I decided on Ackee for its care in anonymizing user data. Through hashing the user’s IP, a unique domain ID, and a salt which changes daily, site visits can be tracked without tracking the individual visitors.

For my needs, I want to know how many visits my sites are getting, where visitors are coming from, and how long they stay on the site. However, I do not have a need or desire to track individual visitors.

Using Ackee with WordPress

After setting up an Ackee instance and adding the tracking script to a few static sites I wanted to bring the functionality to my WordPress sites. At first, I just edited the theme’s footer.php file which worked well enough as a quick way to insert the script. Next, I hooked into wp_footer() so it would be easier to exclude logged in visits from the analytics.

While both of these methods work they do require a bit of WordPress know-how and do not carry over when switching themes. Wanting a better solution, I got to work writing Soapberry a WordPress plugin that adds the Ackee tracking script and data attributes to the site’s footer based on settings saved on a WP Admin page.

Keeping things simple at first, this first version of the plugin only has the ability to exclude all logged-in visitors and does not take into account the personal data options provided by Ackee. In the future, you may be able to exclude visits by role and enable opt-in tracking for personal information.

Exploring Ackee Alternatives

If after looking at Ackee you don’t think its right for you that’s okay. Ackee won’t be right for everyone. The good news is there are other options when looking to move away from Google Analytics, Facebook Pixel, or other third-party tools.

Chris Wiegman wrote a post on anonymizing and tracking visits at the server level to avoid the JavaScript requirement of many trackers. The folks over at Awesome Open Source also list several other Analytics tools that can be explored. If you find a tool you like let me know what you are using in the comments.

MP6 Light

It’s one of the (not so) well kept secrets in WordPress that a team is busy redesigning the admin interface.  In fact, if you use you have likely noticed a change in the admin layout some time ago. For those of you using a self-hosted WordPress site the change most likely won’t happen till at least 3.7.

However, for the early adopters and developers you can preview the new layout by using the MP6 Plugin.  I personally (and from the forums, many others) felt that the new sidebar was too dark. It also currently looks like MP6 plugin won’t give users the option to switch between layouts. For this reason I’ve created MP6-light which basically works by adding a stylesheet that makes the admin a bit lighter. Check out the project page or get the plugin from the WordPress repository.

NOTE: This plugin requires the MP6 plugin to be installed.

P.S: I’m also looking for people to get involved with the project on github.

screenshot-2 screenshot-1

Uploading Files as Post attachments with Gravity Forms

Okay so like may others I love Gravity Forms. Simple, elegant forms for WordPress. However, I recently ran into a snag when trying to use the awesome Custom Post Type plugin to allow my client to upload a PDF then have that be saved as an attachment to the post. Here is my solution in hopes it helps you. I’m open to suggestions on better ways to do this.

add_filter("gform_after_submission", "nifty_add_post_attachements", 10, 3);
 function nifty_add_post_attachements($entry) {
 //you'll need this later, TRUST ME.
 if(!function_exists('wp_generate_attachment_metadata')){require_once(ABSPATH . 'wp-admin/includes/image.php');}

//do we even have a file?
 if (isset($_FILES['input_4'])) {
 $file_url = $entry['4']; //great but what is its url?
 $upload_dir = wp_upload_dir(); //where do you want to put it?
 $file_data = file_get_contents($file_url); //show me what you're made of
 $filename = basename($file_url); //so cute but what's its name?
 if(wp_mkdir_p($upload_dir['path'])) //can we put it there?
 $file = $upload_dir['path'] . '/' . $filename; //yes great
 else //or no, okay fine let's try somewhere else
 $file = $upload_dir['basedir'] . '/' . $filename; //get the whole location
 file_put_contents($file, $file_data); // tada home at last

$wp_filetype = wp_check_filetype($filename, array('pdf' => 'application/pdf','pdf' => 'application/x-pdf') ); //is it the right type of of file?
 $attachment = array( //set up the attachment
 'post_mime_type' => $wp_filetype['type'],
 'post_title' => sanitize_file_name($filename),
 'post_content' => '',
 'post_status' => 'inherit'

$attach_id = wp_insert_attachment( $attachment, $file, $entry['post_id'] ); //insert attachment
 $attach_data = wp_generate_attachment_metadata( $attach_id, $file ); //asign the meta
 wp_update_attachment_metadata( $attach_id, $attach_data ); //update the post

//remove the entry
 //(to keep the entry comment or delete these line)
 // IMPORTANT See: for the function
 if(!function_exists('sedc_gform_remove_entries')){ die('next time maybe you should read the comments');}
 else{ nifty_gform_remove_entries($entry, $form );}

I have included a function that removes the entry and original file upload. That function can be found here. There is also a simpler version that doesn’t give a damn about the file upload that can be found here. Both are original from the GF support forms but have been slightly modified for v 1.6.  I should also point out that some of the upload code came from here.

Hope you find this useful

Simple Portfolio Widget

Hi, I just wrote a simple portfolio widget and thought I would share. This code uses Justin Tadlock’s get_the_image plugin and custom widget code to display the featured image based on tag or post type.

Just drop this into your functions.php or create a plugin to see it in action

if ( function_exists( 'add_image_size' ) ) {
add_image_size( 'sidebar-thumb', 75,75,true   );

class PortfolioWidget extends WP_Widget
function PortfolioWidget()
$widget_ops = array('classname' => 'PortfolioWidget', 'description' => 'Displays a list of thumbnails for portfolio pieces in the sidebar' );
$this->WP_Widget('PortfolioWidget', 'Portfolio Thumbnails', $widget_ops);

function form($instance)
$instance = wp_parse_args( (array) $instance, array( 'title' => '','tags' => '', 'post_type' => '' ) );

$title = $instance['title'];
$tags = $instance['tags'];
$post_type = $instance['post_type'];

<p><label for="<?php echo $this->get_field_id('title'); ?>">Title: <input id="<?php echo $this->get_field_id('title'); ?>" name="<?php echo $this->get_field_name('title'); ?>" type="text" value="<?php echo attribute_escape($title); ?>" /></label></p>
<p><label for="<?php echo $this->get_field_id('tags'); ?>">Tags: <input id="<?php echo $this->get_field_id('tags'); ?>" name="<?php echo $this->get_field_name('tags'); ?>" type="text" value="<?php echo attribute_escape($tags); ?>" /></label></p>
<p><label for="<?php echo $this->get_field_id('post_type'); ?>">Post Types: <input id="<?php echo $this->get_field_id('post_type'); ?>" name="<?php echo $this->get_field_name('post_type'); ?>" type="text" value="<?php echo attribute_escape($post_type); ?>" /></label></p>

function update($new_instance, $old_instance)

$instance = $old_instance;
$instance['title'] = $new_instance['title'];
$instance['tags'] =  $new_instance['tags'];
$instance['post_type'] = $new_instance['post_type'];

return $instance;

function widget($args, $instance)
extract($args, EXTR_SKIP);

echo $before_widget;
$title = empty($instance['title']) ? '' : apply_filters('widget_title', $instance['title']);
$tags = empty($instance['tags']) ? '' : wp_parse_id_list($instance['tags']);
$post_type = empty($instance['post_type']) ? '' : preg_split( '/[\s,]+/',strtolower($instance['post_type']));

if (!empty($title))
echo $before_title . $title . $after_title;

$query = new WP_Query( array( 'post_type' => $post_type, 'tag_id' => $tags  ) );
while ( $query->have_posts() ) : $query->the_post();
echo get_the_image( array( 'meta_key' => 'Thumbnail','size' => 'sidebar-thumb') );
echo $after_widget;


Let me know your thoughts or if you have any questions. If there is a large intrest I may post a complete write up and example with images.

MobileESP 1.3.1

I just put out a quick fix for MobileESP for WordPress to hopefully FINALLY fix the two click cookie issue. Version 1.3.1 can be found in the other versions folder over on the WordPress Plugin page. If you don’t see 1.3.1 listed just grab the “Development Version.”

Please test this version and let me know if any issues arise if all goes well I’ll make this the stable version.

– Upgraded the MobileESP library to latest stable version
– Hopefully fixed full site redirect issue.