Accessing WordPress localization during plugin activation

Accessing WordPress translation capabilities out of the normal flow.

Translations please

I need some localized strings during the activation of a plugin.
Since the plugin is not activated yet the customary localization on the init hook will not happen during the plugin activation request handling: any localization attempt will fail returning the original string.
In this specific case, in the User Groups Content Restriction plugin, I’m trying to insert some default terms

// in the main plugin class

public static function activate() {
    ugcr_TermManager::instance()->remove_terms();
    ugcr_TermManager::instance()->insert_terms();
}

The method of the code in charge of that

// in the ugcr_TermManager class

public function insert_terms() {
    // Register taxonomies to avoid errors
    register_taxonomy( ugcr_Plugin::$taxonomy_name, null );
    register_taxonomy( ugcr_Plugin::$post_taxonomy_name, null );

    // Get default terms with localized names...
    $terms          = $this->get_additional_terms();

    // ...insert terms and so on...
}

is using an helper method to insert the default terms with localized names

public function get_additional_terms() {
    return array(
        array(
            'slug' => 'logged-in',
            'name' => __( 'Logged-in users', 'ugcr' )
        ),
        array(
            'slug' => 'visitor',
            'name' => __( 'Visitors', 'ugcr' )
        )
    );
}

Manually loading a required text domain

Hacking the flow and manually loading the required localization file is not a big lift and WordPress will graciously lend itself to it.
Modifying the insert_terms method will fix non working translations

public function insert_terms() {
    // In need of translated strings now...
    global $l10n;
    $l10n = is_array($l10n) ? $l10n : array();
    $languages_dir =  dirname( dirname( __FILE__ ) ) . '/languages/';
    $mo_file = 'ugcr-' . get_locale() . '.mo';
    load_textdomain( 'ugcr', $dir . $file );

    // Register taxonomies to avoid errors
    register_taxonomy( ugcr_Plugin::$taxonomy_name, null );
    register_taxonomy( ugcr_Plugin::$post_taxonomy_name, null );

    $terms          = $this->get_additional_terms();

    // ...insert terms and so on...
}

WordPress will take care, under the hood, to handle non existing localization files or strings as usual.

Other ways?

Option

I think the above operation should happen during activation but another way would have been to hook the term insertion on the shutdown method behind an option toggle like

// the main plugin class will register its hooks here
public function hooks() {
    add_action( 'init', array( $this, 'localization_init' ) );
    add_action( 'init', array( $this, 'register_taxonomy' ) );
    add_action('init', array(ugcr_TermManager::instance(), 'insert_terms'));
} 

// in the ugcr_TermManager class

public function insert_terms() {
    $version = 1;
    if(get_option('ugcr_did_insert_terms', 0) >= $version){
        return;
    }

    // Get default terms with localized names...
    $terms          = $this->get_additional_terms();

    // ...insert terms and so on...

    // update the option
    update_option('ugcr_did_insert_terms', $version);
}

What I do not like about this approach is that it does not feel less hacky to me and runs on each page load.

Cron

Another option is a cron job

// in the main plugin class

public static function activate() {
    ugcr_TermManager::instance()->remove_terms();
    ugcr_TermManager::instance()->insert_terms();

    wp_schedule_single_event(time() + 10, 'ugcr_first_run');
}

// the main plugin class will register its hooks here
public function hooks() {
    add_action( 'init', array( $this, 'localization_init' ) );
    add_action( 'init', array( $this, 'register_taxonomy' ) );
    add_action('ugcr_first_run', array(ugcr_TermManager::instance(), 'insert_terms'));
} 

This is a more elegant solution but still I feel like an initialization task should not leave traces in the normal plugin flow.
Personal taste in the end.

2 thoughts on “Accessing WordPress localization during plugin activation

  1. If you need to localize software, Luca, take my advice and check out the software translation platform https://poeditor.com/
    It’s a great l10n service, especially useful if you want to translate apps and websites in a team, and you can use it for crowdsourcing translation campaigns too.

    For WP, there’s a special WordPress translation plugin: https://wordpress.org/plugins/poeditor/
    You can use this plugin to connect your WP site to the POEditor software localization platform and send the strings in your PO files to the platform and then back to your site, when they’re translated.

    1. Thanks for the information, I know it already but it might prove useful to someone else.
      The issue in the post was not the translation itself as much as getting hold of it.

I appreciate your input