This week I released Exifography 1.1 (Yay! Woohoo!)
Exifography is a rewrite of Thesography, my WordPress plugin, which displays EXIF data for photographs that have been uploaded to WordPress and enables the import of location (and a few other) EXIF.
I was pretty excited about this rewrite. It was something I had been meaning to do for a long time. It represents a significant increase in my PHP abilities, and therefore an increase in the efficiency and elegance of the plugin (I’ve got more to learn, but it’s still an improvement!), and it also uses the WordPress Settings API, which was developed after I originally wrote the plugin. The settings API is cool because it automatically handles saving of theme and plugin settings and helps to separate out the different elements of settings (page layout, form fields, and input validation), making them a bit more manageable.
One of the things I was thinking of building into the plugin, but wasn’t sure how yet was reordering of the EXIF fields. Then as I was coding and looking over emails from users, I saw that one user had totally rearranged how his location data was displayed. I realised that if I allowed users to filter the output of the plugin they could both reorder and replace any content that they wanted to, as well as add or remove content. So, this post shows how you can do those things.
Naturally, if it’s something very simple that you want to add before or after the EXIF data you could just do that in the HTML options for the plugin, but if you want to add dynamic data (something that changes according to the image or the post) you can do it with a filter. These first couple of examples aren’t dynamic though, just show you what is happening in the filter.
Exifography filter format
The filter format to filter Exifography output is as follows.
function add_exif_item($content,$postID,$imgID) {
$content[] = '<li>This will display after the EXIF data.</li>';
return $content;
}
add_filter('exifography_display_exif','add_exif_item',11,3);
For more about what filters are read the WordPress Codex.
This filter example shows a function with a unique name, and it can receive 3 parameters (sets of information):
- $content is an array with all of the EXIF items already formatted for display (by default they are in an unordered list format, but if you have changed the default HTML display options on the options page, they will be in that format).
- $postID is the post ID that the function is currently working in. You might want to use that in your filter if you need to fetch post specific information to add to the output.
- $imgID is the ID of the image that is currently being referenced. This will be either the first image attached to the post, or the specific image referenced by a template function or shortcode.
The set of square brackets in $content[]
is the PHP syntax for adding a new array item to an existing array. So the above filter adds a list item saying “This will display after the EXIF data.” to the end of the list.
You have to return
the modified content array in order to give it back to the plugin’s display function so it can use the data you’ve given it.
To apply the filter you need the line add_filter('exifography_display_exif','add_exif_item',11,3);
.
- The first parameter is required and cannot be changed (it is the name of the filter in the plugin).
- The second parameter is required and is the name of your function.
- The third parameter is optional and is the priority with which the filter is executed (mainly relevant if you have multiple filters, 1 is executed before 2 etc).
- The fourth paramater is optional and is the number of parameters that can be used. By default filters only pass one parameter, so if you only need the content from the filter (as shown in the next example), that’s fine, but if you do want the post ID and/or image ID you need to use this parameter.
Add something before the EXIF data
If you would like to add something before the EXIF data you can use the PHP array_unshift function to put your new $content
array item at the start of the array.
function add_before_exif($content) {
$item = '<li>This is before the exif items.</li>';
array_unshift($content,$item);
return $content;
}
add_filter('exifography_display_exif','add_before_exif');
Rearrange your EXIF items
By default the exif items are listed in alphabetical order. You can change that by reordering the $content
array. The Exifography output is stored as an associative array, which means that each value is stored with a named key, and that named key is the same as the name with which the exif is stored in the database, and the name that Exifography accepts as a parameter in its function and shortcode.
This function uses an array of EXIF fields that you define ($order
) to create a new array with the EXIF data in the order that you give it, and then combines the new array and old array (in case there were other EXIF fields that should be shown, but that you didn’t include in your order).
function reorder_exif($content) {
$order = array('shutter_speed','aperture','iso','camera');
$new = array();
foreach ($order as $key) {
if (isset($content[$key])) {
$new[$key] = $content[$key];
unset($content[$key]);
}
}
$new_content = array_merge($new,$content);
return $new_content;
}
add_filter('exifography_display_exif','reorder_exif');
Change an EXIF item
You can change an individual EXIF item to anything you want by redefining the array item with that particular key.
Here is a really simple example to show you just how to change a particular item.
function change_aperture($content) {
if (isset($content['aperture']))
$content['aperture'] = '<li>This will display instead of the Aperture item!</li>';
return $content;
}
add_filter('exifography_display_exif','change_aperture');
The following example is more complicated and includes fetching of image information using the image ID. It changes the location display to show latitude and longitude separately. It also uses some of the functions from within the plugin to format the location data.
function change_location($content,$postID,$imgID) {
if (class_exists('exifography')) {
$exif = new exifography();
$imgmeta = wp_get_attachment_metadata($imgID);
if (isset($content['location'])) {
if ($imgmeta['image_meta']['latitude'])
$latitude = $imgmeta['image_meta']['latitude'];
if ($imgmeta['image_meta']['longitude'])
$longitude = $imgmeta['image_meta']['longitude'];
if ($imgmeta['image_meta']['latitude_ref'])
$lat_ref = $imgmeta['image_meta']['latitude_ref'];
if ($imgmeta['image_meta']['longitude_ref'])
$lng_ref = $imgmeta['image_meta']['longitude_ref'];
$content['location'] = '<li>Latitude: ' . $exif->geo_pretty_fracs2dec($latitude) . $lat_ref . '</li>
<li>Longitude: ' . $exif->geo_pretty_fracs2dec($longitude) . $lng_ref . '</li>';
}
}
return $content;
}
add_filter('exifography_display_exif','change_location',11,3);
Some brief notes on what some of that code does:
$exif = new exifography();
sets a new variable to access functions within the plugin’s class. Without it you won’t be able to use the geo formatting functions that I have used here (and your location info will just be a big number).$imgmeta = wp_get_attachment_metadata($imgID);
gets all the metadata for the image, including EXIF and IPTC data.- The middle bunch of code is fetching all the different location related fields from the image meta so that we can use them in the content we wish to display.
$content['location'] =
defines how the location data should display, and I’ve set it to show two list items, one with latitude and one with longitude both in the degree format.
As you can see there is a lot that can be done to customise your EXIF output. I hope these examples get you well on your way.