web-dev-qa-db-fra.com

Changement de lieu avec une taxonomie "de langue"

Je sais qu'il est possible de changer la locale WP en utilisant des paramètres d'URL, comme décrit ici , mais j'essaie de construire une méthode qui reposerait entièrement sur une taxonomie "linguistique" personnalisée.

Ce que j'ai actuellement est un simple plugin, qui enregistre la taxonomie de la langue et implémente un commutateur de paramètres régionaux si la taxonomie est présente:

<?php
add_action( 'plugins_loaded', 'wpsx_register_taxonomies' );
function wpsx_register_taxonomies() {
register_taxonomy('wpsx_language', array (
                  0 => 'post',
                  1 => 'page',
                ), array( 
                    'hierarchical' => true, 
                    'label' => 'Languages',
                    'singular_label' => 'Language',
                    'show_ui' => true,
                    'rewrite' => false,
                    ) 
                );
}
function wpsx_redefine_locale($locale) {
    global $post;
      if ( taxonomy_exists( 'wpsx_language' )) {
        $locale = 'de_DE'; // this does work !!
        if ( has_term( 'fr', 'wpsx_language' )) {
            $locale = 'fr_FR'; // this does not work yet :(
        }   
     }
     return $locale;
}
add_filter('locale','wpsx_redefine_locale',10);
?>

Donc, la petite partie qui ne fonctionne pas est le test has_term(). Mon impression est que le filtre de paramètres régionaux s’exécute à un stade précoce de la séquence de chargement, lorsque le contenu de la publication n’a pas encore été extrait, et que les tests conditionnels tels que is_single() ou has_term() ne renvoient rien.

Puis-je forcer le contenu de la publication à charger plus tôt? Puis-je retarder le filtre de paramètres régionaux?

Je suis incapable de trouver une solution pour cela. Sur la liste de diffusion wp-hackers, une suggestion était d'exécuter global $post; mais cela n'a pas aidé.


Mise à jour: Suivant la suggestion de david.binda, j'ai trouvé une solution de contournement, abandonnant la taxonomie et utilisant le post slug comme déclencheur:

function wpsx89972_redefine_locale($locale) {
    $wpsx_url = $_SERVER['REQUEST_URI'];
    $wpsx_url_lang = substr($wpsx_url, -4); // test for the last 4 chars:
    if ( $wpsx_url_lang == "-fr/") {
        $locale = 'fr_FR';
    } else if ( $wpsx_url_lang == "-en/") { 
        $locale = 'en_US';
    } else { // fallback to default
        $locale = 'de_DE'; 
    }
    return $locale;
}
add_filter('locale','wpsx89972_redefine_locale',10);

Ceci oblige l'utilisateur à réécrire les slugs postaux, tels que "my-post-title-fr" pour le français, "my-post-title-fr" pour l'anglais, etc. Un peu moins convivial que d'utiliser des cases à cocher linguistiques, ça garde le code simple et ça marche.

Alors maintenant, j'ai un plugin multilingue fonctionnel, en seulement 13 lignes de code :)

Néanmoins, je laisserai cette question ouverte pendant quelques jours pour voir si quelqu'un propose une solution qui utiliserait la taxonomie ...

1
Manu

Vous pourriez être intéressé par la fonction url_to_postid

Utilisé comme suit depuis votre fonction wpsx_redefine_locale:

$url = $_SERVER['REQUEST_URI'];
$postid = url_to_postid( $url );

Notez que cela ne renvoie pas l’identifiant de publication pour les types de publication personnalisés, mais la fonction est située dans /wp-includes/rewrite.php et peut être étendue si nécessaire.

UPDATE: voici votre exemple:

function my_function(){
if ( ! wp_is_post_revision( $post_id ) ){

    // unhook this function so it doesn't loop infinitely
    remove_action('save_post', 'my_function');

    // update the post, which calls save_post again
    $my_post_args = array();
    $my_post_args['ID'] = post_id;
    $p = get_post( $post_id );
    $lang_tax = 'my_lang_tax_name';
    $language_terms = get_post_terms( $post_id, $lang_tax );
    $my_post_args['post_name'] = $p->name . '_' . $language_terms[0]->slug;
    wp_update_post( $my_post_args );

    // re-hook this function
    add_action('save_post', 'my_function');
}
add_action('save_posts', 'my_function');

Ce qui doit être fait plus loin, mais c'est à vous de décider. Vous devez supprimer la situation lorsque l'utilisateur a changé le terme de taxonomie de langue attribué à post, de manière à ne pas obtenir my-post_de_en au lieu de my-post_en sur la publication qui était auparavant dans de et avait my-post_de slug. Cela nécessiterait des expressions régulières, mais vous y arriverez;)

1
david.binda

Voici une meilleure solution qui ne changera rien dans votre message, mais ne fera qu'ajouter une méta

// Set the post language when loading up the page based on the store meta
function ppl_set_post_language() {
    $postID = url_to_postid( $_SERVER["REQUEST_URI"] );
    if ($postID > 0) {
        $postLanguage = esc_attr( get_post_meta( $postID, '_ppl_post_language', true ) );
        if ( ! empty( $postLanguage ) ) {
            global $locale;
            $locale = $postLanguage;
        }
    }
}
// Any call to 'url_to_postid' earlier then 'setup_theme' will generate a fatal error.
add_action('setup_theme', 'ppl_set_post_language');

Pour plus de détails, vérifiez ma réponse (sur ma propre question) ici: Définir la langue par publication

Et j'ai un plugin qui fait tout pour vous (le lien est aussi dans ma réponse)

0
Fahad Alduraibi