Localización de "slugs" en el tema (tipos de contenido personalizados, taxonomías)

2 oct 2011, 14:02:29
Vistas: 24.4K
Votos: 17

en mi tema quiero definir una serie de tipos de contenido personalizados y taxonomías personalizadas, cada una con su propio slug personalizado; el idioma base de mi tema es inglés, por lo tanto los slugs estarán en inglés

por ejemplo, al definir el slug de un tipo de contenido personalizado "product" en los argumentos:

'rewrite' => array( 'slug' => 'producto' ),

¿hay alguna manera de traducir el "slug" a través de archivos po/mo? ¿puedo ponerlo como:

'rewrite' => array( 'slug' => __('producto', 'mytextdomain') )

¿o no funcionará? ¿cuál es la práctica actual para localizar slugs?

4
Comentarios

No sé si estamos tratando el mismo problema pero parece que sí. Para ilustrarlo mejor aquí hay un enlace a una página index original para un tipo de entrada personalizado llamado prensa con un slug configurado como prensa. Usando WPML el slug de la página traducida es press ya que no puede ser prensa otra vez: /en/press/ que no muestra nada (nota que ahora hacer clic en el enlace ES no te lleva de vuelta a /prensa/). PERO, si visitas /en/prensa/ sí funciona...

Naoise Golden Naoise Golden
10 oct 2011 19:45:59

Decidí redirigir las páginas desde /en/press a /en/prensa por lo que probablemente el enlace ya no funcione como se mencionó. Lástima no poder usar el slug localizado pero tener algo funcional a tiempo es mejor que URLs amigables con la localización

Naoise Golden Naoise Golden
10 oct 2011 20:00:05

Mira mi respuesta Naoise, creo que te dará una solución funcional.

chrisguitarguy chrisguitarguy
10 oct 2011 20:31:07

Tuve este problema durante horas. Finalmente encontré una solución alternativa: https://github.com/stouch/wp-plugin-polylang-localized-taxonomy-slug/blob/master/functions.php Saludos.

Sylvain Tch Sylvain Tch
14 jul 2019 15:12:04
Todas las respuestas a la pregunta 6
7
21

No intentaría localizar tus slugs. En su lugar, ¿por qué no darles a tus usuarios la opción de cambiarlos agregando otro campo a la página de configuración de enlaces permanentes?

Conéctate a load-options-permalink.php y configura algunos elementos para capturar los datos de $_POST y guardar tu slug. También añade un campo de configuración a la página.

<?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'] ) );
    }

    // Añade un campo de configuración a la página de enlaces permanentes
    add_settings_field( 'wpse30021_cpt_base', __( 'Base CPT' ), 'wpse30021_field_callback', 'permalink', 'optional' );
}

Luego, la función de retorno para el campo de configuración:

<?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" />';
}

Cuando registres tu tipo de contenido, obtén el slug con get_option. Si no está, usa tu valor predeterminado.

<?php
add_action( 'init', 'wpse30021_register_post_type' );
function wpse30021_register_post_type()
{
    $slug = get_option( 'wpse30021_cpt_base' );
    if( ! $slug ) $slug = 'tu-slug-predeterminado';

    // registra tu tipo de contenido, referencia $slug para la reescritura
    $args['rewrite'] = array( 'slug' => $slug );

    // Obviamente probablemente necesites más $args que uno...
    register_post_type( 'wpse30021_pt', $args );
}

Aquí está la parte del campo de configuración como un plugin https://gist.github.com/1275867

EDITAR: Otra Opción

También podrías cambiar el slug basado en lo que está definido en la constante WPLANG.

Solo escribe una función rápida que contenga datos...

<?php
function wpse30021_get_slug()
{
    // retorna un slug predeterminado
    if( ! defined( 'WPLANG' ) || ! WPLANG || 'en_US' == WPLANG ) return 'prensa';

    // array de datos de slugs
    $slugs = array( 
        'fr_FR' => 'presse',
        'es_ES' => 'prensa'
        // etc.
    );

    return $slugs[WPLANG];
}

Luego obtén el slug donde registres tu tipo de contenido personalizado.

<?php
add_action( 'init', 'wpse30021_register_post_type' );
function wpse30021_register_post_type()
{
    $slug = wpse30021_get_slug();

    // registra tu tipo de contenido, referencia $slug para la reescritura
    $args['rewrite'] = array( 'slug' => $slug );

    // Obviamente probablemente necesites más $args que uno...
    register_post_type( 'wpse30021_pt', $args );
}

La mejor opción, en mi opinión, sería tanto darle al usuario una opción como proporcionar valores predeterminados sólidos:

