Translate Dynamic Strings in WordPress

Translate Dynamic Strings in WordPress

Sometimes it can be quite challenging to translate dynamic strings in WordPress. And this is for two main reasons:

  • they come from a plugin or theme that is not using gettext for their strings;
  • they are user-created and saved in the plugin or theme options, in user meta, or in a custom table the translation plugin doesn’t know about.

Themes like Hestia make use of the WordPress Customizer interface to quickly build a beautiful front page containing a slider, various columns for information, a list of WooCommerce products if it’s needed as well as a contact form.

A lot of content from that front page is not stored in the wp_posts or wp_postmeta. While some will voice concerns over why breaking the post/page convention is a bad idea, I personally like how smooth the experience of setting up that initial page was. 

This flexibility is great when you want to do things your way, however, it’s also the main reason translating a WordPress site 100% can be a little harder to achieve, especially if you’re not a very technical person.

Current Solutions

WPML String Translation Interface
WPML String Translation Interface

Each WordPress translation plugin has its own workflow when translating dynamic strings.

  • gettext strings are translated per plugin/theme or directly from;
  • user-generated strings from the plugin/theme need to be marked for translation using the translation’s plugin API.

The good thing about this solution is that it works.

The bad thing is that the translation happens out of context and needs support from plugin and theme developers to work with a variety of translation plugins.

The worst thing about this is that if plugin and theme developers don’t support the translation plugin, it just won’t work at all.

Translate Dynamic Strings with TranslatePress

We knew translating dynamic strings will be a challenge when we started development for TranslatePress. What we considered complicated turned out to be a lot more complicated once we actually started working on the problem.

What we considered complicated turned out to be a lot more complicated.

To make it possible to translate both gettext fields and dynamic strings added by users we implemented a more straightforward interaction:

  • if a plugin or theme was already localized, we’ll keep the translation but you can still change it if you’re not ok with it;
  • strings that are stored in the options table and outputted to the front-end can easily be translated, so no more searching in a complex string translation table;
  • you’re using the same interface to translate all the strings on your site.
dynamic string translation

A Look Into the Quirks and Features

Since gettext-added fields differ from normal strings, there are small but noticeable differences between them.


We’ll start off with %1$s. These represent dynamic variables that depend on the current user, number of purchases, plugin settings, etc.

This is the proper way to translate these strings and as a bonus, if the plugin is already translated in a particular language, we’ll also populate those fields with the correct translation.

Original String

gettext implementation doesn’t allow you to define in what language the strings are. So if you’re a plugin developer from France, you’re free to develop your plugin in French. That’s why you’ll see the “Original String” and all the languages under it. Even English.  Strings that we can detect are highlighted using the green edit button.

A cool little side-effect is that you can even change the default string by “translating” into English for example.

An unfortunate side-effect is that it’s different from the Original Language Translated Language workflow we have available for normal strings. So you need to pay a bit more attention to what language you’re translating until we find a better way of representing this in the interface.

Hidden Strings

Gettext strings that are added with Javascript, as well as other strings that are not visible on the front end of the site (like WooCommerce emails or URL slugs for example) can be accessed from the String Translation interface. This way you can translate content that is not accessible from the Visual Editor.

And finally, there are specific workflows (let’s say a form is displayed only for non-logged-in users, so as an administrator you don’t see it) that won’t expose those strings, so you can’t translate them. Using the Browse as Role add-on you can browse the website from the translation editor as yourself or any other role (logged in) or as a non-logged-in user. This way you’ll be able to translate strings that are dynamically displayed based on the logged-in/non-logged-in status.

If you’re curious to see more, here’s a short video on how to translate any type of dynamic or variable content with TranslatePress:

TranslatePress Makes it Easy to Translate All Dynamic Strings

You can download TranslatePress for free at It was built to make it really easy for you to handle dynamic strings translation and turn your site multilingual.

Download it, play with it and tell us what you need to make your experience translating a WordPress site that much better.

If you’re happy with it, you might consider upgrading to the premium version for unlimited languages, advanced SEO features, and more.

TranslatePress Multilingual

TranslatePress is the easiest way to translate your WordPress site. It's fast, won't slow down your website, works with ANY theme or plugin and it's SEO friendly.

Get the plugin

Or download FREE version

A big Thank You to all our beta-testers and Ionuț Neagu from CodeinWP for their initial feedback.

Do you still have questions about how to translate dynamic strings? Let us know in the comments section below!

If you found this post helpful, please check out our YouTube channel, where we constantly upload short & easy-to-follow video tutorials. You can also follow us on Facebook and Twitter to be the first to know each time we post.

One thought on “Translate Dynamic Strings in WordPress

Leave a Reply

Your email address will not be published. Required fields are marked *