Recently, I experienced a highly annoying problem in Mac OS X Mavericks: any application (including Finder) would crash whenever the Dropbox folder was opened. This resulted in me losing a lot of work in Adobe Illustrator, for instance, simply because I was trying to open a Save dialog, and the default folder was Dropbox. The whole application crashed.

I then noticed that Finder would crash (the window would close and reopen in the Home folder) whenever I tried to switch to the Dropbox folder.

After a little Googling, I found a solution, but only because I managed to interpret verbose forum posts correctly. Let me give you a clearer thing to try, instead.

  1. Open Terminal.
  2. Type the command below in Terminal, replacing [yourusername] with your user name (the name of your home folder).
  3. Press enter.
rm /Users/[yourusername]/Dropbox/.DS_Store

If you’re like me, that fixes it right up! No more crashing.

July 23, 2014 — 7 Comments — In Dropbox, Resources, Tutorial

Almost four years ago, I wrote what would be one of the most popular posts ever on this site: Taking Control of WordPress Gallery Styling (Without a Plugin). I think it resonated because WordPress’s gallery styling has been heavy-handed, injecting a <style> tag and snippet directly into the page with some mildly arbitrary CSS.

Things have changed with the release of WordPress 3.9. You can now declare theme support for HTML5 galleries (and captions), which outputs <figure> and <figcaption> elements and removes the default, injected styling. Now, we can have control over the gallery style more easily.

Enable HTML5

The first step is declaring support for HTML5 galleries—I’d recommend going ahead with captions, too. Make sure you’re on WordPress 3.9, and add this to a theme file (yes, functions.php is fine):

add_theme_support( 'html5', array( 'gallery', 'caption' ) );

Styling

You’ll need to style the galleries yourself now, including that horizontal distribution that WordPress did do really well. You can start with what used to be injected, which I’ve adapted to work with classes instead of IDs:

.gallery {
  margin: auto;
}

.gallery .gallery-item {
  float: left; // Change to 'right' if RTL is enabled
  margin-top: 10px;
  text-align: center;
}

.gallery img {
  border: 2px solid #cfcfcf;
}

.gallery .gallery-caption {
  margin-left: 0;
}

That’s certainly not required; it just gives you a starting point.

WordPress used to calculate the width of the items in a gallery using PHP, because we need to know how many items are in a row (“Columns”) and divide that by 100 to get the proper percentage. We can use JavaScript to set this width, because WordPress still adds a class to the gallery element telling us how many elements go in a row.

<script>
// Cache the Gallery element
var gallery = jQuery('.gallery');
if ( gallery.length > 0 ) {
  // Find the WordPress class that tells us how many columns to use
  var columns = jQuery.grep(gallery.attr('class').split(' '), function(v, i) {
      return v.indexOf('gallery-columns') === 0;
  }).join();
  // Get the number out of the class and calculate the width
  gallery.find('.gallery-item').width( 100/parseInt(columns.replace('gallery-columns-', '')) + '%' );
}
</script>

Lightbox

I like using Nivo Lightbox—so much so I built a WordPress plugin for it. You can grab that plugin and activate it, and it will work automatically throughout your site, including grouping galleries together automatically.

You can also easily integrate it into your theme. If you’re going that route, you ought to combine all the needed CSS and JS files with your theme files to gain any benefit—otherwise, just use the plugin. When integrating, I install Nivo Lightbox with Bower and enqueue the needed files with my existing Grunt configuration. Since the script is used nearly everywhere, we might as well include it in the main files.

You’ll want to do two things to integrate in this manner: change the theme CSS a bit and add the initiation call to your JavaScript file.

Nivo Lightbox CSS

I pull the CSS from the default Nivo Lightbox theme and put it in my own file for two reasons. First, since I’m including the files in a Grunt task, the paths to the small lightbox images (like the “close icon) need to be changed. Second, this allows me to make any visual changes I want. Just make sure those CSS components are pulled in after the main nivo-lightbox.css file.