<?php
add_action( 'init', 'wpse30021_register_post_type' );
function wpse30021_register_post_type()
{
    $slug = get_option( 'wpse30021_cpt_base' );
    // No configuraron una opción, obtén el predeterminado
    if( ! $slug ) $slug = wpse30021_get_slug();

    // registra tu tipo de contenido, referencia $slug para la reescritura
    $args['rewrite'] = array( 'slug' => $slug );

    // Obviamente probablemente necesites más $args que uno...
    register_post_type( 'wpse30021_pt', $args );
}
10 oct 2011 20:27:57
Comentarios

+1 por el plugin en gist y el código bien documentado. En mi caso, sin embargo, pierde el propósito, que es no dar poder al usuario sino crear URLs conscientes de la localización (amigables para SEO) para tipos de posts personalizados

Naoise Golden Naoise Golden
11 oct 2011 20:01:06

No estoy seguro de entender por qué querrías eliminar una opción de tu usuario. Además, pasar un slug por un filtro de traducción les da la misma opción: cambiar el slug. Solo que no con un bonito campo de formulario para rellenar.

chrisguitarguy chrisguitarguy
12 oct 2011 19:05:00

solo por curiosidad, ¿por qué wpse30021?

Naoise Golden Naoise Golden
17 oct 2011 12:29:04

Parece que esta opción es para una localización basada en WPLANG. Pero, ¿qué pasa si estás trabajando con un sitio multilingüe? (por ejemplo, el plugin WPML). La pregunta es más acerca de mostrar un slug diferente dependiendo de la localización del cliente, que de poder establecer un slug de tipo de entrada personalizado desde las opciones del servidor.

Naoise Golden Naoise Golden
17 oct 2011 12:33:18

wpse = WordPress stack exchange. 30021 es el número de la URL. Buena suerte en tu búsqueda; he dado mi respuesta. La complejidad adicional que estás añadiendo, y el aparente cambio completo de la pregunta original — originalmente sobre slugs de CPT— solo refuerza el caso para permitir que el usuario final elija su propio slug.

chrisguitarguy chrisguitarguy
17 oct 2011 16:27:13

La pregunta es si la función __() puede usarse con slugs, y "cuál es la práctica para localizar slugs". Eso podría interpretarse como tener un slug traducido como lo hace una cadena cuando ves un tema en un idioma determinado, independientemente de que se use en un CPT. Por eso se colocó la recompensa en primer lugar.

Naoise Golden Naoise Golden
18 oct 2011 16:38:41

Teniendo en cuenta que desde WordPress 4.7 los usuarios pueden establecer un idioma preferido para su perfil, usar una opción de la base de datos es en realidad la solución preferida. Si un usuario ha seleccionado un idioma diferente al del sitio y desencadena un reinicio de los enlaces permanentes, por ejemplo al visitar la configuración de enlaces permanentes, entonces la traducción del slug de la publicación cambiará a la del usuario, lo cual no es deseable que ocurra.

Gchtr Gchtr
30 jul 2020 18:56:16
Mostrar los 2 comentarios restantes
0

Estoy haciendo exactamente eso en un tema que estamos desarrollando. Está disponible en 5 idiomas distintos, y cada idioma tiene un conjunto de categorías traducidas. El primer componente de la URL en el tema se analiza para determinar qué idioma se usa, en formato país-idioma:

/uk-en
/fr-fr
/it-it

Y luego las categorías traducidas se analizan como componentes adicionales de la URL.

La URL se analiza en la fase 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 );

    // Determinar el idioma desde $components[0]
    $language = array_shift( $components );
    ...

    // Cargar archivo de traducciones...
    $mofile = get_stylesheet_directory()."/$language.mo";

    load_textdomain( 'mydomain', $mofile );

    ...

    // Determinar categoría desde $components[0]
    if( __( 'some-category', 'mydomain' ) == $components[0] )
      $wp->query_vars['category'] = 'some-category';

    ...
}
add_action( 'parse_request', 'my_parse_request' );

Este ejemplo carece de las comprobaciones necesarias, pero solo pretende ser un ejemplo.

Hay desventajas en este enfoque, por supuesto, pero permite URLs naturales en todos los idiomas. Las principales desventajas que veo son:

1) No hace uso del mecanismo de enlaces permanentes. Esto probablemente podría extenderse para que se generen las reglas de enlaces permanentes adecuadas para todos los idiomas y parse_request no sea necesario, pero hacerlo para todos los idiomas implicaría cargar un archivo MO tras otro en un bucle, y no sé qué tan bien soportado está eso.

2) Si un traductor cambia un slug, entonces los enlaces se invalidan.

13 oct 2011 22:46:59
5

Si eso no funciona, ¿por qué no simplemente haces:

$post_slug = __('producto', 'midominiodetexto');
'rewrite' => array( 'slug' => $post_slug );
10 oct 2011 17:53:23
Comentarios

