Localizarea slug-urilor pentru teme (tipuri de postări personalizate, taxonomii)
În tema mea vreau să definesc o serie de tipuri de postări personalizate și taxonomii personalizate, fiecare având propriul său slug personalizat; limba de bază a temei mele este engleza, prin urmare slug-urile vor fi în limba engleză
de exemplu, în timpul definirii slug-ului pentru argumentele tipului de postare personalizată "product":
'rewrite' => array( 'slug' => 'product' ),
există vreo modalitate de a traduce "slug-ul" prin fișiere po/mo? pot să-l pun astfel:
'rewrite' => array( 'slug' => __('product', 'mytextdomain') )
sau nu va funcționa? care este practica actuală pentru localizarea slug-urilor?
Nu aș încerca să localizez slug-urile tale. În schimb, de ce nu oferi utilizatorilor opțiunea de a le schimba prin adăugarea unui alt câmp în pagina de setări pentru permalink-uri?
Folosește hook-ul load-options-permalink.php
și configurează câteva elemente pentru a prelua datele din $_POST
și a salva slug-ul. Adaugă și un câmp de setări pe pagină.
<?php
add_action( 'load-options-permalink.php', 'wpse30021_load_permalinks' );
function wpse30021_load_permalinks()
{
if( isset( $_POST['wpse30021_cpt_base'] ) )
{
update_option( 'wpse30021_cpt_base', sanitize_title_with_dashes( $_POST['wpse30021_cpt_base'] ) );
}
// Adaugă un câmp de setări pe pagina de permalink-uri
add_settings_field( 'wpse30021_cpt_base', __( 'Baza CPT' ), 'wpse30021_field_callback', 'permalink', 'optional' );
}
Apoi funcția de callback pentru câmpul de setări:
<?php
function wpse30021_field_callback()
{
$value = get_option( 'wpse30021_cpt_base' );
echo '<input type="text" value="' . esc_attr( $value ) . '" name="wpse30021_cpt_base" id="wpse30021_cpt_base" class="regular-text" />';
}
Când înregistrezi tipul de postare, preia slug-ul cu get_option
. Dacă nu există, folosește valoarea implicită.
<?php
add_action( 'init', 'wpse30021_register_post_type' );
function wpse30021_register_post_type()
{
$slug = get_option( 'wpse30021_cpt_base' );
if( ! $slug ) $slug = 'slug-ul-tau-implicit';
// înregistrează tipul de postare, folosește $slug pentru rewrite
$args['rewrite'] = array( 'slug' => $slug );
// Evident, probabil ai nevoie de mai mulți $args...
register_post_type( 'wpse30021_pt', $args );
}
Aici este partea cu câmpul de setări ca plugin https://gist.github.com/1275867
EDIT: O altă opțiune
Poți de asemenea să schimbi slug-ul în funcție de ce este definit în constanta WPLANG
.
Scrie o funcție rapidă care să conțină datele...
<?php
function wpse30021_get_slug()
{
// returnează un slug implicit
if( ! defined( 'WPLANG' ) || ! WPLANG || 'en_US' == WPLANG ) return 'press';
// array cu datele slug-urilor
$slugs = array(
'fr_FR' => 'presse',
'es_ES' => 'prensa'
// etc.
);
return $slugs[WPLANG];
}
Apoi preia slug-ul când înregistrezi tipul de postare personalizat.
<?php
add_action( 'init', 'wpse30021_register_post_type' );
function wpse30021_register_post_type()
{
$slug = wpse30021_get_slug();
// înregistrează tipul de postare, folosește $slug pentru rewrite
$args['rewrite'] = array( 'slug' => $slug );
// Evident, probabil ai nevoie de mai mulți $args...
register_post_type( 'wpse30021_pt', $args );
}
Cea mai bună opțiune, în opinia mea, ar fi să oferi utilizatorului o opțiune și să furnizezi valori implicite solide:
<?php
add_action( 'init', 'wpse30021_register_post_type' );
function wpse30021_register_post_type()
{
$slug = get_option( 'wpse30021_cpt_base' );
// Dacă nu au setat o opțiune, preia valoarea implicită
if( ! $slug ) $slug = wpse30021_get_slug();
// înregistrează tipul de postare, folosește $slug pentru rewrite
$args['rewrite'] = array( 'slug' => $slug );
// Evident, probabil ai nevoie de mai mulți $args...
register_post_type( 'wpse30021_pt', $args );
}

