web-dev-qa-db-fra.com

Supprimer les pages parent de Permalink

Des questions similaires ont déjà été posées, mais aucune réponse ne convient.

J'ai: site.com/parent-page/child-page et aimerais avoir: site.com/child-page

Je souhaite donc uniquement avoir des permaliens avec la profondeur 1, sans utiliser le menu personnalisé, mais tout en "hiérarchisant" mes pages dans la vue admin de toutes les pages et avec les attributs parent/ordre dans la page.

La solution doit également fonctionner automatiquement. Par conséquent, ne modifiez pas les liens permanents sur chaque page avec le plug-in "Liens permanents personnalisés".

C’est ce dont j’ai besoin, et je suis sûr que c’est possible avec quelques lignes de code dans le functions.php, que j’ai trouvé ailleurs, mais uniquement pour les publications supprimant la catégorie, mais ne fonctionnant pas pour les pages supprimant le parent.

C’est un code qui peut être modifié pour fonctionner pour pages ?

add_filter( 'post_link', 'remove_parent_cats_from_link', 10, 3 );
function remove_parent_cats_from_link( $permalink, $post, $leavename ) {
    $cats = get_the_category( $post->ID );
    if ( $cats ) {
        // Make sure we use the same start cat as the permalink generator
        usort( $cats, '_usort_terms_by_ID' ); // order by ID
        $category = $cats[0]->slug;
        if ( $parent = $cats[0]->parent ) {
            // If there are parent categories, collect them and replace them in the link
            $parentcats = get_category_parents( $parent, false, '/', true );
            // str_replace() is not the best solution if you can have duplicates:
            // example.com/luxemburg/luxemburg/ will be stripped down to example.com/
            // But if you don't expect that, it should work
            $permalink = str_replace( $parentcats, '', $permalink );
        }
    }
    return $permalink;
}
7
Sofian

tl; dr = Installez le plug-in gratuit " Permalinks Customizer ". Définissez "Paramètres PostTypes" pour les pages sur '% postname%', puis modifiez les pages pour modifier les liens permanents correspondants en conséquence. J'ai testé cela avec un scénario de pages hiérarchiques et non hiérarchiques, et ivt fonctionne sans aucune difficulté.


La réponse la plus longue
Le scénario du PO repose sur une page générique et, à mon avis, cela représente un défi important, voire impossible, car la solution doit s'appliquer de manière anonyme. Autrement dit, il n’existe pas de "déclencheur" ou de "descripteur" prévisible qui puisse être utilisé pour créer une réécriture créant une demande valide. Un type de message personnalisé pourrait travail (ou pas), mais le PO a exclu cette option. L'approche proposée par le PO comporte également le risque de doublons. Compte tenu de tout cela, on pourrait penser que l'approche proposée par le PO n'est ni valable ni sage - mais je laisserai cela à l'OP de se juger lui-même.

Le PO est tout à fait correct. la réponse proposée par Nicu ne fonctionne pas car cette ligne a pour effet de construire l'uri à partir de la filiation d'origine.

$uri = get_post( $parent )->post_name . "/" . $uri;

J'ai (sans succès) travaillé sur un filtre qui répondrait aux exigences de l'OP. Je le propose ici au cas où cela pourrait être utile à quelqu'un d'autre. À des fins de référence, tous mes tests ont été effectués avec les permaliens réglés sur "Nom du post", et chaque fois que je modifiais un filtre, je rafraîchissais la page des permaliens. J'ai créé quatre pages. Ascendance, Parents (parent = 'Ascendance'), Enfants (parent = 'Parents') et Transport (pas de parent).

J'ai trouvé que la création de l'URI est la partie facile, ou du moins semble facile. Cette alternative (dans functions.php) fonctionne:

function wpse_182006_pages_permalink( $link, $post_id) {

    // get the post_type and evaluate
    $posttype = get_post_field( 'post_type', $post_id, 'display' );
    if ($posttype !== 'page'){
        return link;
    }

    // build the uri from the slug
    $slugname = get_post_field( 'post_name', $post_id, 'display' );
    $slugname = $slugname."/";
    $link = home_url($slugname);
    return $link;

}

add_filter( 'page_link', 'wpse_182006_pages_permalink', 10, 3 );

Les pages "Ancestry" et "Transport" s'ouvrent normalement.
Les pages "Parents" et "Enfants" (comportant chacune une page "parent") comportent 404 erreurs.
Si vous examinez la requête de requête (voir ci-dessous), il est évident que la 404 est générée car WordPress interprète la "page" comme une "publication" et aucune publication de ce type n'existe. Notez que l'ID de publication n'est pas utilisé dans les requêtes ayant échoué. C’est peut-être la clé d’une réécriture réussie, mais c’était au-delà de mes capacités.

Pour référence, ce sont les détails de "demande" pour "Ancestry":
Requête correspondante = 'pagename = ancestory & page ='
Matched Rule = '(... +?) (?:/([0-9] +))? /? $'
Requête principale = SELECT wp_posts. * FROM wp_posts WHERE 1 = 1 AND (wp_posts.ID = '46') AND wp_posts.post_type = 'page' ORDER BY wp_posts.post_date DESC

Par comparaison, il s’agit de "demande" de détails pour "Enfants":
Requête correspondante = 'name = children & page ='
Matched Rule = '([^ /] +) (?:/([0-9] +))? /? $'
Requête principale = SELECT wp_posts. * FROM wp_posts WHERE 1 = 1 AND wp_posts.post_name = 'parents' AND wp_posts.post_type = 'post' ORDER BY wp_posts.post_date DESC


FWIW, en définissant le permalien de cette manière, le permalien n’est pas éditable. Avant:
 enter image description here 

Après:
 enter image description here 

1
Tedinoz

une recherche rapide montre un autre sujet stackexchange sur ce sujet, et il utilise ce code pour nettoyer le lien permanent des parents/ancêtres:

function wpse_101072_flatten_hierarchies( $post_link, $post ) {
    if ( 'page' != $post->post_type )
        return $post_link;

    $uri = '';
    foreach ( $post->ancestors as $parent ) {
        $uri = get_post( $parent )->post_name . "/" . $uri;
    }

    return str_replace( $uri, '', $post_link );
}
add_filter( 'post_type_link', 'wpse_101072_flatten_hierarchies', 10, 2 );

Vous pouvez trouver cette discussion ici: Supprimer le slug parent de l'URL sur le type de message personnalisé

1
Nicü