Hijacking WordPress Internationalisation

As part of a new feature I am developing for the next release of my Welcome Pack plugin for BuddyPress, I needed a really smart way of dynamically adding my own translations for strings at page-load time; creating a stand-alone .mo file to load the strings wasn’t a great solution, for reasons of requiring people to know how to configure file permissions on the server, having to figure out how to write a .mo file (I wish they were as easy as XML, but they aren’t), and — honestly — doing it that way feels like such a hack.

Here’s how. Be warned that this will overwrite any translation loaded by a .mo file, but that’s exactly what I needed to do.

To add a new string into the localisation table:

function example() {
global $l10n;

$mo = new MO();
$mo->add_entry( array( 'singular' => 'Spongebob', 'translations' => array( 'Squarepants' ) ) );
if ( isset( $l10n['buddypress'] ) )  //buddypress is the textdomain
$mo->merge_with( $l10n['buddypress'] );

$l10n['buddypress'] = &$mo;
}

_e( 'Spongebob', 'buddypress' );  // This will return "Squarepants".

To change an existing string:

function example() {
global $l10n;

if ( isset( $l10n['buddypress'] ) && isset( $l10n['buddypress']->entries['%s posted an update:'] ) )
$l10n['buddypress']->entries['%s posted an update:']->translations[0] = '%s posted a monkey:';
}

Post a comment if you use this technique for anything interesting

3 thoughts on “Hijacking WordPress Internationalisation

  1. Hey Paul,

    Was meaning to reply to this the other day, but got sidetracked!
    Just tried it and it does what I want it to do, except for one instance.

    I’m trying to override a string that BP uses on an AJAX request (in my case, when a private message is sent, BP outputs a message).

    I’ve tried overriding the string by hooking into the “init” action, but not sure if this is the correct action I should be hooking into.

    Here’s the full function:


    function ray_override_l10n() {
    global $l10n;

    $mo = new MO();

    $l10n['buddypress'] = &$mo;

    if ( isset( $l10n['buddypress'] ) ) {
    $l10n['buddypress']->entries['There was an error sending that message, please try again']->translations[0] = 'You are not friends with the person(s) you are attempting to send a message to. Your message has not been sent.';

    $l10n['buddypress']->entries['There was a problem sending that reply. Please try again.']->translations[0] = 'You are not friends with the person(s) you are attempting to send a message to. Your message has not been sent.';
    }
    }
    add_action( 'init', 'ray_override_l10n' );

    Any ideas?

    Like

    1. For Welcome Pack’s email feature, I use the above technique and have it hooked in like so:

      add_action( 'init', 'dpw_load_dynamic_i18n', 9 );

      Have a look dpw_load_dynamic_i18n() in Welcome Pack’s core.php. It is a bit hard to read as there’s a pair of nested FOR loops, but would suggest you use MO->add_entry() etc rather than write directly to the arrays. I think I switched to doing that after I wrote the above post.

      Like

  2. Paul, thanks for the moment of clarity!
    Of course it has to do with setting the priority for the init action! *slaps head*

    Thanks also for the add_entry() tidbit, I’ll look into that!

    Like

Comments are closed.