Edit Flow: This is Why We Can’t Have Nice пожитки.

Posted by in i18n, Plugins

Edit Flow is a fantastic plugin: it basically turns a standard WordPress installation into a newsroom, with complete control of the editorial workflow. As far as code quality is concerned, it is enough to say that it is prominently featured as one of the recommend plugins on WordPress.com’s VIP service, and that the WordPress.com VIP team itself contributes to the development of the plugin.

I’ve gladly used a few times in the past, and have nothing but praise for the superior and elegant way it’s implemented.

Well, almost.

You see, up to now, I’ve only used it on sites whose content is in English; however, now that I’ve recommended Edit Flow for a new project I’m consulting on (a very large WordPress installation for on-line news that are not in English), my troubles began. Granted, for a normal, admin-only plugin, those troubles could be ascribed to the chapter of “not a big headache, none of it is front-facing, visitors aren’t aware of its presence”, but in this case there is a significant difference: editors and journalists. These are people whose job is to prepare and edit content, and whose command of the English language, unlike that of their own, is most definitely not a requirement. In other words, they need their tools to work, and as much as possible out of their faces, so that they can focus on what matters: content. Again, that’s content that’s not in English, and which (as expected in a newsroom) is heavily transacted in WordPress’ admin area. tl;dr: the plugin’s interface needs to be in, say, French.

That’s when we discovered some localization issues. It was a dark and stormy night.

Je ne regrette rien

Here’s what I did (and if you didn’t know, what every translator more or less usually does):

  • Install the plugin
  • Check for a plugin-slug.pot file with the original strings — Great, edit-flow.pot is there
  • Do we have an edit-flow-fr_FR.po file and is it complete? — If we do, let’s review the translations, complete the missing ones, and create the corresponding .mo file (if it didn’t, I’d just create a new one (from the .pot file of originals) and translate those, compiling the .mo once I’m done).
  • Save edit-flow-fr_FR.po and edit-flow-fr_FR.po back to the plugin’s /languages folder
  • Reload /wp-admin and voilá, a newsroom en Français!

Wait a minute…


Et merde…


But, but, but, PoEdit told me otherwise… 🙁

Screen Shot 2014-02-20 at 17.05.57

Hmmm… I think I know what may be happening, which is that the supplied .PO file doesn’t match the originals’ .POT file. No problem, I’ll just do a Catalog → Update from POT file.. → Choose edit-flow.pot, in PoEdit. Aha, it looks like I was right: 34 new strings and 4 obsolete ones.

Ooook then, it looks like I just need to translate the new strings. At least, that’s what a normal user would do, assuming that normal users are actually aware of the whole process described above, and I am willing to bet that 90% of them are not. For the remaining 10%, to verify that the translations do match the originals, has become a standard, annoying step, particularly so when the potential for automation on the developer’s side could easily make it unnecessary. More about that further ahead.

Balayés pour toujours, je repars à zéro

Since I think of myself as belonging to the 10% who want to be absolutely sure that everything is as it should be, I usually add in another step, just for fun: let’s see if the .POT file (containing the original strings) does indeed reflect all strings used in the code: I use makepot.php, which I’ve checked out from the i18n tools repository to my machine, but you can do this in a number of ways, among which are using raw gettext commands on the command-line (which is mind-blowingly geeky), to using PoEdit’s Catalog → Update From Sources… option. I use it this way:

php makepot.php wp-plugin . languages/new-edit-flow.pot


  • php — because makepot.php is a php program,
  • makepot.php — the actual generator, which is in my path,
  • wp-plugin — we need to tell makepot.php which strain it should grow,
  • . — the current folder, which is Edit Flow’s root folder,
  • languages/new-edit-flow.pot — the output file, in this case “new-…”, because I want to see if there are differences between the generated file and the existing one.

The command has run, new-edit-flow.pot has been generated, lets compare them.


Screen Shot 2014-02-20 at 17.49.46

(Sample) on the left, the supplied .POT. On the right the newly generated one.


Well, that’s not going to work, is it? Now I’ll have to replace the old .POT with the one I’ve generated, do a a Catalog → Update from POT file.. → Choose edit-flow.pot in PoEdit, again, and finish the translation. Only now do I have the assurance that everything’s translated as it should.

Not the end of the world, but let us now put all of this in the perspective of a normal (ish) user:

  • The vast majority of users will assume that a supplied translation is correct, or at the very least complete, especially when the plugin’s changelog announces updated or new translations. Little do they know that this is almost never the case.
  • They won’t bother with all the steps above, except maybe for tweaking and completing an existing file (and they certainly won’t know or care about .POT files, whether updated or not).
  • If their language doesn’t exist, they may create it (based on an outdated .POT file), but have no way of giving that back to the developer, for the currently released version. It’ll always be for the next, which means, yes, outdated. Again, we’re talking about normal (ish) users, not people who know or care about svn or git.
  • They may very well and simply abandon the plugin, or use it in English, or even worse in their language with some English strings, providing a less than optimal experience.

These are just a few of the issues that I see happening over and over again. It’s frustrating because the fix is easy, implies close to zero extra work from the developer, and yet the vast majority of them simply ignore it, injecting .POTs and translations, as a mere afterthought.

Aujourd’hui, ça commence avec toi

It really is simple on the development side, if you keep these principles in mind:

  1. No code ever gets committed anywhere, without running  makepot.php as the last step, to generate a correct and synced .POT file. Ever. As in never, ever, anywhere — cron it, run it manually, add it to your  Gruntfile.js, whatever. You are a developer; I’m sure you can figure out a way to automate it. After all, automating things is what got you into programming to begin with, right? Remember: never, ever, anywhere.
  2. In an ideal world, .po files match the shiny new synced .pot file. I grant you that this is probably a little trickier, especially if you have a more than a couple of translations (hint: it would probably mean automating a gettext msgmerge command, which is not for the faint of heart). Alternatively, you can simply instruct your users to update their respective language’s .po files with the new originals (see above for how to do that in PoEdit)
  3. Find a way to let users collaboratively and publicly work on, and download updated translations: installing your own GlotPress, or using WP Translations are very popular options, just ask Mike.

A final note

As mentioned before, I have the utmost respect and admiration for the work that was put into Edit Flow. I will still, obviously, continue to use it and recommend it; nothing else comes even close to how useful it is. It is precisely because of that that I’ve allowed myself to write the above post. I hope it isn’t taken the wrong way. By the way, yes, I have really generated a new, correct .POT, am in the process of finishing the translation and the plugin will shine (it already does) as a deciding argument for moving the new site and its dozens of contributors, from an archaic, custom CMS to a shiny new WordPress installation.

And a post-scriptum, for Dre and Brad, because Im still not sure that that confusion has been dissipated: you, as a developer, are not required to supply any translations. We translators do that, for free, as long as you give us the proper material to work on 😉