There’s a lot of awesome things going on in the WordPress land. This CMS is just a brilliant ecosystem and more and more devs jumping on the bandwagon. Still, there are basic things – call them standard – which aren’t addressed with the attention they’d actually need. And there’s this need, definitely. Read on, about some nightmares I’ve seen within WordPress code broken down to seven cardinal sins regarding the localizing/internationalization of WordPress plugins and themes.
1.) Not Localizing At All
You got it. This is the biggest sin at all. In the last months I’ve seen SO MANY themes and plugins – including from big premium theme/plugin shops – that were not translateable at all. Or even if they’ve tried to implement localizing they’ve failed at it big time. Yes, I speak of some of the so-called premium elite of WordPress developers. It’s surprising but it’s a reality.
Localizing your plugin or theme is NOT an option. It is a decision BEFORE you even begin to write the first line of code. Not thinking about the majority of your future users will also effect your future sales. The majority of all WordPress users worldwide does NOT speak any English. No matter if they use self-hosted or hosted taste of WP.
Don’t do international users „a little benefit“, just make your coded work useful at all for them. You can come up with the greatest feature set, the most awesome design or an impressive UI. As long as your product cannot be translated it’s not half worth it!
Implementing of Gettext is not a WordPress thing at all. Gettext is a PHP feature/function and you should use it. It belongs to proper coding standards. So, learning this little Gettext syntax should be a developer standard not an add-on.
Having all strings in your own language is not an option, it’s part of the natural user experience from the beginning. Come on, just do it.
2.) No Loading of The Textdomain
Oh, this is a big one. Biggest error – should I say fail? – I’ve seen so far! This function has to be loaded at all AND at first, before anything else. Reason? Strings will effect anything also your error messages and other user notifications. If you load the translated strings somewhere in the middle it’s almost sure your users will miss something important before!
The proper WordPress functions for loading the textdomains are:
For Themes/ Parent Themes/ Frameworks:
For Child Themes:
These go just after the plugin’s header info or in your theme’s functions.php just as the first function. Period.
Just implement these with the correct parameters. Yes, it’s that easy.
And please create a folder for the translations by default. Most popular use is
/languages/ in the first level hierarchy of your plugin or theme folder. Please create it even if it’s empty at first. If this folder is there users later can add their language packs here and all gets loaded out of the box. This way you’ll make your users happy once again.
3.) No Textdomain Attached to the Gettext Strings
Another frustrating one: they’ve implemented the loading call for the textdomain, they did Gettext strings but no textdomain in the end. Maybe because WordPress itself has no textdomain attached? Don’t know yet.
WordPress itself knows its stuff and gets it loaded. In this post here, I am speaking of plugins and themes which are add-ons for WordPress and therefore need some other handling so WordPress can determine a difference from its core files/strings.
So, please, please, please add ONE UNIQUE textdomain to ALL your strings. It’s no magic. So if your plugin’s folder path name is
foo-test-plugin and it’s proper Name is
"Foo Test Plugin" and it has 587 strings to translate your textdomain will most definitely be named
'foo-test-plugin' and all in all we will have 587 appearances of this domain – at each and every string. No exception.
4.) Using A Constant As Textdomain
Some developers think they’re the most clever WP devs out there. Nah, they aren’t. Using of constants in many cases leads to NON-displayed translated strings because they implemented it all the wrong way. To me as a translator and user it just seems they wanted to re-implement the whole loading functions WordPress itself just provides as API/ functions for the developers. WordPress core provides all you need, just USE it as it will make your work easy and gets proper results for your end users.
Don’t re-implement things here and there WordPress has already APIs for! Don’t get too clever, just don’t use any constants for localizing things, use a proper textdomain which itself is a regular string. And, it all goes in single quotes.
The wrong example seen so often:
__( 'Foo text', TOO_CLEVER_DEV_CONSTANT );
The right way – use that:
__( 'Foo text', 'foo-test-plugin' );
This is such a little „mistake“ a lot of coders make but with huge impact. It’s surprising sometimes people think they have to do more clever than going the REAL clever way and making it easy, simple and beautiful. Code is poetry – at least regarding the localization and textdomains. Constant is no poetry in this case…
FYI, Mark Jaquith, WordPress core developer, has spoken out on the constants issue a lot better than I could do, so, go and read his article too!
5.) Mixing of Double and Single Quotes in Gettext Strings/ Textdomains
This is a bit more special and it is more tricky. Some devs mixing up double and single quotes in Gettext calls. This ist NOT recommended as it can lead to crazy things. I’ve had themes with such implemented strings and widgets got no longer displayed on the frontend because something was blocked. As of my experience, my own coding and testing the using of single quotes in the whole thing is the best practice and would lead to correct results.
The wrong example seen a lot of times:
__( "Foo text", 'foo-test-plugin' );
The right way – use that:
__( 'Foo text', 'foo-test-plugin' );
6.) Not ONE Unique Textdomains but A Lot of Them…
This one is spreaded like a virus already… I’ve seen plugins with seven (yes, 7!) different textdomains. Whoa! This is not poetry in the code, this is waste of time and end users get these not displayed properly in THEIR language. So, just use ONE, and I say only ONE textdomain for all your strings. Please test it!
So why is this really important? In almost all cases the only textdomain that will lead to diplayed results is the defined textdomain in the loading call! So when you load ‘foo-test-plugin’ in your call at the beginning you cannot add a textdomain like ‘clever-test-plugin’ to any of your strings. In most circumstances this particularly string will NOT get displayed in the translated language.
To test and verify that you only have one domain in use just use the awesome plugin „Codestyling Localization“. It has an in-built counter and drop-down menu for choosing which string has which domain. So do yourself a favor, install that plugin in your sandbox install and look at your plugin or theme as a real clever dev – with the international user in mind.
Count all „third-party“ textdomains in your plugin or theme down to ZERO! Do not release anything before this task! You’ll make translators and users even more happy!
7.) Not Localizing ALL Strings
Yeah, it happens to all of us. We tend to forget some things sometimes. So is with localizing strings. No problem, release an update of your work after you’ve added Gettext strings to all remaining contents/texts of your plugin or theme.
I mean each and every word or „syntax“ of your plugin and theme. Make it ALL translateable. To test and verify this just set the locale of your test install to something different than English – most definitely to a language where there’s already a completely translated language file available. Install this language pack and look at your plugin or theme if you still see any English you definitely forgot something to localize. Don’t release your work if not all is translateable. Otherwise you and your translators have to update very often and that is more time consuming in the end than some more testing before.
And did I mention it already, help texts, error messages, notifications and even your promotional info and links about your plugin in the backend – it all should be translateable. Especially properly translated help texts and user guidance is very important for your users as to some of them this will be the only documentation/ help/ info within your work. So if you want YOUR HARD WORK getting used please make it accessable for as many users as you could.
With localizing you might not get the most applause at the beginning. But in the long run you will succeed if you do the heavy lifting right from the start. Correct localizing is getting more and more an important factor to get your premium plugins or themes sold and also for free work to get more users, downloads and even user feedback.
Localizing your stuff is absolutely worth it. Getting in touch with your users and give them the best possible user experience. This is the real clever way and it’s win/win in the end. So just think twice.
Happy localizing :)
Dave, some WordPress translator from Germany
P.S. You can blame me for my bad English of course but these things were on my heart for a long time and had to be pointed out finally.
Please join in with your comments and experiences – happy discussion ;-)