+1 pentru plugin-ul pe gist și codul bine documentat. În cazul meu, totuși, nu își atinge scopul, care este să nu ofere putere utilizatorului, ci să creeze URL-uri conștiente de localizare (prietenoase pentru SEO) pentru tipurile personalizate de postări

Nu sunt sigur că înțeleg de ce ai vrea să elimini o opțiune de la utilizatorul tău. Mai mult, rularea unui slug printr-un filtru de traducere le oferă aceeași opțiune: să schimbe slug-ul. Doar că nu cu un câmp frumos de formular de completat.

Se pare că această opțiune este pentru o localizare bazată pe WPLANG. Dar dacă lucrezi cu un site multilingv? (de exemplu, pluginul WPML). Întrebarea se referă mai mult la afișarea unui slug diferit în funcție de localizarea clientului, decât la posibilitatea de a seta un slug pentru tipul de postare personalizată din opțiunile serverului.

wpse = WordPress stack exchange. 30021 este numărul din URL. Mult succes în căutarea ta; am dat deja răspunsul meu. Complexitatea suplimentară pe care o adaugi și schimbarea aparent completă a întrebării originale – inițial despre slug-uri pentru CPT – doar susține argumentul pentru a permite utilizatorului final să își aleagă propriul slug.

Întrebarea este dacă funcția __()
poate fi folosită cu slug-uri și "care este practica pentru a localiza slug-uri". Aceasta ar putea fi interpretată ca având un slug tradus așa cum se întâmplă cu un șir de caractere când vizualizezi o temă într-o anumită limbă, indiferent dacă este folosit într-un CPT. De aceea a fost pusă recompensa inițial.

Având în vedere că începând cu WordPress 4.7 utilizatorii pot seta o limbă preferată pentru profilul lor, utilizarea unei opțiuni din baza de date este de fapt soluția preferată. Dacă un utilizator a selectat o limbă diferită de cea a site-ului și declanșează o resetare a permalinkurilor, de exemplu prin vizitarea setărilor de permalink, atunci traducerea slug-ului postului se va schimba în cea a utilizatorului, lucru pe care nu doriți să se întâmple.

Fac exact același lucru într-o temă pe care o dezvoltăm. Este disponibilă în 5 limbi distincte, iar fiecare limbă are un set de categorii traduse. Prima componentă a URL-ului din temă este analizată pentru a determina ce limbă este utilizată, în formatul țară-limbă:
/uk-en
/fr-fr
/it-it
Iar apoi categoriile traduse sunt analizate ca componente ulterioare ale URL-ului.
URL-ul este analizat în faza parse_request
:
function my_parse_request( $wp ) {
$path = parse_url( $_SERVER['REQUEST_URI'], PHP_URL_PATH );
$components = preg_split('|/|', $path, null, PREG_SPLIT_NO_EMPTY );
// Determină limba din $components[0]
$language = array_shift( $components );
...
// Încarcă fișierul de traduceri...
$mofile = get_stylesheet_directory()."/$language.mo";
load_textdomain( 'mydomain', $mofile );
...
// Determină categoria din $components[0]
if( __( 'some-category', 'mydomain' ) == $components[0] )
$wp->query_vars['category'] = 'some-category';
...
}
add_action( 'parse_request', 'my_parse_request' );
Acest exemplu nu include verificările necesare, dar are doar scop ilustrativ.
Există dezavantaje în această abordare, desigur, dar permite URL-uri naturale în toate limbile. Principalele dezavantaje pe care le văd sunt:
1) Nu utilizează mecanismul de permalink. Acest lucru ar putea fi extins astfel încât să se genereze regulile corecte de permalink pentru toate limbile și parse_request
nu va mai fi necesar, dar pentru a face acest lucru pentru toate limbile ar implica încărcarea unui fișier MO după altul într-o buclă, și nu știu cât de bine este acceptat acest lucru.
2) Dacă un traducător modifică un slug, atunci link-urile devin invalide.

Ai adăugat domeniul text corect? <?php load_theme_textdomain(my_text_domain);?> ?