esto no funcionó para mí

Naoise Golden Naoise Golden
10 oct 2011 19:41:22

es básicamente el mismo código con otro estilo

Naoise Golden Naoise Golden
10 oct 2011 19:47:37

¿Has añadido el dominio de texto correcto? <?php load_theme_textdomain(my_text_domain);?> ?

chifliiiii chifliiiii
10 oct 2011 21:37:40

Esta es, sin duda, la mejor solución.

Al Rosado Al Rosado
20 abr 2017 09:44:18

¡Ten cuidado con esto! Desde WordPress 4.7, los usuarios pueden establecer un idioma preferido para su perfil. Si un usuario tiene un idioma diferente al del sitio y provoca un vaciado de los enlaces permanentes, por ejemplo, al visitar la configuración de enlaces permanentes, ¡la traducción del slug de la publicación cambiará a la del usuario! Por eso la respuesta aceptada, que utiliza una opción que se carga desde la base de datos, es en realidad una solución mucho mejor y a prueba de fallos.

Gchtr Gchtr
30 jul 2020 18:53:53
0

Yo tuve este problema y aquí está mi solución, que funciona cuando conoces los idiomas de tu sitio web de antemano. Digamos que tienes un CPT llamado "movie", y tu sitio web tiene 3 idiomas. Necesitas reescribir el permalink de tu CPT, para cada idioma. También podrías hacer esto de forma dinámica.

add_action("init", "rewrite_cpt", 10, 0);
function rewrite_cpt(){    
    add_rewrite_rule('^movie/([^/]*)/?', 'index.php?post_type=movie&name=$matches[1]', 'top'); // Inglés
    add_rewrite_rule('^film/([^/]*)/?', 'index.php?post_type=movie&name=$matches[1]', 'top');  // Italiano
    add_rewrite_rule('^фильм/([^/]*)/?', 'index.php?post_type=movie&name=$matches[1]', 'top'); // Ruso
}

Ahora solo necesitas reconstruir tus permalinks: ve a Ajustes > Enlaces permanentes y simplemente presiona "Guardar"

La siguiente parte es reescribir las URLs para tu CPT, si tienes un CPT traducido necesitas obtener el idioma del post, en mi caso uso Polylang. Es importante codificar caracteres extranjeros en las URLs

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;
}
5 abr 2020 17:53:13
1

Podrías probar esto en tu archivo functions.php

<?php
add_filter('rewrite_slugs', function($translated_slugs) {
    // las posibles traducciones para tu slug '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;
});
?>

como se ve aquí

26 mar 2015 00:43:22
Comentarios

el filtro rewrite_slugs existe en WordPress por sí mismo, el enlace que has referenciado es para el plugin wp polylang - así que eso puede ayudar a la gente que usa poly lang

jave.web jave.web
16 feb 2020 15:47:14
4
-1

Recomendaría no hacer traducibles los slugs.

La traducción es para el contenido del sitio orientado al usuario. Los slugs se usan internamente, y solo son marginalmente "visibles públicamente" mediante reescrituras de URL - y las URLs tampoco deberían ser traducibles.

Por lo tanto: deja tus slugs como los defines originalmente. Solo haz traducibles las cadenas destinadas para consumo público.

12 oct 2011 20:06:31
Comentarios

los slugs traducidos, tanto desde una perspectiva de SEO como de experiencia de usuario, tienen mucho sentido...

Naoise Golden Naoise Golden
17 oct 2011 12:20:45

No estoy de acuerdo en que los slugs afecten de alguna manera la experiencia de usuario. Si un slug se utiliza como parte de un enlace, el texto de anclaje del enlace estará traducido, por lo que el usuario no notará la diferencia. Y cuando la gente empieza a mencionar "SEO", generalmente pienso "pseudociencia". No soy un experto en SEO, pero no creo en el impacto del SEO con respecto a los slugs traducidos.

Chip Bennett Chip Bennett
17 oct 2011 14:28:10

Discrepo basado en la experiencia. Tenemos gestores de contenido extranjeros internos que son explícitos en que los slugs de las URL deben localizarse. Se trata de crear una experiencia completa/mente local para el usuario extranjero. Para algunos países, como Japón, es literalmente esencial para establecer un tipo de confianza auténtica e indicar que realmente estás serio sobre hacer negocios allí.

internetross internetross
15 feb 2013 01:13:28

Las URLs deben ser claras. Por lo tanto, si el slug es (como suele ocurrir) el nombre de la entidad o la taxonomía, la reescritura debe tener en cuenta tanto los plurales como las traducciones. Esto no es opcional, tanto para SEO como por simple buena práctica hacia los usuarios finales.

Luca Reghellin Luca Reghellin
21 dic 2015 16:11:27