web-dev-qa-db-ja.com

特定の管理者ページの翻訳(gettext文字列)をフィルタリングする

私は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 );

特定の投稿タイプ(管理者用)でのみ機能するようにします。そこで私は get_current_screen() を関数内で試してみました:

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 );

しかし、私はエラーを受けています:

致命的なエラー: 未定義の関数への呼び出しget_current_screen()

私が理解したいくつかのテストで、gettextget_current_screen()関数を起動するための正しいフィルタではありません。

それでは、自分のカスタム投稿タイプのみに特定の方法でそれを実行できますか。

5
Mayeenul Islam

とコーデックス によると、get_current_screen()admin_initフックより後に使用する必要があります。いくつかのテストの後、最も安全な方法はget_current_screen()の代わりに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;

}

必要に応じてフィルタを再利用することができます。たとえば、 "mycpt"アーカイブのフロントエンドにあります。

add_action('init', function() {
    if( is_post_type_archive( 'mycpt' ) ) {
        add_filter( 'gettext', 'theme_change_comments_label', 99, 3 );
    }
});
5
cybmeta

get_current_screen()は苦痛です、私はそれを避ける/ラップするために次のコードを使います:

/*
 * 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;
}

あなたの機能は次のようになります。

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 );

カスタムタイプのadmin_initsを短縮したり、自分の設定ページに自分の設定を登録するだけの場合にも便利です。

2
bonger