Atenție la asta! Începând cu WordPress 4.7, utilizatorii pot seta o limbă preferată pentru profilul lor. Dacă un utilizator are o limbă diferită de cea a site-ului și declanșează o resetare a legăturilor permanente, de exemplu prin vizitarea setărilor de legături permanente, atunci traducerea slug-ului articolului se va schimba în cea a utilizatorului! De aceea, răspunsul acceptat, care folosește o opțiune care se încarcă din baza de date, este de fapt o soluție mult mai bună și mai sigură.

Am avut de fapt această problemă, iată soluția mea care funcționează atunci când știi dinainte limbile site-ului tău. Să presupunem că ai un CPT numit "movie", iar site-ul tău are 3 limbi. Trebuie să rescrii permalink-ul CPT-ului pentru fiecare limbă. Ai putea face asta și dinamic.
add_action("init", "rewrite_cpt", 10, 0);
function rewrite_cpt(){
add_rewrite_rule('^movie/([^/]*)/?', 'index.php?post_type=movie&name=$matches[1]', 'top'); // Engleză
add_rewrite_rule('^film/([^/]*)/?', 'index.php?post_type=movie&name=$matches[1]', 'top'); // Italiană
add_rewrite_rule('^фильм/([^/]*)/?', 'index.php?post_type=movie&name=$matches[1]', 'top'); // Rusă
}
Acum trebuie doar să reconstruiești permalink-urile: mergi la Setări > Legături permanente și apasă "Salvează"
Următoarea parte este rescrierea URL-urilor pentru CPT-ul tău, dacă ai un CPT tradus trebuie să obții limba postării, în cazul meu folosesc Polylang. Este important să codezi caracterele străine în URL-uri
add_filter("post_type_link", "x_tours_postlink", 10, 2);
function x_tours_postlink($post_link, $post){
$urls = array(
"en" => "movie",
"it" => "film",
"ru" => "фильм"
);
if(get_post_type($post) == "movie")
$post_link = str_replace("movie", urlencode($urls[pll_get_post_language($post->ID)]), $post_link);
return $post_link;
}

Puteți încerca acest lucru în fișierul dvs. functions.php
<?php
add_filter('rewrite_slugs', function($translated_slugs) {
// traducerile posibile pentru slug-ul 'product'
$translated_slugs = array(
'product' => array(
'pt' => array(
'has_archive' => true,'rewrite' => array('slug' => 'produto'),
),
'es' => array(
'has_archive' => true,'rewrite' => array('slug' => 'producto'),
),
),
);
return $translated_slugs;
});
?>
așa cum se vede aici

Vă recomand să nu faceți slug-uri traductibile.
Traducerea este pentru conținutul site-ului destinat utilizatorilor. Slug-urile sunt folosite intern și sunt doar marginal "publice" prin intermediul rescrierii URL-urilor - iar URL-urile nu ar trebui să fie traductibile de asemenea.
Deci: lăsați slug-urile așa cum le-ați definit. Faceți traductibile doar șirurile destinate consumului public.

slug-urile traduse, atât din perspectivă SEO cât și din punct de vedere al experienței utilizatorului, au mult sens...

Nu sunt de acord că slug-urile afectează în vreun fel experiența utilizatorului. Dacă un slug este folosit ca parte a unui link, textul ancoră al link-ului va fi tradus, așa că utilizatorul nu va observa diferența. Și când oamenii încep să arunce cu termenul "SEO", în general mă gândesc "ulei de șarpe". Nu sunt expert SEO, dar nu cred în impactul SEO în ceea ce privește slug-urile traduse.

Nu sunt de acord, bazat pe experiență. Avem manageri de conținut străini în echipă care susțin explicit că slug-urile URL-urilor ar trebui localizate. Este vorba despre crearea unei experiențe complet/locale pentru utilizatorul străin. Pentru unele țări, cum ar fi Japonia, este literalmente esențial pentru a stabili un tip de încredere autentică și pentru a indica că ești cu adevărat serios în a face afaceri acolo.

URL-urile trebuie să fie intuitive. Prin urmare, dacă slug-ul este (așa cum se întâmplă adesea) numele entității sau al taxonomiei, rescrierea trebuie să ia în considerare atât formele de plural, cât și traducerile. Acest lucru nu este opțional, atât pentru SEO, cât și pur și simplu ca o bună practică față de utilizatorii finali.