Nivo Lightbox JS

To initialize the lightbox, we need to add a quick function call. The following is in my plugin that I linked up, but you’ll need it regardless:

<script>
jQuery(document).ready(function(){
    jQuery('.gallery a:has(img)').attr('data-lightbox-gallery', 'nivo-gallery');
    jQuery('a[href*=".png"]:has(img), a[href*=".gif"]:has(img), a[href*=".jpg"]:has(img)').nivoLightbox();
});
</script>

This looks through the page and initializes any link that’s pointing to an image, and adds a data attribute to gallery images so they’re grouped together.

You can add options inside the nivoLightbox() call as you wish.

That should get you started! Looking back on an old article, seeing its popularity, and seeing WordPress naturally evolve to address its concerns is encouraging.

I hope this updated article helps you move forward in building great websites. As always, feel free to leave questions in the comments area.

May 9, 2014 — 2 Comments — In Blog, Development, Tutorial, WordPress

I’m constantly looking for ways to make WordPress more palatable for the common user (see: non-developers). It may be simple in comparison to other content management systems, but it’s still got some confusing artifacts. And, once you start adding robust plugins, things can get messy.

Here are some of my approaches to optimizing the WordPress admin area, along with snippets for making it happen or links to a plugin.

Disable Editor and Updates

I can’t think of a good reason to ever use the built-in code editor in WordPress. If you’re far enough along to edit code, you’re far enough along to use a real code editor with FTP or version control. This will disable it entirely:

define( 'DISALLOW_FILE_EDIT', true );

If—and only if—you are consistently checking for updates and updating on your client’s behalf, and you don’t want them adding plugins autonomously, you can disable the ability to add and update plugins and themes:

define( 'DISALLOW_FILE_MODS', true );

The two lines above can go in wp-config.php or a plugin. Everything else from this point should go in a plugin.

Editor Permissions

I often want to give editors access to the Appearance menu, so I built a plugin that does that. No setup, no settings.

Hide Unnecessary or Sensitive Menu Items

The Tools > Available Tools menu item in WordPress provides no value to most of my clients (or me, for that matter). You can remove it from view with:

function yourplugin_remove_tools() {
   remove_submenu_page( 'tools.php', 'tools.php' );
}
add_action( 'admin_menu', 'yourplugin_remove_tools', 999 );

I also utilize plugins for caching and security, but I don’t really want either of those settings to be visible to folks if I’m helping them manage things. Here, I’ve removed the menu links for Better WP Security and W3 Total Cache:

function yourplugin_remove_tools() {
    remove_menu_page( 'better-wp-security' );
    remove_menu_page( 'w3tc_dashboard' );
}
add_action( 'admin_menu', 'yourplugin_remove_tools', 999 );

Note: these pages will still be accessible by visiting the proper URL. That means you can get to it, and it’s very unlikely that a user will stumble upon it. That’s the goal.

Hide Sensitive Plugins from the Plugins Page

Following the logic from above, there are some plugins that need to stay put and not be deactivated. In some cases, dropping plugins in the mu-plugins folder will work. That won’t do in all instances, so you can hide them from the plugins listing instead.

This removes the same two plugins:

function yourplugin_filter_plugins( $plugins ) {
    $hidden = array(
        'Better WP Security',
        'W3 Total Cache'
    );
    foreach ($plugins as $key => &$plugin ) {
        if ( in_array( $plugin["Name"], $hidden ) ) {
            unset($plugins[$key]);
        }
    }
    return $plugins;
}
add_filter( 'all_plugins', 'yourplugin_filter_plugins' );

Remove Specific Links from the Menu Bar

The W3 Total Cache plugin is a good example here: sometimes, I want to leave the menu option for purging cache available to users with permission. However, I don’t want the ‘FAQ’ and ‘Support’ links that come along with that dropdown. So, I’ll just remove those specific links:

