2

I am struggling with the translations of my theme. I use the function get_permalink_date of my class. The relevant snippet is:

$permalink_title = sprintf(
    /* translators: 1 = Post Title, 2 = Author Name */
    esc_html_x( '%1$s by %2$s', 'permalink title', 'themeberger' ),
    __( 'A post', 'themeberger' ),
    get_the_author_meta( 'display_name', $this->post->post_author )
);

What I don't understand is that the translation from __(); works, but esc_html_x(); does not. I hope that someone can help me.

The relevant part from the .po file is:

#. translators: %1$s: Post Title. %2$s: Author Name.
#: themeberger/class-themeberger-post-functions.php:237
msgid "%1$s by %2$s"
msgstr "%1$s von %2$s"

#: themeberger/class-themeberger-post-functions.php:238
msgid "A post"
msgstr "Ein Beitrag"

The output is <a href="[...]" title="Ein Beitrag by Christian Hockenberger">[...]</a>

I really don't get it. In another line also _x( '%s ago', '%s = human-readable time difference', 'themeberger' ) is not working. I first thought that for some reason the translations are not transferred to the class, but __(); works.

What can I do?

2 Answers 2

3
+50

You are trying to translate a string with a context but in your po file your string doesn't declare a context

To declare a context in your po file you need to use msgctxt

msgctxt "permalink title"
msgid "%1$s by %2$s"
msgstr "%1$s von %2$s"

You can find more documentation on how to format your PO file here (It's very simple, there is only 5 different declarations)

Or remove the context from your string like this

esc_html_x( '%1$s by %2$s', 'permalink title', 'themeberger' ); //With context
esc_html__( '%1$s by %2$s', 'themeberger' ); //Without context

You can find information on how to use the wordpress internationalization functions here

The documentation is pretty incomplete so I will add a list of the available functions

  • __ Basic translation
  • _n Translate a string with plural
  • _x Translate a string with a context
  • _nx Translate a string with a context and a plural

All of this function also have variants with esc_html_, esc_attr_ or _e in front of them

The _e variant will simply echo the string instead of returning it (I don't recommend using this as sometimes you will want to sprintf in your string but if you use _e within a sprintf it will not work and it's hard to catch)

The esc_html_ variant will escape the string to be displayed in html (eg: > becomes &gt;) You should pretty much always use it in templates as it increases security by preventing XSS (some translations are public)

The esc_attr_ variant is to ALWAYS be used within an html attribute as it will escape quotes and others that would break your attribute

Example:

<a href="<?php esc_attr_e('https://domain.com/en/content/', 'domain') ?>"><?php esc_html_e('My link', 'domain') ?></a>

You can also look at the source code to see all the declared functions

3
  • Hello @Toffee, thank you very much. 'msgctxt' was completely unknown to me. I could not find any reasonable information in the codex. Could you please add a link to a page with further explanations to your answer? Maybe there is more to learn.
    – chrisbergr
    Commented Mar 12, 2020 at 0:37
  • 1
    Looking at the WP documentations, the information is quite scattered and honestly lacking, I will add some links and some info
    – Toffee
    Commented Mar 12, 2020 at 9:13
  • 1
    Thanks a lot for expanding your answer. It helps me and hopefully others as well. BTW: Inspecting the wp core source code is always a good idea :)
    – chrisbergr
    Commented Mar 12, 2020 at 10:12
3

Okay, it appears that I was overwhelmed by the amount of functions for translating strings. The functions with an 'x' in their name need a gettext context. I don't have that for my strings, so it didn't work.

esc_html_x(); replaced with esc_html__(); and _x(); replaced with __(); is the simple solution.

Embarrassing for me, hopefully helpful for someone else.

Your Answer

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

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