Come stampare testo con supporto alla traduzione e URL HTML
Sono relativamente nuovo in WordPress quando si tratta di personalizzazioni più avanzate.
Attualmente ho questa funzione:
esc_html_e( 'Gentile Ospite, con le Sue informazioni al momento non abbiamo trovato alcuna camera disponibile. La preghiamo di contattarci via email all\'indirizzo info@whitesandsamuiresort.com.', 'awebooking' );
E il testo viene visualizzato correttamente finora.
Ma quale funzione devo usare quando voglio aggiungere un tag a
href
(link HTML)?
Vorrei ottenere questo testo:
Gentile Ospite, con le Sue informazioni al momento non abbiamo trovato alcuna camera disponibile.
La preghiamo di contattarci tramite la nostra
<a href="http://www.whitesandsamuiresort.com/contact-us/">pagina dei contatti</a>
o via email all'indirizzoinfo@whitesandsamuiresort.com
.
Sto avendo problemi nel supportare contemporaneamente la traduzione (internazionalizzazione/localizzazione) e l'escape dei link HTML.

Poiché esc_html_e
eseguirà l'escape del link HTML (mostrando quindi l'ancora HTML come testo normale), dovrai segmentare il testo e applicare l'escape alla parte non-HTML con esc_html_e
o esc_html__
, e stampare la parte del LINK HTML senza escape HTML.
Metodo-1 (solo per la tua comprensione):
Puoi farlo in parti, in questo modo:
esc_html_e( 'Gentile Ospite, con le Sue informazioni al momento non abbiamo trovato alcuna camera disponibile.', 'text-domain' );
echo "<br><br>";
printf(
esc_html__( '%1$s %2$s', 'text-domain' ),
esc_html__( 'La preghiamo di contattarci sulla nostra', 'text-domain' ),
sprintf(
'<a href="%s">%s</a>',
esc_url( 'http://www.example.com/contattaci/' ),
esc_html__( 'Pagina di Contatto', 'text-domain' )
)
);
printf(
' oppure <a href="%s">%s</a>',
esc_url( 'mailto:info@example.com', array( 'mailto' ) ),
esc_html__( 'Email', 'text-domain' )
);
Metodo-2 (solo per la tua comprensione):
Ovviamente, lingue diverse avranno un ordine diverso dei testi, quindi per dare ai traduttori più flessibilità (con l'escape e l'ordine del testo), puoi farlo nel seguente modo:
printf(
esc_html__( '%1$s%2$s%3$s%4$s%5$s', 'text-domain' ),
esc_html__( 'Gentile Ospite, con le Sue informazioni al momento non abbiamo trovato alcuna camera disponibile.', 'text-domain' ),
nl2br( esc_html__( "\n\n", 'text-domain' ) ),
sprintf(
esc_html__( '%1$s %2$s', 'text-domain' ),
esc_html__( 'La preghiamo di contattarci sulla nostra', 'text-domain' ),
sprintf(
'<a href="%s">%s</a>',
esc_url( 'http://www.example.com/contattaci/' ),
esc_html__( 'Pagina di Contatto', 'text-domain' )
)
),
esc_html__( ' oppure ', 'text-domain' ),
sprintf(
'<a href="%s">%s</a>',
esc_url( 'mailto:info@example.com', array( 'mailto' ) ),
esc_html__( 'Email', 'text-domain' )
)
);
Questo metodo permetterà di:
Applicare l'escape a tutti i testi tradotti necessari.
Permettere l'HTML per link, email (con sintassi
mailto:
) ecc.Permettere ai traduttori di avere qualsiasi ordine di testo per lingue diverse. La notazione di scambio argomenti (
%1$s
,%2$s
ecc.) viene utilizzata in modo che i traduttori possano riordinare il testo tradotto dove necessario.
Metodo-3 (Aggiornato e Consigliato):
Come @shea ha giustamente sottolineato, il Metodo-2 sopra funziona bene, ma potrebbe essere difficile per i traduttori aggiungere supporto per lingue diverse. Quindi abbiamo bisogno di una soluzione che:
Mantenga le frasi intatte (senza spezzarle).
Esegua l'escape corretto.
Fornisca modi per avere un ordine diverso per i link di contatto e email (o qualsiasi cosa simile) all'interno della frase tradotta.
Quindi per evitare la complicazione del metodo-2, la soluzione seguente mantiene intatte le frasi traducibili e allo stesso tempo esegue l'escape degli URL e lo scambio di argomenti (ulteriori note nei commenti del CODICE):
// URL di contatto di esempio (potrebbe provenire da un'origine non sicura come input utente)
$contact_url = 'http://www.example.com/contattaci/';
// escape di $contact_url
$contact_url = esc_url( $contact_url );
// email di contatto di esempio (potrebbe provenire da un'origine non sicura come input utente)
$contact_email = 'info@example.com';
// escape, sanificazione e nascondimento di $contact_email.
// Sì, potresti ancora dover sanificare e eseguire l'escape dell'email mentre usi la funzione antispambot()
$contact_email = esc_url( sprintf( 'mailto:%s', antispambot( sanitize_email( $contact_email ) ) ), array( 'mailto' ) );
esc_html_e( 'Gentile Ospite, con le Sue informazioni al momento non abbiamo trovato alcuna camera disponibile.', 'text-domain' );
echo "<br><br>";
printf(
esc_html__( 'La preghiamo di contattarci sulla nostra %1$s oppure via %2$s.', 'text-domain' ),
sprintf(
'<a href="%s">%s</a>',
$contact_url,
esc_html__( 'Pagina di Contatto', 'text-domain' )
),
sprintf(
'<a href="%s">%s</a>',
$contact_email,
esc_html__( 'Email', 'text-domain' )
)
);
Questo modo di procedere darà ai traduttori due frasi complete e due parole separate da tradurre. Quindi un traduttore dovrà solo preoccuparsi delle seguenti semplici righe (mentre il CODICE si occupa del resto):
esc_html_e( 'Gentile Ospite, con le Sue informazioni al momento non abbiamo trovato alcuna camera disponibile.', 'text-domain' );
// ...
esc_html__( 'La preghiamo di contattarci sulla nostra %1$s oppure via %2$s', 'text-domain' )
// ...
esc_html__( 'Pagina di Contatto', 'text-domain' )
// ...
esc_html__( 'Email', 'text-domain' )
Ecco fatto, struttura semplice e che esegue correttamente l'escape e lo scambio di argomenti.
Leggi di più su internazionalizzazione per temi e internazionalizzazione per plugin.

