How to Relabel WordPress’ “Publish” Button for Custom Post Types

3 minute read

For my WordPress plugin Print My Blog, I wanted to change WordPress’ “Publish” button to instead say “Save”, and it was complicated enough to merit sharing a blog post.

My Situation

The plugin registered a custom post type called “Print Material”, which isn’t publicly visible on the website. So the button “Publish” was misleading because it implies the content will then be visible to everyone who visits the website, which wasn’t the case. So a user recommended it get be something else, like “Save”.

Also, I want my plugin to work with WordPress’ new Gutenberg block editor, the classic editor (I found about half my surveyed users used it), and also ClassicPress (which is mostly the same as the classic editor). Let’s start with the easier of the two…

CHanging it for Classic Editor & CLassicPress

Adding new “Print Materials” via the Classic Editor. Notice the URL and that it says “Publish”.

The code to change it for the Classic Editor and ClassicPress was straightforward: on the new Print Materials admin page, use the gettext filter to change “Publish” to “Save”. This code would do the trick:

function makePrintContentsSaySaved(){
    global $pagenow;
    if ( isset($pagenow) && $pagenow == 'post-new.php'
        && isset($_GET['post_type']) && $_GET['post_type'] === CustomPostTypes::CONTENT){
        add_filter(
            'gettext',
            function($translated,$text_domain,$original){
                if($translated === 'Publish'){
                    return __('Save', 'print-my-blog');
                }
                return $translated;
            },
            10,
            3
        );
    }
}
add_action('init', 'makePrintContentsSaySaved');

It checks we’re on the post-new.php page, and using the Print Materials custom post type, then changes any translated strings that say “Publish” to “Save”, and makes “Save” translatable.

The “Publish box” became a “Save box” with a “Save” button.

Changing it FOr Gutenberg Block Editor

The Gutenberg Block Editor showing the “Publish” button

It took a bit of digging, but I found on this Stack Overflow article how to translate it for Gutenberg. It’s not the same because the string “Publish” is added from Javascript, and so the PHP filter gettext won’t work. You’ve gotta do the filtering in Javascript too.

So, the solution is to add some Javascript that changes the Javascript translations, like so:

function makePrintContentsSaySaved(){
    global $pagenow;
    if ( isset($pagenow) && $pagenow == 'post-new.php'
        && isset($_GET['post_type']) && $_GET['post_type'] === CustomPostTypes::CONTENT){
        add_action('admin_print_footer_scripts','makePrintContentsSaySavedGutenberg');
    }
}
function makePrintContentsSaySavedGutenberg(){
    // we've already checked we're on the right page
    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({
                'Publish': [
                    'Save',
                    'print-my-blog'
                ]
            });
        </script>
        <?php
    }
}
add_action('init', 'makePrintContentsSaySaved');

On the new Print Materials page, provided the wp-i18n script is enqueued, add some Javascript. That Javascript calls wp.i18n.setLocaleData() which changes the string “Publish” to “Save”.

Gutenberg editor, with the “Publish” button changed to “Save”

ALl Together Now

My final code looked something like this (not quite, because I had my code in a class)

protected function makePrintContentsSaySaved()
    {
    global $pagenow;
    if ( isset($pagenow) && $pagenow == 'post-new.php'
        && isset($_GET['post_type']) && $_GET['post_type'] === 'print_materials'){
        add_action('admin_print_footer_scripts','makePrintContentsSaySavedGutenberg');
        add_filter(
            'gettext',
            function($translated,$text_domain,$original){
                if($translated === 'Publish'){
                    return __('Save', 'print-my-blog');
                }
                return $translated;
            },
            10,
            3
        );
    }
    }

    /**
     * On the PMB Print Materials CPT Gutenberg new page, change "Publish" button to just be "Save" because the post
     * type isn't publicly visible.
     */
public function makePrintContentsSaySavedGutenberg(){
    // we've already checked we're on the right page
    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({
                'Publish': [
                    'Save',
                    'print-my-blog'
                ]
            });
        </script>
        <?php
    }
}
add_action('init', 'makePrintContentsSaySaved');

Make sense?

So that’s how you change the “Publish” button to be “Save”, or anything else. I kinda wonder if the “Publish” button shouldn’t automatically be called something else for non-public post types.

For background info, you may want to read up on PHP translations, and the newer Javascript translations, in WordPress.

Leave a Reply