Implementing conditional gettext translation

I have added a message button on my site (I’m using a plugin which enables private messaging) by adding the plugin’s shortcode to my footer.php:

<div class="msgshort"><?php echo do_shortcode('[ultimatemember_message_button user_id=1]'); ?></div>

Here is a screenshot of how it looks on my site: https://ibb.co/hLTkmQ

Here is the code behind this shortcode:

/***
*** @shortcode
***/
function ultimatemember_message_button( $args = array() ) {
    global $ultimatemember, $um_messaging;

    $defaults = array(
        'user_id' => 0
    );
    $args = wp_parse_args( $args, $defaults );
    extract( $args );

    $current_url = $ultimatemember->permalinks->get_current_url();

    if( um_get_core_page('user') ){
        do_action("um_messaging_button_in_profile", $current_url, $user_id );
    }

    if ( !is_user_logged_in() ) {
        $redirect = um_get_core_page('login');
        $redirect = add_query_arg('redirect_to', $current_url, $redirect );
        $btn = '<a href="' . $redirect . '" class="um-login-to-msg-btn um-message-btn um-button" data-message_to="'.$user_id.'">'. __('Message','um-messaging'). '</a>';
        return $btn;
    } else if ( $user_id != get_current_user_id() ) {

        if ( $um_messaging->api->can_message( $user_id ) ) {
            $btn = '<a href="#" class="um-message-btn um-button" data-message_to="'.$user_id.'"><span>'. __('Message','um-messaging'). '</span></a>';
            return $btn;
        }

    }

}

This button is coded so that the button text is “Message”. This button already appears on my user profile pages, but now that I have also added it to my footer I want to change the text that says “Message” in my footer but not when on the user profile template area.

So, I am using this code to rename the text of the message button on my site:

//rename messagetxt
function um_rename_messagetxt( $translated_text, $text, $text_domain ) {
if ( 'Message' === $text ) {
       $translated_text = 'Contact Us';
}
return $translated_text;
}

add_filter ( 'gettext', 'um_rename_messagetxt', 10, 3);

Of course, this changes the button text for all of my buttons that say originally say “Message” (so both the footer.php message button I added with the shortcode and the message button in the user profile template changes).

I just need to change the text for the button that I added via shortcode into my footer.php file. How can I isolate the text translation so that I am only translating the text of a specific element? For instance, is there a way I can only translate “Message” when it’s found in footer.php and if so, how would I write it? I would really appreciate any help on this!

Side note: I am a premium member of this plugin and have already contacted their paid support, which they have said they weren’t sure about how to do this and directed me to use Poedit… I don’t think Poedit is an appropriate solution for this. Thanks so much to Dave Romsey who has tried to help me despite my php skill deficit 🙂

Solutions Collecting From Web of "Implementing conditional gettext translation"

WordPress provides the _x() function which is just like __(), but it adds the $context parameter which is used to differentiate between identical strings.

In the example below, some output is generated in the footer. The translatable string is Message is used in both cases, but in the first instance, Message is given the context for use in footer text.

Next, we use the gettext_with_context and gettext filters respectively to translate each of the strings independently.

// Generate output for our example.
add_action( 'wp_footer', 'wpse_example_strings' );
function wpse_example_strings() {
    // Note that concatenating strings is not translation friendly. It's done here for simplicity.
    echo 'Message string with context: ' . _x( 'Message', 'for use in footer text', 'text_domain' ) . '<br>';
    echo 'Message string without context: ' . __( 'Message', 'text_domain' ) . '<br>';
}

/**
 * Translate text with context.
 *
 * https://codex.wordpress.org/Plugin_API/Filter_Reference/gettext_with_context
 *
 * @param string $translation  Translated text.
 * @param string $text         Text to translate.
 * @param string $context      Context information for the translators.
 * @param string $domain       Text domain. Unique identifier for retrieving translated strings.
 *
 * @return string
 */
add_filter( 'gettext_with_context', 'wpse_gettext_with_context', 10, 4 );
function wpse_gettext_with_context( $translation, $text, $context, $domain ) {
    if ( 'text_domain' === $domain ) {
        if ( 'Message' === $text && 'for use in footer text' === $context ) {
            $translation = 'Message Us';
        }
    }

    return $translation;
}

/**
 * Translate text without context.
 *
 * @param string $translation  Translated text.
 * @param string $text         Text to translate.
 * @param string $domain       Text domain. Unique identifier for retrieving translated strings.
 *
 * @return string
 */
