web-dev-qa-db-fra.com

Réécriture de l'URL du nom de la catégorie avant les différents types de message

J'ai abordé plus d'une centaine de sujets similaires, ce qui était proche de ce dont j'avais besoin, mais malheureusement, je n'ai pas pu le peaufiner. Je m'excuse donc, s'il s'agit d'un doublon.

J'ai plusieurs types de publication (tels que Events, Venues, Places) et j'utilise également Posts, où les quatre types de publication sont connectés à la taxonomie standard WordPress Categories.

J'ai essayé d'assembler un permalien qui ressemble à ça:

http: // nom du site/sites/61312/california-venue

venues est le nom de la catégorie; 61312 est le post_id et california-venue est le nom du post.

Tous les types de publication doivent rendre la même structure:

%category%/%post_id%/%postname%/

Cette structure de lien permanent semble fonctionner parfaitement pour les publications dans Paramètres -> Permaliens, mais pas pour les autres types de publication.

Ceux avec with_front => false retournent 404, les autres fonctionnent bien, mais redirigent vers post_type/postname.

J'ai une règle de réécriture personnalisée qui ressemble à ceci:

array( 
  'regex'     => '^([^/]+)/([0-9]+)/([^/]+)?',  
  'query'       => 'category_name=$matches[1]&post_id=$matches[2]&pagename=$matches[3]', 
 )

J'ai essayé de filtrer le post_type_link et de voir si la redirection s'arrêterait. J'ai aussi essayé l'extrait de code suivant en ajoutant disable_redirect=1 à mes règles de requête:

add_filter('query_vars', 'my_public_query_vars');
function my_public_query_vars($qv)
{
    $qv[] = 'disable_redirect';
    return $qv;
}
add_filter('wp_redirect', 'my_disable_redirect');
function my_disable_redirect($location)
{
    $disable_redirect = get_query_var('disable_redirect');
    if(!empty($disable_redirect)) return false;
    return $location;
}

Cela a simplement causé un WSOD.

Comment puis-je empêcher la redirection vers mes vues uniques de chaque type de publication (la vue d'une publication semble fonctionner correctement) et conserver la structure d'URL %category%/%post_id%/%postname%?

4
Mario Peshev

Après quelques réflexions et de nombreux essais et erreurs avec T5 Rewrite et HM Rewrite, j'ai opté pour la solution la plus simple possible.

Le permalien ayant été intercepté par WordPress, je n'ai donc pas eu besoin de la règle de réécriture supplémentaire (même si cela ne faisait pas mal, hormis les performances). J'ai laissé %category%/%post_id%/%postname% en tant que permalien personnalisé par défaut, et cela semble fonctionner pour tous les types de publication jusqu'à présent.

Le slug d'origine est également traité avec élégance (lorsque des liens restants sont trouvés), mais le nouveau est celui par défaut.

J'ai joué avec template_redirect, request, redirect_canonical, query_vars, wp_redirect et d'autres hooks afin de trouver le problème et je me suis retrouvé avec ceci:

add_filter( 'request', 'sm_permalink_request_handler' );
function sm_permalink_request_handler( $request ) {
    if ( ! isset( $request['p'] ) ) {
        return $request;
    }

    // Get the post type, it's required to prevent the redirect
    $post_id = $request['p'];
    $post = get_post( $post_id );
    $request['post_type'] = $post->post_type;

    return $request;
} 


/**
 * Override get_permalink and prevent redirects
 */
function sm_fix_permalinks_for_post_types( $url, $post ) {
        $taxonomies = get_post_taxonomies();
        // See if categories are assigned to our CPT entry
        if ( ! empty( $taxonomies ) && in_array( 'category', $taxonomies ) ) {

            // Fetch all categories
            $categories = wp_get_post_categories( $post->ID, array() );

            if ( ! empty( $categories ) ) {
                // Get the main category in case there are more assigned
                // Somewhat arbitrary since it pops the last one.
                $main_category_id = array_pop( $categories );

                $main_category = get_category( $main_category_id );

                if( ! empty( $main_category ) ) {
                    $category_slug = $main_category->slug;
                    $post_id = $post->ID;
                    $post_name = $post->post_name;

                    $url = home_url( "$category_slug/$post_id/$post_name" );
                }
            }
        }

        return $url;
}

add_filter( 'post_type_link', 'sm_fix_permalinks_for_post_types', 10, 2 );

Le premier problème était lié au manque de post_type passé avec la requête. Mon permalien filtrait par nom de catégorie et par ID de publication, mais était indépendant du type de post qui interférait avec WordPress. En récupérant le message par son ID et en définissant le type_type, les choses sont redevenues normales.

Le deuxième problème était lié aux liens permanents pour les nouvelles publications, dans l’administrateur et partout autour des modèles frontaux. Une autre partie de filtrage a fait l'affaire et cela fonctionne sur tout le site.

1
Mario Peshev