6

I'm trying to do a string replacement using gettext filter (source):

function theme_change_comments_label( $translated_text, $untranslated_text, $domain ) {
    if( stripos( $untranslated_text, 'comment' !== FALSE ) ) {
        $translated_text = str_ireplace( 'Comment', 'Review', $untranslated_text ) ;
    }
    return $translated_text;
}
is_admin() && add_filter( 'gettext', 'theme_change_comments_label', 99, 3 );

I want it to work only on a specific Post Type (in admin). So I tried get_current_screen() within the function:

function theme_change_comments_label( $translated_text, $untranslated_text, $domain ) {
    $screen = get_current_screen();
    if( $screen->post_type == 'mycpt' ) {
        if( stripos( $untranslated_text, 'comment' !== FALSE ) ) {
            $translated_text = str_ireplace( 'Comment', 'Review', $untranslated_text ) ;
        }
        return $translated_text;
    }
}
is_admin() && add_filter( 'gettext', 'theme_change_comments_label', 99, 3 );

But I'm getting error:

Fatal error: Call to undefined function get_current_screen()

With several testing I understood, gettext is not the correct filter to trigger the get_current_screen() function.

Then how could I do that, specific to my custom post type only?

6

According with the codex, get_current_screen() has to be used later than admin_init hook. After a few tests, it seems that the safiest way is to use current_screen action hook instead of get_current_screen():

add_action('current_screen', 'current_screen_callback');
function current_screen_callback($screen) {
    if( is_object($screen) && $screen->post_type == 'mycpt' ) {
        add_filter( 'gettext', 'theme_change_comments_label', 99, 3 );
    }
}

function theme_change_comments_label( $translated_text, $untranslated_text, $domain ) {

    if( stripos( $untranslated_text, 'comment' ) !== FALSE ) {
        $translated_text = str_ireplace( 'Comment', 'Review', $untranslated_text ) ;
    }

    return $translated_text;

}

You can reuse the filter if you want, for example in the frontend for "mycpt" archives:

add_action('init', function() {
    if( is_post_type_archive( 'mycpt' ) ) {
        add_filter( 'gettext', 'theme_change_comments_label', 99, 3 );
    }
});
| improve this answer | |
  • I'm afraid none of 'em is triggering the string replacement in admin panel. I tried 'post' instead of CPT, no good result – Mayeenul Islam Jan 12 '15 at 10:54
  • I've tested and the filter is triggered and working, see edited answer; I've added what I have tried at the end. The logic of your stripos and str_ireplace is your problem now. – cybmeta Jan 12 '15 at 10:59
  • 1
    admin_menu seems to be too early. Test hooking in wp action and it works for admin listing pages. I'm now invetigating a way to not relay in get_current_screen. – cybmeta Jan 12 '15 at 11:29
  • 2
    Sorry, but I've updated again the answer. See the last update. I usually look the order in this list, not sure if it is the exact order the actions occur, but it has been helpful for me a lot of times. – cybmeta Jan 12 '15 at 11:42
  • 1
    @ChristineCooper current_screen action hook is triggered only in admin side, not in frontend, and, as far I understand the code, the action recieves the global $current_screen, which is already set in every admin page, so I don't think that using current_screen action hook makes any difference, only what you do in that hook could make a big difference. – cybmeta Jun 23 '15 at 9:41
2

get_current_screen() is a pain, I use the following code to avoid/wrap it:

/*
 * Convenience function to tell if we're on a specified page.
 */
function theme_is_current_screen( $base = null, $post_type = null ) {
    if ( ! $base && ! $post_type ) {
        return false;
    }
    $screen = function_exists( 'get_current_screen' ) ? get_current_screen() : null;
    if ( ! $screen ) {
        // Fake it.
        $screen = new StdClass;
        $screen->post_type = $screen->base = '';

        global $pagenow;
        if ( $pagenow == 'admin-ajax.php' ) {
            if ( isset( $_REQUEST['action'] ) ) {
                $screen->base = $_REQUEST['action'];
            }
        } else {
            $screen->post_type = isset( $_REQUEST['post_type'] ) ? $_REQUEST['post_type'] : '';
            if ( $pagenow == 'post.php' || $pagenow == 'post-new.php' || $pagenow == 'edit.php' ) {
                $screen->base = preg_replace( '/[^a-z].+$/', '', $pagenow );
                if ( ! $screen->post_type ) {
                    $screen->post_type = get_post_type( theme_get_post_id() );
                }
            } else {
                $page_hook = '';
                global $plugin_page;
                if ( ! empty( $plugin_page ) ) {
                    if ( $screen->post_type ) {
                        $the_parent = $pagenow . '?post_type=' . $screen->post_type;
                    } else {
                        $the_parent = $pagenow;
                    }
                    if ( ! ( $page_hook = get_plugin_page_hook( $plugin_page, $the_parent ) ) ) {
                        $page_hook = get_plugin_page_hook( $plugin_page, $plugin_page );
                    }
                }
                $screen->base = $page_hook ? $page_hook : pathinfo( $pagenow, PATHINFO_FILENAME );
            }
        }
    }
    // The base type of the screen. This is typically the same as $id but with any post types and taxonomies stripped.
    if ( $base ) {
        if ( ! is_array( $base ) ) $base = array( $base );
        if ( ! in_array( $screen->base, $base ) ) {
            return false;
        }
    }
    if ( $post_type ) {
        if ( ! is_array( $post_type ) ) $post_type  = array( $post_type );
        if ( ! in_array( $screen->post_type, $post_type ) ) {
            return false;
        }
    }
    return true;
}

/*
 * Attempt to determine post id in uncertain (admin) situations.
 * Based on WPAlchemy_MetaBox::_get_post_id().
 */
function theme_get_post_id() {
    global $post;

    $ret = 0;

    if ( ! empty( $post->ID ) ) {
        $ret = $post->ID;
    } elseif ( ! empty( $_GET['post'] ) && ctype_digit( $_GET['post'] ) ) {
        $ret = $_GET['post'];
    } elseif ( ! empty( $_POST['post_ID'] ) && ctype_digit( $_POST['post_ID'] ) ) {
        $ret = $_POST['post_ID'];
    }

    return $ret;
}

Your function would then become:

function theme_change_comments_label( $translated_text, $untranslated_text, $domain ) {
    if( theme_is_current_screen( null, 'mycpt' ) ) {
        if( stripos( $untranslated_text, 'comment' ) !== FALSE ) {
            $translated_text = str_ireplace( 'Comment', 'Review', $untranslated_text ) ;
        }
    }
    return $translated_text;
}
is_admin() && add_filter( 'gettext', 'theme_change_comments_label', 99, 3 );

It's also useful for shortcircuiting custom type admin_inits, or only registering your settings on your own settings page.

| improve this answer | |
  • It's also working and it's nice gift alternative to get_current_screen() as there are many problems regarding this erronus hooking for this function. Nice one! – Mayeenul Islam Jan 12 '15 at 12:11
  • 1
    Yeah, it is nice, but current_screen action looks nicer, easier, shorter and it is fully working. – cybmeta Jan 12 '15 at 13:25

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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