-
-
Save tacoverdo/2ffad5693b9532305a41 to your computer and use it in GitHub Desktop.
<?php | |
// METHOD 1 | |
sprintf( __( 'Please read %1$sthis%2$s.', 'tacoverdo-example-domain' ), '<a target="_blank" href="' . esc_url( 'https://goo.gl' ) . '">', '</a>' ); | |
// METHOD 2 | |
echo '<a target="_blank" href="' . esc_url( 'https://goo.gl' ) . '">'; | |
__( 'Please read this.', 'tacoverdo-example-domain' ); | |
echo '</a>'; | |
// METHOD 3 | |
sprintf( __( 'Please read <a href="%s">this</a>.', 'tacoverdo-example-domain' ), esc_url( 'https://goo.gl' ) ); | |
// METHOD 4 | |
sprintf( __( 'Please read %sthis%s.', 'tacoverdo-example-domain' ), '<a target="_blank" href="' . esc_url( 'https://goo.gl' ) . '">', '</a>' ); | |
// METHOD 5 | |
__( 'Please read <a target="_blank" href="' . esc_url( 'https://goo.gl' ) . '">this</a>', 'tacoverdo-example-domain' ); |
Thanks Coen, I updated method 3 in the above gist :)
There is no point in runtime escaping if URL is hardcoded. Most of these treat URL as separate from the string, but I very well might imagine scenarios where it is translatable information, for example linking to language–specific version of target page.
So I'd say path of least resistance is 5 sans escaping.
As Coen mentioned, method 3. This is how core does it, with the addition of separate i18n on the URL so localised installs can change the link destination. Depends on the context of the link though.
I personally do not like putting HTML tags in translations as I feel they don't belong here. One possible solution is:
sprintf( __( '%s <a href="%s">%s</a> %s', 'texdomain' ), 'Please read', 'http://goo.gl', 'this link', 'as soon as possible' );
This is a little overkill though. In my experience if someone takes the time to translate something they are OK with a little bit of HTML so I would probably also use method 3.
Agree with Method 3, disagree with @Rarst, re Method 5. As any validator of translations will tell you, it is far too easy for a translator (i.e. not a dev), to mess up or mistype the esc_url( 'http://goo.gle')
bit (see what I did there? :) ). If we have to go and check stuff like that in addition to the normal strings, validating becomes a bigger headache than it needs to be.
Yeah, after some pondering 3 with separate translation call on URL is probably the way to go (as per John). And keeping escaping in that case since it won't hurt if it doesn't hurt.
This is the best method if the entire text is to be translated.
echo '<a href="#">' . __( 'Please read this.', 'textdomain' ) . '</a>';
If the link is within the text, this can be the easiest if there are no other placeholders. I like this method because I prefer to not have translators tinkering with the HTML.
/* Translators: %s are placeholders are for HTML. The order cannot be changed. */
printf( __( 'Please read %sthis%s.', 'textdomain' ), '<a href="#">', '</a>' );
Otherwise, this is probably the way to go:
_e( 'Please read <a href="#">this</a>.', 'textdomain' );
You don't need to use esc_url()
if you're hardcoding the URL. If that's a variable, it changes things about the above method, which would need to be:
printf( __( 'Please read <a href="%s">this</a>.', 'textdomain' ), esc_url( $url ) );
And, like Rarst said, sometimes URLs need to be translated, so that may change things up.
@danielpataki, you're assuming that the sequence 'Please read', url , 'this' is valid for any language, which it is not true.
Method 3.
To be honest, I expected method 1 to be the most widely used/favorited.
The reason for that is that method 3 requires every translator to "translate" <a href="%s">
as part of the string, even though it does not change per language. Therefore using %s
for the whole seemed to make more sense.
Using that also lowers the chance that translators make (un)intentional mistakes in the HTML.
The downside of method 1 however is readability. %ssentence%s
can be quite easily misread.
So, why do most of you prefer method 3 over method 1?
Because core does it that way? Or is there an argument I overlooked?
So, why do most of you prefer method 3 over method 1?
I can only speak as a translator, validator, and team lead of translators: It's the way core does it, and we're all used to it. A variation would cause a translator to stop and ponder on the meaning of the unusual placeholders. That said, you're of course free to use Method 1.
Regarding method 1: It's not clear to a translator what the %1$s
and %2$s
placeholders represent (A <strong>
tag? An <a>
tag? Speech marks?). It would need to be accompanied by a translator comment, or the translator would need to look up the string in the source code to see what was going on.
I'm for a version there exclude the html, is not helpful to translate this and makes harder to secure this.
I'm agree with the hints from @justintadlock . But if you will add context for the translators use the function _x()
or a related function with context.
The esc_url()
in method 3 is not helpful, only a performance topic here if you hardcoded the url.
In some cases I would recommend something like:
sprintf( __( 'Please read the %s.', 'tacoverdo-example-domain' ), '<a href="' . esc_html__( 'https://goo.gl', 'tacoverdo-example-domain' ) . '">' . __( 'docs', 'tacoverdo-example-domain' ) . '</a>' );
you might want to use _x()
to clarify the connection but I think this way the translator is safe from screwing up html elements
EDIT:
Or do I need to go with:
sprintf( __( 'Please read the %s.', 'tacoverdo-example-domain' ), '<a href="' . esc_url( __( 'https://goo.gl', 'tacoverdo-example-domain' ) ) . '">' . __( 'docs', 'tacoverdo-example-domain' ) . '</a>' );
@cfoellmann I must say I disagree with both, as Otto explained under Law the Second.
@bueltge & @johnbillion I think it's good practice to provide context when needed, but do translators really need it in this case? Do they need to know whether %s
stands for <strong>
or <a href target="#">
? Does it influence their translation?
I find context helpful. if you add a context for %s
, makes easier for translators, especially if she don't know about the position, the context in the source.
I used to include HTML tag in translations until some people reported bugs that I couldn't figure out. It turns out that a translator messed up with some HTML closing tags: < /a>
(space between <
and /a>
) which caused some errors.
So from now, I will go for a non including HTML tags method.
@tacoverdo You are totally right. The "chapter" is great and logical but I think the case here with a link it a little bit beyond the described case. This discussion is a good indicator for that.
Hopefully there are some more ideas coming up here. I am not happy with either of the solutions (including mine)
I summarized my thoughts and my interpretation of this discussion in answer at WPSE, but since Ze grumbled at me for it — alternate answers welcomed. :)
If you can go with method 2 then that is the best but not always possible. Method 3 is simple and balanced.
Method 1 and 4 are the same except for using %s
or %1$s
@cfoellmann solution should work in every language as you can move the variable as needed but requires a certain understanding to make it work.
I would also opt for method 3. It's not uncommon for a translator to have strings with some HTML markup inside. As long as it's just as much as you need.
I would also find 1 and 4 not easy to translate if you don't know what the placeholders stand for. And beside readability, it's quite easy to mess it up. Method 2 would be somehow OK. I would never use method 5, as it's quite impossible to parse such a translation. If you hard code the URL in method 5, to make the URL itself translatable (as @Rarst pointed out), than I am also OK with method 5, but still wouldn't do it this way.
Please continue discussion here, if necessary.
Thanks!
Method 3, but change the single quotes around attributes to double quotes so they are easier to read and don't need any escaping. Also, the
sprintf()
variable parameters don't need to be wrapped in quotes: