What’s the difference between “double underscore” and “underscore x”?

In PHP, specifically in WordPress, what’s the difference between __('string') and _x('string')?

I’m reading WordPress documentation and confused. The following good example of the confusion is drawn from example code on the WordPress doc for register_post_type():

$labels = array(
    'name'               => _x( 'Books', 'post type general name', 'your-plugin-textdomain' ),
    'singular_name'      => _x( 'Book', 'post type singular name', 'your-plugin-textdomain' ),
    'menu_name'          => _x( 'Books', 'admin menu', 'your-plugin-textdomain' ),
    'name_admin_bar'     => _x( 'Book', 'add new on admin bar', 'your-plugin-textdomain' ),
    'add_new'            => _x( 'Add New', 'book', 'your-plugin-textdomain' ),
    'add_new_item'       => __( 'Add New Book', 'your-plugin-textdomain' ),
    'new_item'           => __( 'New Book', 'your-plugin-textdomain' ),
    'edit_item'          => __( 'Edit Book', 'your-plugin-textdomain' ),
    'view_item'          => __( 'View Book', 'your-plugin-textdomain' ),
    'all_items'          => __( 'All Books', 'your-plugin-textdomain' ),
    'search_items'       => __( 'Search Books', 'your-plugin-textdomain' ),
    'parent_item_colon'  => __( 'Parent Books:', 'your-plugin-textdomain' ),
    'not_found'          => __( 'No books found.', 'your-plugin-textdomain' ),
    'not_found_in_trash' => __( 'No books found in Trash.', 'your-plugin-textdomain' )
);

Related posts

Leave a Reply

2 comments

  1. In WordPress, both _x() and __() are translation functions. _x() allows you to specify a context for the translation:

    <?php _x( $text, $context, $domain ); ?>
    

    Whereas __() does not:

    <?php __( $text, $domain ); ?>
    

    The context option is useful for various situations where literal translation might not yield the desired result.

    Since the string ‘Read’ on its own could have one of several different meanings in English, context is given so that translators know that they should be supplying a short term that means “Books I have read.”

    Some other examples could be: “date”, “type”, “right”, “leaves”, etc.

    Source: WordPress Codex

  2. __(..) does direct translation from string A to string B

    _x(..) lets you provide context. For example, lets say you have 2 strings in English that mean the same thing but in another language might not mean the same thing, then you can use _x to provide context so that although your strings are the same in English, you can translate them to 2 different strings in another language.

    So as an example in your question you have

    __( 'All Books', 'your-plugin-textdomain' ),

    which uses __ because the author must have thought “‘All books’ will always mean ‘All books’ in every context that this term is used”. However lets consider a usecase for _x:

    _x( 'Books', 'post type general name', 'your-plugin-textdomain' )

    So here the author was thinking “‘Books’ is a very general term, depending on the context in which we used the term ‘Books’ in our app, we may want to translate this term differently” – and thus additional parameters are used as context. When translating ‘Books’ to another language from the above line, we would know that we’re talking about books in the context of our plugin’s textdomain.

    Source: http://wpengineer.com/2237/whats-the-difference-between-__-_e-_x-and-_ex/