Edit Flow: This is Why We Can’t Have Nice пожитки.
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.
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.potfile with the original strings — Great,
- Do we have an
edit-flow-fr_FR.pofile and is it complete? — If we do, let’s review the translations, complete the missing ones, and create the corresponding
.mofile (if it didn’t, I’d just create a new one (from the
.potfile of originals) and translate those, compiling the
.moonce I’m done).
edit-flow-fr_FR.poback to the plugin’s
/wp-adminand voilá, a newsroom en Français!
Wait a minute…
But, but, but, PoEdit told me otherwise… :(
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
makepot.phpis a php program,
makepot.php— the actual generator, which is in my path,
wp-plugin— we need to tell
makepot.phpwhich 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.
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:
- No code ever gets committed anywhere, without running
makepot.phpas 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.
- 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)
- 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 ;)
Thanks for the critique, Ze. As a “one language American”, I really appreciate detailed perspective on how people are using Edit Flow in other languages.
Given my background, it’s really difficult for me to continuously ensure Edit Flow works against all of its translations. The best feedback mechanisms have historically been WordPress.org support threads and Github issues, but often those reports communicate breakage that will require a new release to fix.
Ideally, I’d love to have Edit Flow’s original translators at my beck and call each time I push out a new release. Typically though, they consider their contribution as a one-off and don’t have plans to stick around.
My makepot.php usage is through WordPress.org (e.g. commit to trunk and download a new POT file), so I’ll look into making it a regular part of my commit process. Translation tools would be a neat addition to WP-CLI if you want to weigh in there.
Daniel, thank you so much for the detailed reply.
I think illustrates very well a misconception that English-speaking developers tend to perpetuate, which is that localization is hard. I am seriously thinking about going into this in more detail on a separate post, but in the meantime let me try to frame the perceived problem in a way that will make it, if not disappear altogether, at the very least, diminish it to easily digestible proportions:
Very true, but the point is that this is not something you need to worry about; as long as we have a correct and current .pot file, that’s what we translators and users do, anyway. We’ll look for our language (i.e. the .po file, if it exists, if not, we create one) and make all the adaptations, completions and adjustments we need.
Again, no need; It is most definitely not your responsibility to provide us with a complete and current translation, nor are we expecting that. Most often than not, and if you do supply a translation, we’ll still peek into the file to see if it is correct and complete.
I would strongly advise to look into automating all of this, before you commit. I mentioned the Grunt plugin in the post, simply because I myself use Grunt. There are probably other ways to do this (beginning with a basic cron). I am still a little in awe of WP-CLI, but I’ll make sure to stop by and see if I can suggest an extension to it that would make the process simpler.
One a final note, regarding the translations we tweak, locally, isolated from others: I cannot stress enough the importance of sharing translations on a collaborative platform: not only does it incite discussion and continuous refinement, but it also transfers a significant part of the burden of managing dozens of .po files, right back to the translators, freeing the developer to do what he does best.
All that said, I am very excited to see that a burgeoning and serious debate on the issues of internationalization and localization. Thank you again for weighing in.