What’s that close paren doing after my video embed in WordPress?

Working on a new client site that has a lot of YouTube video embeds, I was alarmed this morning to find a stray close paren ) character in all of the posts right after the videos.

Knowing I had recently been tampering with the embed_handler_html and embed_oembed_html filters in the site theme, I figured it was something I had created. So I set about debugging my code but couldn’t get anywhere.

I decided to see if it was in fact a new problem in WordPress itself, by setting up a test post on this site with a YouTube video embed (this, of course). Sure enough, even on my unadulterated theme, the stray close paren appears.

Look at it!!!I mean, just look at it!!!

Anyway, I hope/assume this will get fixed in the WordPress core soon, but in the meantime if you are running into this problem and want a quick fix, and you’re not afraid of editing the functions.php file in your theme, have a go at this little addition that will strip out the offending punctuation:

function embed_fix_stray_parens($content) {
    return str_replace('</iframe>)','</iframe>',$content);
}
add_filter('the_content','embed_fix_stray_parens');

Update #1: I went to submit a bug report to the WordPress development team and found my report was a duplicate of this one. If I understand correctly, the close paren is actually being delivered by YouTube itself, not WordPress, via the oEmbed request. Isn’t the Internet fun?

Update #2: This really is YouTube’s problem… it even shows up in the embed code you get on their own site:

Screen Shot 2014-03-12 at 11.00.12 AM

This issue is also showing up on StackOverflow now, including a more efficient temporary workaround for WordPress sites than my own hasty solution.

WordPress tip: A simple way to search all post types

I love WordPress, but its huge designer/developer community and extensible structure have made it possible to over-engineer a solution to just about every problem. And then under-document that solution.

Case in point: today I needed to add the ability to search across custom post types, along with pages. But by default search only searches posts. (That is, the “post” post type. Are you with me?)

This isn’t a new problem, even to me, although very few of the sites I build have (or need) internal search. It’s just not that useful on a site that doesn’t have hundreds of pages or posts, and most of the sites I build don’t.

In the few times in the past when I needed to be able to search across other post types, or other content like taxonomy data, I’ve relied on the Search Everything plugin. And judging by the fact that (as of today) it’s been downloaded 555,309 times, clearly I am not alone.

It’s a pretty good plugin, as plugins go. But it can be overkill, especially if all you need is the ability to search other post types.

And that’s where we run into the real, multifaceted problem with WordPress for developers: 1) there’s a plugin (no, make that dozens of plugins) for just about every obscure task, and 2) there are also several ways to go about building your own custom solution, especially if you’re building your own theme, but 3) the documentation is all over the place, and none of it is comprehensive.

Granted, by offering a targeted solution to a very specific problem in this blog post, I’m contributing to that documentation fragmentation, but whaddayagonnado.

There’s a fourth (and probably even more important) facet as well: plugins are developed independently by countless individuals (of varying degrees of skill), and it’s impossible for anyone to test them all for interoperability. The more plugins you install — especially if they’re excessively complex for the problem you’re intending to solve — the greater the chance you’ll introduce an incompatibility that will break your site. So it’s in your best interest to try to keep things as simple as possible. (And to err on the side of installing fewer plugins.)

tl;dr

If I understand correctly, every parameter in WP_Query can be passed in the query string, which means you can add corresponding input fields into searchform.php in your theme to modify the search functionality.

OK, now that was too simple (and abstract). Give me an example I can work with.

Here’s a one-line solution to get WordPress to search all of your post types (even custom post types), not just “post”-type posts. Add this into the form in searchform.php:

<input type="hidden" name="post_type" value="any" />

Guess what… you can also specify multiple specific types of posts using PHP’s method of using square brackets in your input name to pass in data as an array, like this:

<input type="hidden" name="post_type[]" value="foo" />
<input type="hidden" name="post_type[]" value="bar" />
<input type="hidden" name="post_type[]" value="baz" />

A caveat: I tried the above with page as one of the values and it didn’t work; it showed my custom post types, but not “page”-type posts. I suspect it’s because that’s one of the predefined type parameters that make the query behave slightly differently. So this solution isn’t perfect, but using any as the value will work: it gets “post”, “page” and your custom post types.

My goal was to have a simple search form that would just search all post types, so I made this a hidden field, but you could make it radio buttons, checkboxes or a select menu if you wanted to let the user pick, and this just scratches the surface of what you can do to customize your search form to leverage the capabilities of WP_Query.

How not to update a WordPress plugin