add_filter( 'gettext', 'um_rename_messagetxt', 10, 3);
function um_rename_messagetxt( $translation, $text, $domain ) {
    if ( 'text_domain' === $domain ) {
        if ( 'Message' === $text ) {
            $translation = 'Contact Us';
        }
    }

    return $translation;
}

Edit: Ultimate Member Messaging Button customization

I’ve taken a close look at this, and unfortunately the plugin authors have not made it very easy to change the button text.

Here’s a solution that will replace the default Ultimate Member Message Button’s shortcode with our own forked version. Note that we can recycle the ultimatemember_message_button name. I would suggest making a plugin out of this code:

<?php
/*
Plugin Name: Ulimate Member Custom Message Button Shortcode
Plugin URI: 
Description: 
Version: 0.0.1
Author:
Author URI:
License: GPL2/Creative Commons
*/

/**
 * Remove the default UM Message shortcode and wire up our forked version.
 */ 
add_action( 'init', 'wpse_ultimatemember_message_button_custom' );
function wpse_ultimatemember_message_button_custom() {
    global $um_messaging;
    remove_shortcode( 'ultimatemember_message_button', [ $um_messaging->shortcode, 'ultimatemember_message_button' ] );
    add_shortcode( 'ultimatemember_message_button', 'wpse_ultimatemember_message_button' );
}

/**
 * Customized version of ultimatemember_message_button shortcode, which allows
 * for the button's label to be specified using the 'label' parameter.
 */
function wpse_ultimatemember_message_button( $args = array() ) {
    global $ultimatemember, $um_messaging;

        $defaults = array(
            'user_id' => 0,
            'label' => __( 'Message','um-messaging' ),
        );
    $args = wp_parse_args( $args, $defaults );
    extract( $args );

    $current_url = $ultimatemember->permalinks->get_current_url();

    if( um_get_core_page('user') ){
        do_action("um_messaging_button_in_profile", $current_url, $user_id );
    }

    if ( !is_user_logged_in() ) {
        $redirect = um_get_core_page('login');
        $redirect = add_query_arg('redirect_to', $current_url, $redirect );
        $btn = '<a href="' . $redirect . '" class="um-login-to-msg-btn um-message-btn um-button" data-message_to="'.$user_id.'">'. $label .'</a>';
        return $btn;
    } else if ( $user_id != get_current_user_id() ) {

        if ( $um_messaging->api->can_message( $user_id ) ) {
            $btn = '<a href="#" class="um-message-btn um-button" data-message_to="'.$user_id.'"><span>'. $label .'</span></a>';
            return $btn;
        }

    }

}

Update your template to call the ultimatemember_message_button shortcode with our new label parameter like this:

<div class="msgshort">
    <?php echo do_shortcode('[ultimatemember_message_button user_id=2 label="Contact US"]'); ?>
</div>

This isn’t really the greatest solution, but our options are limited by the way that the plugin is implemented. I would suggest making a feature request for the label parameter to be added.

Well, I have become hopeless so I have resolved this in an alternate way (this method is not ideal but at least it gets the job done)

I just added a second shortcode function to the plugin’s shortcode.php file and changed the “Message” to “Contact Us” in the new function:

/***
*** @shortcode
***/
function ultimatemember_message_button2( $args = array() ) {
    global $ultimatemember, $um_messaging;

    $defaults = array(
        'user_id' => 0
    );
    $args = wp_parse_args( $args, $defaults );
    extract( $args );

    $current_url = $ultimatemember->permalinks->get_current_url();

    if( um_get_core_page('user') ){
        do_action("um_messaging_button_in_profile", $current_url, $user_id );
    }

    if ( !is_user_logged_in() ) {
        $redirect = um_get_core_page('login');
        $redirect = add_query_arg('redirect_to', $current_url, $redirect );
        $btn = '<a href="' . $redirect . '" class="um-login-to-msg-btn um-message-btn um-button" data-message_to="'.$user_id.'">'. __('Contact Us','um-messaging'). '</a>';
        return $btn;
    } else if ( $user_id != get_current_user_id() ) {

        if ( $um_messaging->api->can_message( $user_id ) ) {
            $btn = '<a href="#" class="um-message-btn um-button" data-message_to="'.$user_id.'"><span>'. __('Contact Us','um-messaging'). '</span></a>';
            return $btn;
        }

    }

}

Then I just called the “new” shortcode in my footer.php file:

<div class="msgshort"><?php echo do_shortcode('[ultimatemember_message_button2 user_id=1]'); ?></div>

This isn’t exactly great because I wanted to use translation and add to my child theme’s function.php file so I won’t lose the modifications when I update… so I would still appreciate a better solution if anyone has one. Thanks again for the help!