Synchro Genesis

Synchro Genesis

Shameless self promotion:

I’m close friends with some of the core team members of the Synchro Genesis product launch campaign. Synchro is awesome. It’s a protein shake / meal replacement / energy drink. The main idea is: instead of drinking caffeine and sugar, which will inevitably wear off and leave you feeling shitty… why not start your day with something that’s actually good for you? Synchro wakes you up and invigorates you, but because the energy comes from protein, you don’t crash later– you don’t develop a tolerance, you don’t feel like crap when it wears off, and if you need a boost in the afternoon… just take some more!


This is a unique tracking link to our Indiegogo campaign. We’re trying to raise enough startup capital to begin large-scale commercial production of Synchro. If you have a minute, check out the product… and by clicking the link above, I get to show my support of Synchro by sending them traffic.

The definitive method to highlight an array of search terms using PHP and preg_replace

I came across this problem while working on the WP Ultimate Search plugin. Here’s the code we were using initially:

  1. private function highlightsearchterms($text,$keywords){
  2.  foreach($keywords as $keyword) {
  3.   $text = preg_replace('#' . $keyword . '#iu', '<strong class="usearch-highlight">$0</strong>', $text);
  4.  }
  5.  return $text;
  6. }

This works fine, except when someone adds the words “search” or “highlight” as additional keywords to a search that already has results. At that point, the preg_replace would go through and highlight the class name within the <strong> tag, since the HTML matched the search query. We needed to figure out how to do the entire preg_replace in one operation, without iterating for each element of the $keywords array.

It took almost an hour of searching to hack together a solution. Doesn’t seem like any one else has come up with a way to do it all on one line. So here it is.:

  1. private function highlightsearchterms($text,$keywords){
  2.  return preg_replace('/(' . implode('|', $keywords) . ')/i', '<strong class="usearch-highlight">$0</strong>', $text);
  3. }

Elegant, fast, and solved the problem. The /i flag tells preg_replace to ignore case. You can leave it in or take it out.

There are 150,000 lines of code in WordPress

The King James Bible has just shy of 80,000 lines of text

Hamlet has only 4,000.

WP Ultimate Search

Check out my newest plugin… WP Ultimate Search. It’s the first ever ajax-enabled faceted search plugin for WordPress. Right now it can only facet by category, but when we launch the premium version there will be an interface where you can enable faceting by any custom taxonomy, post meta data, or (advanced) custom field.


  • Searches post title and body content
  • Can search by multiple keywords, and by full phrases
  • Highlights search terms in results
  • Searches inside of shortcodes
  • Option to send search queries as events to your Google Analytics account
  • Facets by post category
  • Can search in multiple categories (OR search)
  • Category options are dynamically generated and autocompleted as you type
  • Attractive and lightweight interface based on jQuery, Backbone.js, and the VisualSearch.js library
  • Bypasses WordPress’ built-in search functions and conducts direct database queries for low overhead and high flexibility

Try a demo:

Search with plain text, or begin typing “category” to facet by categories: (my site’s especially overloaded these days, so results may be slow, but this isn’t the norm)

How to include a custom stylesheet on a WordPress options page

(or, “how to put a bunch of error messages in a blog post for effortless traffic”)

Let’s start with what doesn’t work, beginning with including the options page file itself:

If you’re defining a base URL for your includes, for example define('PLUGIN_BASE', plugin_dir_url( __FILE__ ));, you won’t run into any problems enqueuing scripts and stylesheets.
wp_enqueue_style( 'plugin-style', PLUGIN_BASE. 'css/plugin-style.css'); will work fine.
But don’t think about trying to include( PLUGIN_BASE . 'plugin-options.php');, you’ll get a friendly:
Warning: include() [function.include]: URL file-access is disabled in the server configuration
(It seems like include( 'plugin-options.php'); works, but I don’t think it’s the best way to go about it).

If we were suspicious of PLUGIN_BASE before, we’ll quickly progress to dismay and anger once we try to use it in plugin-options.php. A simple call to wp_enqueue_style( 'options-style', PLUGIN_BASE. 'css/options-style.css'); gives us this bizzarre error in the console:

Failed to load resource: the server responded with a status of 404 (Not Found)

Ok, so maybe the PLUGIN_BASE constant isn’t valid inside of a different class, or something. Let’s forget the definition and just put plugin_dir_url( __FILE__ ) there instead.


trailingslashit( dirname( $file ) )?
plugin_dir_url( $file )?
realpath( dirname( __FILE__ ) )?

What eventually ended up working, though I still couldn’t tell you why, is wp_enqueue_style( 'options-style', plugins_url('/options-style.css', __FILE__) );

