Before your eyes glaze over, I want to assure you that no programming experience is necessary to follow the examples contained herein, but it sure wouldn’t hurt either. This article contains a functional example that you can use with minimal modification on your own WordPress site. With that out of the way…
The beauty of WordPress, and building plugins for WordPress is the hooks and filters that are available. This is the glue that brings things together, and makes WordPress extendable. A hook lets you run whatever code you wish at that point in time, but it does not generally let you modify what the rest of the code is doing. A filter is a different animal altogether as it is given a value to work with, modify, mangle, delete, or whatever, and then it must pass back that value to the parent function. You can probably read articles about hooks and filters till your eyes bleed, but essentially there are two components to make this happen:
- Somewhere in the core code, the apply_filters() function is called, which then starts the process of running any filters that have been attached to a specific action.
- In your own code, you call add_filter() with the name of the action matching apply_filters(), and the name of whatever function you want to run.
When you’re writing a plugin, you make heavy use of add_filter() and add_action(), but making your own plugin extensible is often an afterthought. At least, I’ll be honest enough to admit that is generally what happens for me, although I do have some proactive filters out there just waiting for folks to find. Allowing other plugins, or even your users, to modify what your plugin does by default takes things to a whole new level. It also means you have to be careful what you allow them to do.
The first filter we are going to look at in EWWW I.O. is called ewww_image_optimizer_bypass and it allows someone to change whether or not an image will be optimized based on the characteristics of the file. It provides two variables to work with, and looks like this:
$bypass_optimization = apply_filters( 'ewww_image_optimizer_bypass', false, $file );
As you can see, any filter added to ewww_image_optimizer_bypass will receive two parameters, a boolean false, and the filename ($file). To continue optimizing, the filter would return false, to bypass optimization it must return a boolean true value. The most common use for this filter is to stop optimization of images in a particular folder, and that is what I will show you how to accomplish. So without further delay, here is the code to bypass all images within a specific folder:
<?php
/*
Plugin Name: EWWW Bypass Folder
Version: .1
*/
add_filter( 'ewww_image_optimizer_bypass', 'ewww_skip_theme', 10, 2 );
function ewww_skip_theme( $bypass, $filename ) {
$folder_to_skip = '/var/www/wordpress/wp-content/themes/';
if ( strpos( $filename, $folder_to_skip ) !== false ) {
return true;
}
return $bypass;
}
First I’ll tell you how to use this, and then I’ll break down what it does for those who are curious. You can copy and paste this into a new text file (Notepad, nano, vim, whatever you like for a text editor), and then save it as ewww-bypass-folder.php. You will then need to edit the line that says “folder to skip” to contain the full folder name on the server where you don’t want EWWW to optimize images. Currently it is set for the themes directory on my old dev server, but you will need to change the path between the single quotes to whatever you want to use. You could also repeat the folder_to_skip line and the five lines after that if you have other folders you want to skip too. Once you have customized ewww-bypass-folder.php you can copy it into your wp-content/plugins/ folder, then visit your WordPress plugins page and activate EWWW Bypass Folder. You could also copy this code (minus the first 5 lines with the Plugin Name and Version) into the functions.php file of your theme, or add it into any custom plugins you might have. Once active, this code will instruct EWWW I.O. to ignore images in the folder(s) specified.
How does it work? Glad you asked, because I’m going to tell you (not that it is terribly complicated, but if you are new to programming, it might not be obvious). The first block is just a standard plugin header with the required pieces, a name and a version. It begins with /* and ends with */ to make sure the server does not run this piece of text as code. It’s just for informational purposes, although WordPress does parse these values and display them on your Plugins page.
Next up we have the add_filter() function that I mentioned. The first bit is the name of the action that we are attaching the filter to. If you mess this part up, the function you specify in parameter two will never run. The function name in this case is ewww_skip_theme. The next parameter tells WordPress what priority level to run this filter at, so that filters can be run in a particular order if necessary. Lower numbers run first, higher numbers run later, but 10 is the default. Then the last parameter is 2 which tells add_filter() how many items to pass along to ewww_skip_theme().
The very next line is the ewww_skip_theme function itself, which accepts the boolean false from EWWW IO as $bypass, and the filename of the image currently being considered for optimization. The first line of the function sets the folder we are going to skip/bypass and assigns it to $folder_to_skip which we will use in the next line. The next line then, looks to see if $folder_to_skip matches part of the filename. If it does, we return true, thus telling EWWW to skip this image. Otherwise, we return the existing value for $bypass. Normally, that is a ‘false’ value, but if you have multiple functions hooked onto the bypass action, it might already be true, so it is important to pass along the value “as is”. If you are familiar with regular expressions, you may note that the one used here looks a bit odd, with | characters on either end, instead of the usual / characters. This is because our folder name contains / characters, and rather than trying to escape them all and confuse you all, I opted to make the code cleaner and use pipes for delimeters. Well, that’s all for that one, enjoy!