function yourplugin_remove_admin_bar_links() {
    global $wp_admin_bar;
    $wp_admin_bar->remove_menu('w3tc-faq');
    $wp_admin_bar->remove_menu('w3tc-support');
}
add_action( 'wp_before_admin_bar_render', 'yourplugin_remove_admin_bar_links' );

Remove Dashboard Widgets

Yes, you can use the ‘Screen Options’ menu to show/hide widgets on the Dashboard. However, the ‘WordPress News’ widget is pretty irrelevant to most of my clients. We can hide it completely, instead:

function yourplugin_disable_dashboard_widgets() {
    remove_meta_box( 'dashboard_primary', 'dashboard', 'normal' );
}
add_action( 'admin_init', 'yourplugin_disable_dashboard_widgets' );

All the Code as a Plugin

If you like everything you see here, you can use the boilerplate code in this gist. Change the prefixes to something relevant, fill in the other information, and customize as needed. Drop it in the mu-plugins folder (create that folder if you don’t have it). That’ll keep it activated automatically.

Also: don’t drop any of this code in functions.php. This has nothing to do with your theme, so it shouldn’t be dependent on it.

For any of these functions, you can make the result conditional by role, permissions, etc. A little digging around should help you figure any of that out.

I hope this helps you! I’m passionate about making WordPress a CMS that users love. Luckily, it’s easy to integrate code like this that removes what we don’t want.

March 7, 2014 — 3 Comments — In Blog, Development, Tutorial, WordPress

Recently, I needed to dynamically set a Custom Variable in Google Analytics. This isn’t hard if you’re putting in the web tracking code by hand, but it can be a bit tough working with a plugin.

Yoast’s Google Analytics for WordPress plugin (which I highly recommend) can do this, although it’s not entirely intuitive.

First, you need to throw some Javascript into your <head> to set a global variable. You can set whatever you want here, but make sure it’s got a priority of 1 when you add it to wp_head. That’s the only way to set it before the analytics code gets echoed. Add this to your functions.php file or your own plugin:

function set_your_customvar() {
    echo "
        <script>
            var yourcustomvar = 'whatever';
        </script>";
}
add_action( 'wp_head', 'set_your_customvar', 1 );

Obviously, you’ll set your variable to whatever dynamic value you need it to be. In my case, I pulled the value from an existing cookie.

Then, you need to set your custom variable in the analytics code. To do this, go to Settings > Google Analytics in the admin area. Make sure ‘Show advanced settings’ is checked:

Screen Shot 2014-02-14 at 3.47.37 PM

Then, scroll down to the ‘Custom Code’ area. Here, set the custom variable and pull in your global variable from before. Make sure you set the parameters properly. Also, make sure you use single quotes and not double, due to the way the plugin will strip some things out. For instance:

_gaq.push(['_setCustomVar',5,'my_custom_var',yourcustomvar,2]);

Screen Shot 2014-02-14 at 3.47.55 PM

That’s it! Wait an indiscriminate amount of time (something like 2-24 hours), then log into Google Analytics. Look under Audience > Custom > Custom Variables, and set the ‘Primary Dimension’ to whatever slot you put your variable in.

If you just made the change today, make sure you update the date range Google Analytics is showing to include today. 🙂

February 28, 2014 — 2 Comments — In Blog, Development, SEO, Tutorial, WordPress

View Slides

We’ll cover the basics of the Transients API, see basic examples, and then discuss common places where this method can be most helpful, like large, complex queries or pulling from an external API. We’ll also discuss how this type of caching is unique, when to use it, and how to scale it for big bursts of traffic.

Follow Along

I’ve got all the working code samples in a plugin that you can look through while we talk. View it in GitHub, or download the repo and apply it to a local WordPress installation to see the code at work. To do that:

  1. Clone the repo to your plugins directory or download the .zip file.
  2. Activate the plugin.
  3. Import the contained .xml file, which will import five posts with shortcodes that execute the functions.

If you use MAMP and want to spin up an installation quickly, I’ve got a shell script for you to do just that.