Plugin updates and translation lessons

I can think of many excuses to explain why I’d, until recently, neglected my WordPress plugins. For some time now, I’ve only set aside time to bump their WordPress-version compatibility and respond to the occasional support thread. As my plugins’ users may have recently noticed, this has changed. I added block-editor (Gutenberg) support to both External Permalinks Redux and WP Revisions Control. I also fixed all of my actively-maintained plugins so that they can be translated through translate.wordpress.org. Today I’m revisiting a plugin, Automatically Paginate Posts, that I have ignored for more than two years; it requires some serious revisions to make it compatible with the block editor, and now feels like the right time to undertake that effort.

One interesting discovery that came from fixing my plugins’ support for translations was the realization that, while I thought I’d done everything correctly, I’d actually overlooked several key details. I was diligent about wrapping all user-facing strings in appropriate translation functions, and I’d followed best practices for building strings in ways that made them translatable as a whole (rather than concatenating translated chunks), but I hadn’t chosen proper text domains nor had I called all of the functions required to apply available translations.

Lessons Learned

Error message shown when a plugin is not properly prepared for translation
  1. If your plugin supports WordPress versions older than 4.0, both the Text Domain plugin header and a call to load_plugin_textdomain() are required.
  2. If your plugin includes a block-editor component that contains translatable strings, a call to wp_set_script_translations() is required.
  3. The plugin’s text domain must match its slug on WordPress.org if you wish to allow the community to submit translations that aren’t bundled with the plugin itself.

There’s a lengthy documentation page that covers all of the above and more: https://developer.wordpress.org/plugins/internationalization/how-to-internationalize-your-plugin/. I should’ve paid closer attention to it.

Supporting My Plugins

If you find any of my plugins beneficial and would like to support my development efforts, please visit my donation page for links to various ways to provide financial support.

Were it not for Nick Bradbury’s HomeSite, I probably couldn’t have written this

Perhaps like many starting out with HTML, myriad aspects of the syntax were confusing, or downright overwhelming. For me, tables were one example of the latter. Despite their prevalence at the time (1995), their structure was something I struggled to understand.

Fortunately, one of the many amazing features of HomeSite was its table editor. The visual interface made it easy to create tables and set various attributes. Toying with that GUI helped me correlate what I saw there with the markup it produced.

That ability to experiment and connect changes to their output was essential for me to become familiar with HTML. With no formal training, meager search engines (Google didn’t yet exist), and documentation beyond my understanding, I had no way to learn but to change things and test those effects.

Thanks to the experimentation that HomeSite afforded me, I learned HTML, began hosting my own sites, and in 1999, encountered PHP. Had I abandoned web development out of frustration with learning the early syntax, there’s no chance I could’ve returned to programming as a career when the recession hit in 2009.

Who knows, maybe I’d still be an accountant?

Strebel’s interview with Alex King, from PressNomics 4

Today at PressNomics 4, Josh Strebel shared an interview he did with Alex King back in September, just ten days before Alex passed following a long fight with cancer.

It’s both incredible to me, and simultaneously unsurprising, that Alex took the time to record this interview given how sick he was at the time–one final contribution to a community he was so important to and engaged with.

Hello PHP 7!

With relatively little difficulty, I’m now running PHP 7 alongside PHP 5.6. PHP 7 was released at the beginning of the month, and WordPress was one of the platforms tested against. Given that I can’t stop tinkering with this server’s configuration, I really had no excuse not to set up PHP 7.

Given the myriad services I’m running, I couldn’t switch to PHP 7 outright. While WordPress and YOURLS (powering my url shortener, eth.pw) both support PHP 7, the compatibility list basically ended there.

As I went into this with a fair bit of trepidation (and many backups), what follows is a bit about my experience.

Continue reading Hello PHP 7!

Redis Object Cache for WordPress, the Accidental Effect of PHP 5.5