Non sono sicuro di quanto bene il secondo esempio funzionerebbe per tutte le lingue, come quelle che utilizzano una struttura di frase diversa dall'inglese. Non sarebbe meglio non dividere le frasi o separare le parole?

@shea Non sono sicuro di cosa tu stia chiedendo, ma, ad esempio, anche questa riga esc_html__( '%1$s%2$s%3$s%4$s%5$s', 'text-domain' )
può essere modificata in %3$s%2$s%1$s%4$s%5$s
con una traduzione. Questa flessibilità nell'ordinamento dovrebbe coprire le diverse strutture linguistiche.

Non tutte le lingue hanno una sola parola per "o", o formuleranno frasi come "Per favore contattaci sul nostro <link>". Sto dicendo che un metodo migliore sarebbe fornire frasi o espressioni complete da tradurre, e poi lasciare che i traduttori facciano ciò che è necessario per tradurle. Il metodo dello scambio di argomenti sembra eccessivamente disordinato e inefficace

Penso che la risposta di @Fayaz sia molto buona; sono sicuramente sulla strada giusta nel suggerire di usare sprintf() attorno alle traduzioni per includere elementi come HTML e link.
Tuttavia, non credo sia una buona idea dividere le frasi in parti per la traduzione, poiché molte lingue hanno strutture di frase completamente diverse dall'inglese. Dividendo le singole parole, si perde molto del contesto in cui una parola specifica viene tradotta, potenzialmente portando ad ambiguità ed errori di traduzione.
Invece, consiglio di tradurre intere frasi e poi usare sprintf
o diverse funzioni di escaping dove appropriato.
Per il tuo testo, la prima parte può essere semplicemente tradotta da sola con esc_html_e
:
esc_html_e( 'Gentile Ospite, con le informazioni fornite al momento non abbiamo trovato alcuna camera disponibile. ', 'text-domain' );
La seconda parte è leggermente più complessa. Ora, presumo che tu stia recuperando l'URL della pagina e l'email dal database in qualche modo, probabilmente usando get_the_permalink()
o get_option()
o qualche altra funzione. Quindi assumerò che siano memorizzati nelle variabili $contact_page_url
e $contact_email
.
Il primo passo è tradurre la stringa, senza i link. Nota che dobbiamo usare __()
senza escaping a questo punto - quello verrà dopo.
__( 'Per favore contattaci nella nostra <a href="%1$s">pagina di contatto</a> o via email %2$s.', 'text-domain' );
In questo modo il traduttore è libero di formulare la frase come necessario e posizionare l'URL del link e l'email dove serve.
Il passo successivo è usare sprintf()
per inserire l'URL del link e l'email. Nota che usiamo esc_url()
qui per eseguire l'escape dell'URL, e anche antispambot()
per codificare l'indirizzo email e fornire una protezione minima contro gli scraper:
$text = sprintf(
__( 'Per favore contattaci nella nostra <a href="%1$s">pagina di contatto</a> o via email %2$s.', 'text-domain' ),
esc_url( $contact_page_url ),
sprintf( '<a href="mailto:%1$s">%1$s</a>', antispambot( $contact_email ) )
);
Infine, invece di usare esc_html()
, dobbiamo usare wp_kses()
per permettere solo elementi link nell'HTML tradotto:
echo wp_kses( $text, array( 'a' => array( 'href' => array() ) );
Ecco tutto! Il codice finale è:
esc_html_e( 'Gentile Ospite, con le informazioni fornite al momento non abbiamo trovato alcuna camera disponibile. ', 'text-domain' );
$text = sprintf(
__( 'Per favore contattaci nella nostra <a href="%1$s">pagina di contatto</a> o via 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 piace la tua idea con wp_kses
. Tuttavia, ci sono due punti (1) un traduttore potrebbe aggiungere link aggiuntivi nella traduzione e il tuo CODICE non lo impedirebbe. (2) un traduttore dovrebbe fornire HTML
, cioè <a href="%1$s">..</a>
all'interno della traduzione. Potresti non volerlo, poiché potrebbero commettere errori nella gestione anche del più semplice tag HTML <a>
.

Giusto @Fayaz, sono punti validi. Se pensi che siano i più importanti, allora potresti voler utilizzare una soluzione diversa :)

+1 per alcuni buoni punti comunque. Poiché la tua soluzione ha questi problemi, ho aggiornato la mia soluzione (Metodo-3) con una struttura più semplice questa volta.