So if you got here with any of those errors above, I hope this has helped you out.

Upgrading Mountain Lion to a bigger hard drive

I just purchased a Seagate Momentus XT 750GB hard drive to replace my aging Hitachi 320GB drive that came with my Macbook Pro. (It’s a lot faster… I don’t know why I didn’t do this a long time ago.) Normally I’m used to simply mirroring the old drive onto the new one during an upgrade, but with OSX Lion and later, Apple installs a hidden Recovery HD partition.This hidden partition is essential for running OSX, and will be lost if you use disk utility to do a direct copy of the old drive. Here’s how I upgraded to a new drive, step by step:

  1. Plugged the new drive into a USB port using a Cables To Go USB drive adapter (there’s probably a faster way to do this, but it’s what I had on hand).
  2. Opened Disk Utility and partitioned the drive into two partitions: one 60gb NTFS (compressed) partition for my Bootcamp install, and the rest as a journaled HFS+ partition called “Macintosh HD”
  3. Opened Carbon Copy Cloner, opened the Disk Center, and selected the new Macintosh HD partition on the new drive. Click the Recovery HD tab and click “Create a Recovery partition for this volume.” This will automatically create an appropriately sized Recovery HD, and copy over the existing Recovery HD from your current system. Carbon Copy Cloner was the only tool I could find that supported copying this hidden drive easily— neither Apple’s Disk Utility, or Drive Genius 3 supported copying the recovery drive.
  4. Back in the Cloning Console, select your current internal Macintosh HD as the source drive, and the new Macintosh HD as the destination drive. Click “clone.” Carbon Copy will clone your existing drive, and update the recovery partition if necessary.
  5. (Optional) I then cloned my current Bootcamp partition onto the new bootcamp partition on the new drive.
  6. Physically remove the old drive, install the new one, and boot.

Everything should be there, and you’ve saved yourself from having to reinstall Mountain Lion and do a migration!

Cheat Sheet for the WordPress bundle in TextMate

There wasn’t one of these already, so I made one. Based on the WordPress TextMate Bundle by Shawn Parker & Top Frog Graphics.

GDE Error: Unable to load profile settings

jQuery Notify

jQuery Notify

I released my first WordPress plugin yesterday, jQuery Notify. It’s a lightweight and highly configurable jQuery notification pane that will appear after a page loads. It can be inserted into a page or post by either using a shortcode or template tag, and is smart enough to only load on pages it’s needed on.

I created this as an opportunity to learn more about WordPress’ action/hook/filter system for my upcoming presentation at Wordcamp 2012. The entire plugin is wrapped in a class to avoid variable/function naming conflicts, and it only loads on pages where the shortcode is actually called. All styles and scripts are registered through wp_enqueue_script and wp_enqueue_style, and data is passed between the plugin and the scripts using the localize_script function.

Check out a demo of the plugin, or install it on your own site.

jQuery .fadeIn() opacity bug in Chrome and IE 8

I kept encountering this strange glitch in Chrome when using jQuery’s .fadeIn() effect on a text element. The text would fade in properly, but then flicker to a slightly bolder weight. The text wasn’t bold, so I couldn’t figure out what was going on.

It turns out that in IE 8 (and lower) and in Chrome on some operating systems, the text loses its ClearType while fading, and then has ClearType activated once it’s fully faded in. This causes a distracting jitter. Thankfully there is an easy fix. Add the following to the CSS selector for the text element:

  1. opacity:0.99;
  2. filter:alpha(opacity=99);

This will make the element fade in to only 99%, thus preventing ClearType from engaging, and smoothing out the transition.

Moving bookmarks from Cyberduck to Transmit

Transmit has an “Import from Cyberduck…” option, but it seems to be unable to recognize the .duck files that Cyberduck uses to store its bookmarks. I found this bash script on a German blog, so I thought I’d repost it here for convenience sake. The script iterates through all of the bookmarks in the Cyberduck bookmarks directory, and generates a .plist file which Transmit can import. Worked perfectly for me. Good luck.

  1. echo '< ?xml version="1.0" encoding="UTF-8"?>
  2. < !DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "">
  3. <plist version="1.0">
  4. <array>'
  6. shopt -s nullglob
  7. DIRECTORY=~/Library/Application\ Support/Cyberduck/Bookmarks/
  8. cd "$DIRECTORY"
  9. for file in *
  10.  do sed -ne '/dict/,/\/dict/p' "$file"
  11. done
  13. echo '</array>
  14. </plist>'

Save the file (, for example), and then make the script executable with

  1. $ chmod a+rwx ./

And then run it with

  1. $ ./ > cyberduck_bookmarks.plist

This will generate a .plist file which you can happily import into Transmit.