Last week, I went a little upgrade-crazy with the VPS that hosts this site. With SPDY 3.1 support in nginx 1.5, I upgraded. I also bumped PHP from 5.4 to 5.5.

The latter change is significant because PHP 5.5 drops support for APC, and I was using APC for both opcode caching at the PHP level and object caching at the WordPress level (thanks to Jaquith’s plugin). Since I’d lost my object cache, I’d also lost my page cache because I was using Batcache. Nice job, Erick.

Almost a year ago, I contributed two small changes to Eric Mann’s WordPress Redis Backend plugin. With Redis already running on my VPS for reasons unrelated to WordPress, it seemed an obvious choice over competing persistent caching options.

I spent some time updating Eric’s plugin (see https://github.com/ethitter/wordpress-redis-backend/commits/master for the fun I’ve had) and sent a massive pull request back with my changes. I’ve been using the plugin for a few days now without incident, though I wouldn’t rush to switch over just yet unless you’re adventurous. I’d watch Eric’s repo if you’re interested in what comes of my efforts.

Disable Jetpack’s Photon module in specific situations

I receive a lot of interesting questions about the Photon module in Jetpack. Occasionally, users would like to disable Photon for certain requests, such as when a plugin or theme calls one of WordPress’s image functions (wp_get_attachment_image(), wp_get_attachment_image_src(), or anything else that ultimately calls image_downsize()).

While the Photon module does include filters to disable it for each individual image requested (see here and here), there are situations where one may wish to disable Photon regardless of the image being requested, such as when a certain widget retrieves an image from WordPress’s media library.

Doing so is relatively simple, but a bit obfuscated because the Photon module is written as a PHP class. The snippet below demonstrates how to do so, and is made possible because the Photon module is implemented as a singleton.

$photon_removed = remove_filter( 'image_downsize', array( Jetpack_Photon::instance(), 'filter_image_downsize' ) );
// Call wp_get_attachment_image(), wp_get_attachment_image_src(), or anything else that ultimately calls image_downsize()
if ( $photon_removed ) {
	add_filter( 'image_downsize', array( Jetpack_Photon::instance(), 'filter_image_downsize' ), 10, 3 );
}

The code on line 1 should appear immediately before the function call that shouldn’t have Photon applied, and lines 5 and 6 should appear immediately afterwards to ensure that Photon is available for any subsequent calls to image functions.

Grab the snippet from https://git.ethitter.com/snippets/1.

Aside – if you’re curious about using singletons in WordPress, check out Eric Mann’s post on the subject: The Case for Singletons in WordPress.

Using shortlinks with Jetpack Sharing

At present, Jetpack doesn’t use shortlinks when visitors share your content through the built-in Sharing module. With length-limited services like Twitter, this can be a problem. Take, for example, http://ethitter.com/2013/05/using-shortlinks-with-jetpack-sharing/ versus http://eth.pw/s; the latter frees up many more precious characters.

Thankfully, the folks who built the Sharing module provided a filter to override the link used with the sharing buttons.

Add this snippet of code to your theme’s functions.php file, or a file in your site’s wp-content/mu-plugins directory, and your visitors will be sharing with shortlinks in no time.

/**
 * Force Jetpack's Sharing module to use a shortlink rather than full permalink
 *
 * From http://eth.pw/s
 *
 * @param string $url
 * @param int $post_id
 * @uses wp_get_shortlink
 * @filter sharing_permalink
 * @return string
 */
function eth_sharedaddy_shortlink( $url, $post_id ) {
	return wp_get_shortlink( $post_id );
}
add_filter( 'sharing_permalink', 'eth_sharedaddy_shortlink', 10, 2 );

Note that the Publicize module, which handles automatically sharing your content to your own connected social media accounts, does use shortlinks already; therefore, the code snippet above won’t have any impact on Publicize.

Also, I opted not to make this a plugin in anticipation of Jetpack making the switch to shortlinks at some point.