Cum să afișezi text cu traducere și URL HTML
Sunt relativ nou în WordPress când vine vorba de personalizări "avansate".
Acum am această funcție:
esc_html_e( 'Dragă Oaspete, cu informațiile dumneavoastră nu am găsit nicio cameră disponibilă momentan. Vă rugăm să ne contactați prin email la info@whitesandsamuiresort.com.', 'awebooking' );
Și textul se afișează corect până acum.
Dar ce funcție trebuie să folosesc când vreau să adaug un a
href
(link HTML)?
Vreau să obțin acest text:
Dragă Oaspete, cu informațiile dumneavoastră nu am găsit nicio cameră disponibilă momentan.
Vă rugăm să ne contactați pe
<a href="http://www.whitesandsamuiresort.com/contact-us/">pagina noastră de contact</a>
sau prin email lainfo@whitesandsamuiresort.com
.
Am probleme în a combina suportul pentru traducere (internaționalizare/localizare) cu escaparea link-urilor HTML în același timp.

Deoarece esc_html_e
va escapa legăturile HTML (prin urmare va afișa ancorajul HTML ca text simplu), va trebui să segmentați textul și să escapați partea non-HTML cu esc_html_e
sau esc_html__
, iar partea de LEGĂTURĂ HTML să o afișați fără escapare HTML.
Metoda-1 (doar pentru înțelegerea dumneavoastră):
Puteți face acest lucru pe părți, astfel:
esc_html_e( 'Dragă Oaspete, cu informațiile dumneavoastră nu am putut găsi nicio cameră în acest moment.', 'text-domain' );
echo "<br><br>";
printf(
esc_html__( '%1$s %2$s', 'text-domain' ),
esc_html__( 'Vă rugăm să ne contactați pe', 'text-domain' ),
sprintf(
'<a href="%s">%s</a>',
esc_url( 'http://www.example.com/contact-us/' ),
esc_html__( 'Pagina de Contact', 'text-domain' )
)
);
printf(
' sau <a href="%s">%s</a>',
esc_url( 'mailto:info@example.com', array( 'mailto' ) ),
esc_html__( 'Email', 'text-domain' )
);
Metoda-2 (doar pentru înțelegerea dumneavoastră):
Evident, diferite limbi vor avea o ordine diferită a textelor, așa că pentru a oferi traducătorilor mai multă flexibilitate (cu escaparea și ordonarea textului), puteți face acest lucru în felul următor:
printf(
esc_html__( '%1$s%2$s%3$s%4$s%5$s', 'text-domain' ),
esc_html__( 'Dragă Oaspete, cu informațiile dumneavoastră nu am putut găsi nicio cameră în acest moment.', 'text-domain' ),
nl2br( esc_html__( "\n\n", 'text-domain' ) ),
sprintf(
esc_html__( '%1$s %2$s', 'text-domain' ),
esc_html__( 'Vă rugăm să ne contactați pe', 'text-domain' ),
sprintf(
'<a href="%s">%s</a>',
esc_url( 'http://www.example.com/contact-us/' ),
esc_html__( 'Pagina de Contact', 'text-domain' )
)
),
esc_html__( ' sau ', 'text-domain' ),
sprintf(
'<a href="%s">%s</a>',
esc_url( 'mailto:info@example.com', array( 'mailto' ) ),
esc_html__( 'Email', 'text-domain' )
)
);
Acest mod de a face acest lucru va:
Escapa toate textele traduse necesare.
Permite HTML pentru legătură, email (cu sintaxa
mailto:
) etc.Permite traducătorilor să aibă diferite ordonări ale textelor pentru diferite limbi. Notația de schimbare a argumentelor (
%1$s
,%2$s
etc.) este folosită astfel încât traducătorii să poată reordona textul tradus unde este necesar.
Metoda-3 (Actualizată & Recomandată):
După cum @shea a subliniat corect, Metoda-2 de mai sus funcționează bine, dar poate fi dificil pentru traducători să adauge suport pentru diferite limbi. Deci avem nevoie de o soluție care:
Păstrează propozițiile întregi (nu le desparte).
Face escaparea corectă.
Oferă modalități de a avea o ordonare diferită pentru legăturile de contact și email (sau orice altceva similar) în cadrul propoziției traduse.
Deci pentru a evita complicațiile metodei-2, soluția de mai jos păstrează propozițiile traduse întregi și face escaparea URL-urilor și schimbarea argumentelor în același timp (mai multe note în comentariile din COD):
// exemplu de URL de contact (poate proveni dintr-o sursă nesigură ca inputul utilizatorului)
$contact_url = 'http://www.example.com/contact-us/';
// escaparea $contact_url
$contact_url = esc_url( $contact_url );
// exemplu de email de contact (poate proveni dintr-o sursă nesigură ca inputul utilizatorului)
$contact_email = 'info@example.com';
// escaparea, sanitizarea și ascunderea $contact_email.
// Da, poate fi necesar să sanitizați și să escapați emailul chiar și când folosiți funcția antispambot()
$contact_email = esc_url( sprintf( 'mailto:%s', antispambot( sanitize_email( $contact_email ) ) ), array( 'mailto' ) );
esc_html_e( 'Dragă Oaspete, cu informațiile dumneavoastră nu am putut găsi nicio cameră în acest moment.', 'text-domain' );
echo "<br><br>";
printf(
esc_html__( 'Vă rugăm să ne contactați pe %1$s sau prin %2$s.', 'text-domain' ),
sprintf(
'<a href="%s">%s</a>',
$contact_url,
esc_html__( 'Pagina de Contact', 'text-domain' )
),
sprintf(
'<a href="%s">%s</a>',
$contact_email,
esc_html__( 'Email', 'text-domain' )
)
);
Acest mod de a face acest lucru va oferi traducătorilor două propoziții complete și două cuvinte separate de tradus. Deci un traducător va trebui doar să se preocupe de următoarele linii simple (în timp ce CODul se ocupă de restul):
esc_html_e( 'Dragă Oaspete, cu informațiile dumneavoastră nu am putut găsi nicio cameră în acest moment.', 'text-domain' );
// ...
esc_html__( 'Vă rugăm să ne contactați pe %1$s sau prin %2$s', 'text-domain' )
// ...
esc_html__( 'Pagina de Contact', 'text-domain' )
// ...
esc_html__( 'Email', 'text-domain' )
Atât, o structură simplă și care face escaparea și schimbarea argumentelor corect.
Citiți mai multe despre internaționalizarea pentru teme și internaționalizarea pentru pluginuri.

