4

Question: how can I change text within the Block Editor itself?

  • When a user with edit but not publish permissions makes changes to a published post and clicks "submit for review," the Block Editor presents a "post reverted to draft" success message. I would like to change this to my own text.

  • Also, in the Block Editor's Publish panel, there's text specific to WP Core roles - when a user with edit but not publish permissions hits Publish the first time and the pre-publish checks show up, a Core message says "When you're ready, submit your work for review, and an Editor will be able to approve it for you." (I use custom roles, so it's not an Editor who can help them.)

I would like to either change that text (replace it with my own static text) or, ideally, find a way to pull a list of all users who have publishing permissions for this post type and output a list, saying something like, "One of these users will be able to approve it for you: (list of users' display names)."

I can't seem to find any documentation on filtering these messages, but surely I'm overlooking something since at the very least I'm sure they are translatable.

1
  • 1
    That's one of main problems with Gutenberg - it's lacking a lot of docs... Let me take a look... Feb 11, 2019 at 22:36

2 Answers 2

9
+100

Changing the "Post reverted to draft." text

In WordPress version 5.0, WordPress introduced a new post type label which has the key item_reverted_to_draft and it's defined as:

item_reverted_to_draft – Label used when an item is switched to a draft. Default is ‘Post reverted to draft.’ / ‘Page reverted to draft.’

Hence, as with any other post type labels — and as suggested in the previous answer, you can use the post_type_labels_{$post_type} filter to change the label (text):

function my_post_type_labels( $labels ) {
    $labels->item_reverted_to_draft = 'Your custom text.';

    return $labels;
}

add_filter( 'post_type_labels_post', 'my_post_type_labels' );   // post
add_filter( 'post_type_labels_my_cpt', 'my_post_type_labels' ); // CPT

Or you can also use the register_post_type_args filter or the registered_post_type action:

add_filter( 'register_post_type_args', function( $args, $post_type ){
    $labels = isset( $args['labels'] ) ? (array) $args['labels'] : [];
    if ( in_array( $post_type, ['post', 'my_cpt'] ) ) {
        $labels['item_reverted_to_draft'] = 'Your custom text.';
    }
    $args['labels'] = $labels;

    return $args;
}, 10, 2 );

Changing the "When you’re ready, submit your work for review, and an Editor will be able to approve it for you." text

In WordPress version 5.0, WordPress introduced the JavaScript i18n support, which basically means you can use __(), _n(), etc. in JavaScript to retrieve the translation of a specific string/text like so:

// Equivalent example in PHP: <?php var_dump( __( 'My string', 'text-domain' ) ); ?>
console.log( wp.i18n.__( 'My string', 'text-domain' ) );

// Equivalent example in PHP: <?php var_dump( sprintf( _n( '%s Comment', '%s Comments', 9, 'text-domain' ), 9 ) ); ?>
console.log( wp.i18n.sprintf( wp.i18n._n( '%s Comment', '%s Comments', 9, 'text-domain' ), 9 ) );

So as you can see, unlike in PHP, in JavaScript, we access the functions via wp.i18n which is the translation library. However, not all functions are available; for example, the _e() function as in <?php _e( 'Text' ); ?> — there's no wp.i18n._e() and wp.i18n._e( 'Text' ) will result in an error.

Now, for that text — When you’re ready, submit your work for review, and an Editor will be able to approve it for you. — which you're trying to customize, you can find it in the Block Editor script in wp-includes/js/dist/editor.js under a local function named PostPublishPanelPrepublish:

prePublishBodyText = Object(external_this_wp_i18n_["__"])('When you’re ready, submit...');

And that external_this_wp_i18n_ points to wp.i18n; hence the external_this_wp_i18n_["__"]) is equivalent to wp.i18n.__.

Now here's how you can change the text via JavaScript...

Use wp.i18n.setLocaleData():

wp.i18n.setLocaleData({
    'String to translate #1': [
        'Translated string - singular',
        'Translated string - plural'
    ],
    'String to translate #2': [
        'Translated string'
        // No plural.
    ]
// Omit the text domain (or set it to '') if overriding the default WordPress translations.
}, 'text-domain');

So for example, in your case:

wp.i18n.setLocaleData({
    'When you’re ready, submit your work for review, and an Editor will be able to approve it for you.': [
        'Publish when you are ready..'
    ]
});

And here's how you could add the script to the post/page edit screen...

Or any admin pages/screens where the wp-i18n script is being enqueued.