The meaning of this post’s title is twofold: 1) how, as a WordPress user, to avoid having a plugin show up in the built-in updater; and 2) how, as a developer, you probably should not approach releasing a major update to your plugin that is incompatible with earlier versions.

The scapegoat here is Elliot Condon’s excellent Advanced Custom Fields, which has become one of my essential go-to plugins for building highly customized WordPress websites for my clients. I don’t mean to pick on Elliot Condon. He’s clearly a tremendously talented developer and I have a ton of respect for his work and what it has allowed me to do in my work.

But I do feel that he handled the 4.0 release of Advanced Custom Fields poorly. I’m not sure the fault is really his, however, as it is just as much or more the fault of how the built-in updater in WordPress works. (Especially since at least some of the changes he made in version 4 were done solely to conform to changes in the official WordPress plugin requirements.)

Here’s the problem: WordPress has a central Plugin Directory that makes it easy to install and update approved plugins. Perhaps too easy. Because if an update of a plugin is made available, and it’s newer than the version you have installed, it appears as an option in the updater. Yes, there are links to information about the update, which you really should read before doing anything else, but it’s all too easy with a few clicks to just run the update and move on.

Most of the time, it just works. Which can be dangerous. Because users — even “experts” like me — come to assume it will always “just work.”

As it happens, the version 4.0 release of Advanced Custom Fields was made available while I was on a weeklong vacation out west with my family, with only my iPad (and SLP’s MacBook Air) along for the ride. And, based on my own recommendations, a client with a relatively newly-launched website went ahead and ran the update. This particular site is heavily dependent on ACF, and the update broke it.

The official ACF website offers a migration guide that makes it (somewhat) easy to convert your existing version 3 implementation to work with version 4. But it’s not a “click-it-and-you’re-done” kind of process. It takes time, and you need to know what you’re doing. Which is nothing like the general experience of using the built-in WordPress updater.

I was able to temporarily solve the problem for this website by rolling back to an earlier version (which required some hunting to locate, given the limited Internet access I had with hotel WiFi). Which leads to my first tip:

How to prevent a WordPress plugin from updating

How does WordPress know when a plugin has an update available? Well, it’s easy for it to check the Plugin Directory to see what the latest version of any given plugin is. But how does it know which version you have installed? Also easy. Each plugin’s main PHP file includes a comment block at the top, with information WordPress parses both to display in the Plugins area of the admin interface and for added functionality (e.g. knowing when there’s an update available). For Advanced Custom Fields, the comment block looks like this:

/*
Plugin Name: Advanced Custom Fields
Plugin URI: http://www.advancedcustomfields.com/
Description: Fully customise WordPress edit screens with powerful fields. Boasting a professional interface and a powerfull API, it’s a must have for any web developer working with WordPress. Field types include: Wysiwyg, text, textarea, image, file, select, checkbox, page link, post object, date picker, color picker, repeater, flexible content, gallery and more!
Version: 3.5.8.2
Author: Elliot Condon
Author URI: http://www.elliotcondon.com/
License: GPL
Copyright: Elliot Condon
*/

This is essentially a set of key/value pairs. Version is what WordPress reads to see which version you’re running, and compares it against the master version in the Plugin Directory to see if updates are available.

So how do you keep it from running the update? Simple: Change the version number to something higher. I like to prepend it with “999” so I still know what the “real” version number is that I’m running, like this: 999.3.5.8.2. This way the WordPress updater thinks the major version is “999”, which is almost certainly higher than whatever the real current version is.

Simply change this version number, save the PHP file on your server, and you’re done. The updater will never trigger for this plugin (as long as its real version number is less than 999). You may also want to update Description with an explanation of what you’ve done.

Bear in mind this is a temporary solution. You really should do whatever you need to do to get your site compatible with the latest version, then restore the original version number and let the updater do its magic.

How, as a developer, not to create this mess for your users

I have submitted a few, very simple, plugins and themes to the official WordPress repositories, so I have a bit of experience with this, but I’m no expert on the process. However, what is clear to me is that if you submit changes to a plugin as an update, the built-in updater will pick it up and make it available to any users who have an older version installed. This is dangerous. If your new version includes such radical changes as to make it incompatible with earlier versions, you have to assume that most users will not read your notes, and will believe they can just run the updater with no problems… especially if you’ve made a habit of releasing frequent incremental updates to the plugin in the past that “just worked.”

The only real solution I see to this is to submit the new, incompatible version to the Plugin Directory as an altogether new plugin, instead of an update to the existing plugin. The risk here is that you lose visibility. Your download count and ratings/reviews reset to zero, and anyone who’s using an older version may never know about the new version. So, it’s bad for marketing.

