web-dev-qa-db-fra.com

Plusieurs liens permanents pour un même message

Je voudrais pouvoir avoir plusieurs permaliens pour le même post sous-jacent (pour des raisons d'i18n) - par exemple

http://www.example.com/my-custom-post-type/this-is-a-cool-article
http://www.example.com/mon-type-de-poste-personnalise/cest-un-article-sympa

Les deux pointant vers la même page de publication. Les fonctions WP i18n intégrées traitent du changement de langue sur la page de publication elle-même. Je suis plus préoccupé par l'affichage des URL pour le référencement et l'esthétique de l'utilisateur final.

Je ne peux pas utiliser une redirection 301 car je ne souhaite pas que l'URL du navigateur change. Je comprends comment internationaliser le slug de type de message personnalisé, mais pas le slug de message réel.

Je pense que je peux sauvegarder le slug de post secondaire dans un méta-champ de post, mais je devrais accrocher quelque part dans le routage pour l'activer - je n'ai pas eu beaucoup de chance de trouver le bon endroit pour accrocher? Y a-t-il un endroit où accrocher ou un moyen plus facile de gérer cela?

2
Roscius

L'analyse de la demande est traitée dans WP::parse_request(). Après cela, il y a un crochet d’action parse_request qui vous donne l’instance de l’objet wp.

Nous supposons que http://www.example.com/my-custom-post-type/this-is-a-cool-article est votre lien permanent et que http://www.example.com/mon-type-de-poste-personnalise/cest-un-article-sympa se termine en 404. La première chose à vérifier dans votre rappel devrait être, si l'objet wp est dans un état d'erreur/404:

if ( ! empty( $wp->query_vars[ 'error' ] && 404 == $wp->query_vars[ 'error' ] ) {
    //…
}

Edit: j’ai commis une erreur: ce n’est pas sûr, le statut $wp est toujours 404 sur votre URL alias. Cela dépend fortement des règles de réécriture de votre système. Vous devez donc vérifier directement votre slug cpt slug.

Maintenant, vous devez analyser vous-même la demande et rechercher votre méta-valeur pour trouver l'article correspondant:

if ( ! empty( $wp->query_vars[ 'error' ] && '404' == $wp->query_vars[ 'error' ] ) {

    //look up for your post, this var should looks like 
    // 'mon-type-de-poste-personnalise/cest-un-article-sympa' in your case:
    $wp->request;
    //e.g.
    $parts = explode( '/', $wp->request );
    // your language slug
    $slug = ( isset( $parts[ 1 ] ) ) ? $parts[ 1 ] : '';
    // do your query with your meta value $slug here

}

La prochaine chose à faire est de configurer le $wp->query_vars tel qu’il se présenterait lorsque nous ferions face à la requête initiale:

if ( ! empty( $wp->query_vars[ 'error' ] && '404' == $wp->query_vars[ 'error' ] ) {

    //look up for your post, this var should looks like 
    // 'mon-type-de-poste-personnalise/cest-un-article-sympa' in your case:
    $wp->request;
    //e.g.
    $parts = explode( '/', $wp->request );
    // your i18n post slug
    $slug = ( isset( $parts[ 1 ] ) ) ? $parts[ 1 ] : '';
    // do your query with your meta value $slug here
    // and setup the WP_Post object for the matching post
    $matching_post; // WP_Post

    // if you don't find any post, return here!

    // unset the error flag
    unset( $wp->query_vars[ 'error' ] );

    // your cpt slug
    $cpt_slug = 'my-custom-post-type';

    $wp->query_vars[ $cpt_slug ] = $matching_post->post_name;
    $wp->query_vars[ 'post_type' ] = $cpt_slug;
    $wp->query_vars[ 'name' ] = $matching_post->post_name;
}

La dernière chose à faire est d'empêcher WordPress de rediriger automatiquement vers l'URL canonique en supprimant la fonction redirect_canonical de l'action template_redirect:

if ( ! empty( $wp->query_vars[ 'error' ] && '404' == $wp->query_vars[ 'error' ] ) {

    //look up for your post, this var should looks like 
    // 'mon-type-de-poste-personnalise/cest-un-article-sympa' in your case:
    $wp->request;
    //e.g.
    $parts = explode( '/', $wp->request );
    // your language slug
    $slug = ( isset( $parts[ 1 ] ) ) ? $parts[ 1 ] : '';
    // do your query with your meta value $slug here
    // and setup the WP_Post object for the matching post
    $matching_post; // WP_Post

    # unset the error flag
    unset( $wp->query_vars[ 'error' ] );

    # your cpt slug
    $cpt_slug = 'my-custom-post-type';

    $wp->query_vars[ $cpt_slug ] = $matching_post->post_name;
    $wp->query_vars[ 'post_type' ] = $cpt_slug;
    $wp->query_vars[ 'name' ] = $matching_post->post_name;

    # don't redirect to the canonical url
    remove_action( 'template_redirect', 'redirect_canonical' );
}

Placez le dernier codeblock dans une fonction et appliquez-le à l'action parse_request:

add_action( 'parse_request', 'wpse_126309_parse_request' );

/**
 * @wp-hook parse_request
 * @param WP $wp
 * @return void
 */
function wpse_126309_parse_request( $wp ) {
    // the code goes here
}

Vous devriez tester cet exemple (ce n'est pas plus qu'une preuve de concept) pour les effets secondaires.

3
David