add_action( 'admin_print_footer_scripts', function(){
    // Make sure the `wp-i18n` has been "done".
    if ( wp_script_is( 'wp-i18n' ) ) :
    ?>
        <script>
            // Note: Make sure that `wp.i18n` has already been defined by the time you call `wp.i18n.setLocaleData()`.
            wp.i18n.setLocaleData({
                'When you’re ready, submit your work for review, and an Editor will be able to approve it for you.': [
                    'Publish when you are ready..'
                ]
            });
        </script>
    <?php
    endif;
}, 11 );

But of course, you could use other similar WordPress hook, or place the JavaScript code in a .js (external JavaScript) file and enqueue it by specifying the wp-i18n (remember, it's a dash and not a dot) as a dependency.

Displaying the "One of these users will be able to approve it for you: (list of users' display names)." text

add_action( 'admin_print_footer_scripts', function(){
    // Make sure the `wp-i18n` has been "done".
    if ( wp_script_is( 'wp-i18n' ) ) :
        $wp_roles = wp_roles();
        $role_names = [];

        // Get the roles which have the publish_posts capability.
        foreach ( $wp_roles->role_objects as $name => $role ) {
            if ( $role && $role->has_cap( 'publish_posts' ) ) {
                $role_names[] = $name;
            }
        }

        // Get the users which have the role(s) in the `$role_names`.
        $users = get_users([
            'role__in' => $role_names,
        ]);
        $user_names = [];

        foreach ( $users as $user ) {
            $user_names[] = $user->display_name;
        }

        $data = [
            'When you’re ready, submit your work for review, and an Editor will be able to approve it for you.' => [
                'One of these users will be able to approve it for you: ' . implode( ', ', $user_names )
            ],
        ];
    ?>
        <script>
            // Note: Make sure that `wp.i18n` has already been defined by the time you call `wp.i18n.setLocaleData()`.
            wp.i18n.setLocaleData(<?php echo json_encode( $data ); ?>);
        </script>
    <?php
    endif;
}, 11 );

How to test the above snippet:

  • Add the snippet to the theme's functions.php file.

  • Login to the WordPress back-end as any user with a "Contributor" role.

  • Create a new Post and click the "Publish" button.

  • You should see something like this.

5
  • 1
    Wow. Pick any 3 adjectives from this list thesaurus.com/browse/thorough
    – tmdesigned
    Feb 12, 2019 at 11:02
  • 2
    Sally, you're a lifesaver. Thank you for the level of detail you included in this answer - it helped me better understand not just what code to pop in, but why.
    – WebElaine
    Feb 12, 2019 at 15:02
  • You're welcome. I'm glad I could help. :)
    – Sally CJ
    Feb 12, 2019 at 23:09
  • Great answer thanks! Will "One of these users will be able to approve it for you" won't be translatable though, will it? Eg if this code were used in a plugin that should be translatable into different languages, where do you provide the translations text domain so the new text can be translated? Nov 18, 2020 at 16:36
  • @thespacecamel, you should check this if you haven't already done so. :) And there's a guide there for generating the translation strings (JED) using wp i18n.
    – Sally CJ
    Nov 23, 2020 at 23:35
2

I'm not able to test it right now, so I won't guarantee that it will work, but...

1. post reverted to draft

When you grep through WP code searching for that string, only one occurrence appears. It's inside wp-includes/post.php file (see on trac) in get_post_type_labels function. And there is a filter used inside that function: post_type_labels_{$post_type}.

So something like this should do the trick:

function my_custom_post_labels( $labels ) {
    $labels->item_reverted_to_draft  = 'MY OWN TEXT';
}
add_filter( 'post_type_labels_post', 'my_custom_labels' );

2. When you're ready, submit your work for review, and an Editor will be able to approve it for you.

This is a little bit harder. This string is placed directly in wp-includes/js/dist/editor.js (line 26896) in this context:

prePublishBodyText = Object(external_this_wp_i18n_["__"])('When you’re ready, submit your work for review, and an Editor will be able to approve it for you.');

And external_this_wp_i18n_ is the new JS object introduced in 5.0.

I'm not very familiar with this mechanism, but... As long as I understand this article correctly, there is currently no way of running PHP filters for these strings, so we won't be able to make these strings dynamic... And that's the moment I'm really starting to hate this Gutenberg JS mess...

On the other hand, if it doesn't have to be dynamic, you can use the method described in the article I've linked to "translate" that string.

2
  • Thank you, Krzysiek! The post_type_labels_{$post_type} filter worked quite well, and researching it a little, I realized that when I register my CPTs I can set the label there as well.
    – WebElaine
    Feb 12, 2019 at 15:01
  • 1
    Yes - that should be possible. But the lack of consistency in this editor is really annoying... Feb 12, 2019 at 15:09

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.