Nu sunt sigur cât de bine ar funcționa al doilea exemplu pentru toate limbile, cum ar fi cele care folosesc o structură de propoziție diferită de cea din engleză. Nu ar fi mai bine să nu despărțim propozițiile sau să izolăm cuvintele?

@shea Nu sunt sigur la ce te referi, dar, de exemplu, chiar și această linie esc_html__( '%1$s%2$s%3$s%4$s%5$s', 'text-domain' )
poate fi modificată în %3$s%2$s%1$s%4$s%5$s
cu o traducere. Această flexibilitate în ordonare ar trebui să acopere diferite structuri lingvistice.

Nu toate limbile au un singur cuvânt pentru "sau", sau ar formula lucruri precum "Vă rugăm să ne contactați pe <link>". Spun că o metodă mai bună ar fi să oferim propoziții sau fraze complete pentru traducere, apoi să lăsăm traducătorii să facă ce este necesar pentru a traduce acest lucru. Metoda de schimbare a argumentelor pare excesiv de complicată și ineficientă

Cred că răspunsul lui @Fayaz este foarte bun; ei sunt cu siguranță pe drumul cel bun în sensul că ar trebui să folosești sprintf() în jurul traducerilor pentru a include elemente precum HTML și link-uri.
Totuși, nu cred că este o idee bună să împărți propozițiile în părți pentru traducere, deoarece multe limbi au structuri de propoziții complet diferite care nu sunt compatibile cu engleza. Prin separarea cuvintelor individuale, o mare parte din contextul în care un cuvânt specific este tradus se pierde, ceea ce poate duce la ambiguitate și erori de traducere.
În schimb, recomand să traduci fraze și propoziții ca întreg, iar apoi să folosești sprintf
sau diferite funcții de escapare unde este cazul.
Pentru textul tău, prima parte poate fi tradusă simplu cu esc_html_e
:
esc_html_e( 'Stimate Oaspete, cu informațiile furnizate nu am găsit nicio cameră disponibilă momentan. ', 'text-domain' );
A doua parte este puțin mai dificilă. Acum, presupun că obții URL-ul paginii și adresa de email din baza de date cumva, probabil folosind get_the_permalink()
sau get_option()
sau o altă funcție. Așadar, voi presupune că acestea sunt stocate în variabilele $contact_page_url
și $contact_email
.
Primul pas este să traduci șirul, fără link-uri. Reține că trebuie să folosim __()
fără escapare în acest moment - aceasta va veni mai târziu.
__( 'Vă rugăm să ne contactați pe <a href="%1$s">pagina noastră de contact</a> sau prin email %2$s.', text-domain' );
În acest fel, translatorul este liber să formuleze propoziția după necesități și să plaseze URL-ul link-ului și adresa de email unde este necesar.
Următorul pas este să folosim sprintf()
pentru a insera URL-ul link-ului și adresa de email. Reține că folosim esc_url()
aici pentru a escapa URL-ul și, de asemenea, antispambot()
pentru a codifica adresa de email și a oferi o protecție minimă împotriva scraperelor:
$text = sprintf(
__( 'Vă rugăm să ne contactați pe <a href="%1$s">pagina noastră de contact</a> sau prin email %2$s.', 'text-domain' );
esc_url( $contact_page_url ),
sprintf( '<a href="mailto:%1$s">%1$s</a>', antispambot( $contact_email ) );
);
În final, în loc să folosim esc_html()
, trebuie să folosim wp_kses()
pentru a permite doar elemente de tip link în HTML-ul tradus:
echo wp_kses( $text, array( 'a' => array( 'href' => array() ) ) );
Și asta este! Codul final este:
esc_html_e( 'Stimate Oaspete, cu informațiile furnizate nu am găsit nicio cameră disponibilă momentan. ', 'text-domain' )
$text = sprintf(
__( 'Vă rugăm să ne contactați pe <a href="%1$s">pagina noastră de contact</a> sau prin email %2$s.', 'text-domain' );
esc_url( $contact_page_url ),
sprintf( '<a href="mailto:%1$s">%1$s</a>', antispambot( $contact_email ) );
);
echo wp_kses( $text, array( 'a' => array( 'href' => array() ) ) );

Îmi place ideea ta cu wp_kses
. Totuși, sunt două aspecte (1) un traducător poate adăuga linkuri suplimentare în traducere, iar CODUL tău nu va împiedica asta. (2) un traducător va trebui să furnizeze HTML
, adică <a href="%1$s">..</a>
în cadrul traducerii. S-ar putea să nu dorești asta, deoarece ar putea greși în gestionarea corectă chiar și a celui mai simplu tag HTML <a>
.

Corect spus @Fayaz, acestea sunt puncte valide. Dacă consideri că sunt cele mai importante, atunci poate vei dori să folosești o altă soluție :)

+1 pentru câteva puncte valide. Deoarece soluția ta are aceste probleme, am actualizat soluția mea (Metoda-3) cu o structură mai simplă de data aceasta.