But an incompatible update breaking sites for unsuspecting users is bad for marketing too. It’s going to cause your ratings to take a hit, cause a lot of bad publicity, and turn off your loyal users. The migration is going to be work for them anyway; making them do it after they clean up a mess created when they unsuspectingly ran the update is even worse.

A few specifics as pertains to Advanced Custom Fields

Again, I don’t mean to pick on Elliot Condon for his work with Advanced Custom Fields. I will continue to be a loyal (and, yes, paid) user of this plugin. It’s brilliant. Nonetheless, it’s created a hassle for me this week. After returning from my trip, the first work-related thing I did was go through every client site that’s running ACF and apply my “version 999” trick so those clients won’t run the updater until I have a chance to migrate their sites to version 4.

The biggest challenge I had in rolling back was simply getting my hands on the old version. Sure, I had it on some of my other sites, but I access almost every client site via SSH/SFTP, and the hotel I was staying at had port 22 blocked. Luckily the site I needed to fix was one of the few I access via regular FTP, and port 21 was open. But I still needed to get a copy of version 3.x to reinstall on that client’s site.

As I found along the way, the WordPress Plugin Directory hides old versions under the “Developers” tab, where every previous version can be downloaded as a ZIP file or checked out with Subversion. Previous versions of ACF are available here.

Where’s the option to change the “uploads” path in WordPress 3.5?

Thanks for nothing, WordPress.

It’s not often that I complain about anything in WordPress, much less get genuinely angry about something I think is downright stupid, but today it happened.

I build a lot of WordPress sites for clients, and I frequently post them in a staging area on my server. Rather than having dozens of separate installations of WordPress filling up my server’s disk space, I set up a single installation (but with a separate database for each site), with some simple customizations to the wp-config.php file that tell it which database to use based on the domain name.

Please don’t bother to mention that I should “probably” be running WordPress-MU (or MultiSite or whatever they call it now). Ultimately these sites are going to be hosted elsewhere as standalone WordPress sites so I need to keep their databases separate.

One key to making this arrangement work nicely has always been the simple setting in WordPress that allows you to define a special directory for uploads, instead of dumping them all in the main uploads directory. By setting this to a subdirectory under wp-content/uploads named to match the site’s theme folder name, it was easy to keep everything separate.

It’s been a while since I’ve set up a new site on the staging server, at least since before I updated to WordPress 3.5. But I was doing one today, and I had to do a sanity check as I scoured the settings to try to find where in the hell you set the custom uploads path. I was sure it was under Settings → Media but I couldn’t find it there.

Because they took it out.

Yes, they took it out. Why? Well, apparently there’s a rational explanation, but frankly no explanation would satisfy me because it seems incredibly disruptive to take something like this out, even if it was a bad idea to implement it as it was in the first place.

Fortunately, there’s still a way to do it. You just can’t do it in the admin interface anymore; you need to edit the wp-config.php file directly to add a constant. No problem, I’m already doing that anyway.

Here’s what you need:

define('UPLOADS', '/your/custom/path/under/wordpress/root');

If you’re just putting your uploads into a subdirectory under the main uploads directory, like I am, it would look like this:

define('UPLOADS', '/wp-content/uploads/yourdirectory');

Just remember, if you’re doing this because you’re running multiple sites from a single installation like I am, this constant should be set in the same conditional where you’re setting which database the site should use.

Easy. Not as easy as it was, nor as easy as I think it should be, but…

Dr. Heckyll is his own little guinea pig…

Much like “Dr. Heckyll” in the Men at Work song, I am my own little guinea pig.

This week Facebook released an official WordPress plugin that promises deep integration. Vaguely lewd as that may sound, it’s something I need to pursue. I keep Facebook at arm’s length, but as a web developer I cannot deny that it is by far the most popular — nay, ubiquitous — social network out there. Social network integration is a big part of what my clients want with new websites, and the more we can take advantage of these kinds of tools, the more we can achieve those goals.

And so, here I am, finding myself trying out just about everything the Facebook WordPress plugin can do, right on my very own blog. Eventually I’ll probably turn off most or all of these features, but before I do that I need to find out what they do, so I know which of them are right for my clients.

Update, about 3 seconds later… I’ve already turned off the first of the “features” of the Facebook plugin: comment integration. I have already been happily using Disqus for my comments, and Facebook (unsurprisingly) doesn’t play nicely with it.