Some site owners don’t realize what “translation support” really means when it comes to WordPress and s2Member. The fact that s2Member supports translation indicates that s2Member can be translated into an entirely different language. However, this also makes it possible for tidbits of information to be modified dynamically (e.g., you can change words/phrases easily).

So maybe I don't want to translate s2Member into an entirely different language. Maybe I just want to change some of it’s words/phrases a bit. As an example, let’s say that I want to change the phrase “Password (type this twice please)", which appears in s2Member Pro-Forms. This phrase is part of the default template set that comes with s2Member Pro. Using a custom template file would accomplish what I need (i.e., I can change quite a bit by using a custom Pro-Form template), but if the only purpose of this custom template is just to change that specific phrase, it seems like too much work. Right? There must be an easier way!

Translating Words/Phrases (Example)

In this example, I'm going to change every instance of the phrase “Password (type this twice please)”. Instead, I want it to read “Password (enter twice to confirm)”. I'm also going to change instances of “Submit Form” to just “Submit”.

Please create this directory and file: /wp-content/mu-plugins/s2member-o.php

Note: this is called a MUST USE plugin, see: MU Plugins @

See also: Hacking s2Member® Plugin w/ Hooks/Filters for WordPress

Note Also: The name of this hack file (s2member-o.php) is very important. It allows translations in normal s2Member functionality, and it also supports translations in s2Member-Only Mode—for JavaScript/CSS files. See this related article about s2Member-Only Mode.

add_filter('gettext_with_context', function ($translated, $original, $context, $text_domain)
        if($context === 's2member-front' && $text_domain === 's2member')
                if($original === 'Password (type this twice please)')
                    $translated = 'Password (enter twice to confirm)';

                else if($original === 'Submit Form')
                    $translated = 'Submit';
        return $translated; // Return final translation.
    }, 10, 4);

How Do I Know What Can Be Changed?

Most of what s2Member displays on your site is already configurable in the Dashboard. So changing words/phrases that are already configurable in the UI does not require this approach. However, if you find that portions of the s2Member codebase need to be tweaked, you can use the example above as a guideline.

Throughout s2Member's source code you will see text wrapped inside the _x() PHP function call. This is a WordPress translation. Any text that s2Member wraps with this function will ultimately pass through the gettext_with_context filter in WordPress—making it possible for you to filter the text and modify it dynamically.

Inspecting s2Member’s Source Code

Inside: /s2member-pro/includes/templates/forms/paypal-checkout-form.php I find this code fragment. Indicating that I can translate this text.

_x('Password (type this twice please)', 's2member-front', 's2member')

Inside: /s2member-pro/includes/templates/forms/paypal-checkout-form.php I find this code fragment. Indicating that I can translate this text.

_x('Submit Form', 's2member-front', 's2member')

So searching the s2Member codebase for instances of _x will reveal the portions of s2Member that are translatable. TIP: There is also a master POT translation file for s2Member that lists every translatable string in both s2Member and s2Member Pro.

Why isn't the text changing?

One important thing to note (as described above), is that the exact original message from the source code must be used--it's not enough to simply copy/paste the message shown on the front-end of the site. If there isn't an exact match to what is shown in the code (i.e., the full text passed to _x()), then the replacement won't work.

For example, if this was the message in the code that you were trying to change:

_x('<strong>Thank you.</strong> Your account has been approved.<br />&mdash; Please <a href="%s" rel="nofollow">login</a>.', "s2member-front", "s2member")

Setting $original to the following would NOT work:

$original = 'Thank you. Your account has been approved.';

You would need to use the exact, full line from the code like this:

$original = '<strong>Thank you.</strong> Your account has been approved.<br />&mdash; Please <a href="%s" rel="nofollow">login</a>.';

To find the exact original message in the source code, you can search the codebase for a phrase or part of the phrase you are looking for, and then inspect the code inside any files that you find until you locate the message you're trying to change.