Comment définir une relation parent-enfant entre différents types d'articles personnalisés

10

Je viens de mettre en place une relation post / parent entre un "épisode" de type post et un type "série-dessin animé".

J'ai utilisé ce bit de code pour ajouter dans la boîte de méta afin d'affecter le parent d'un autre type de message:

add_action('admin_menu', function() {
    remove_meta_box('pageparentdiv', 'episodes', 'normal');
});
add_action('add_meta_boxes', function() {
    add_meta_box('episodes-parent', 'Cartoon Series', 'episodes_attributes_meta_box', 'episodes', 'side', 'default');
});

function episodes_attributes_meta_box($post) {
    $post_type_object = get_post_type_object($post->post_type);
    if ( $post_type_object->hierarchical ) {
        $pages = wp_dropdown_pages(array('post_type' => 'cartoon-series', 'selected' => $post->post_parent, 'name' => 'parent_id', 'show_option_none' => __('(no parent)'), 'sort_column'=> 'menu_order, post_title', 'echo' => 0));
        if ( ! empty($pages) ) {
            echo $pages;
        } // end empty pages check
    } // end hierarchical check.
}

Cela a fonctionné sur l'écran d'administration en me permettant de définir la série en tant que parent pour l'épisode, mais lorsque j'essaie de voir le message, je reçois un 404. La structure de l'URL est la suivante:

domain/episodes/series-name/episode-name

L'URL de la série est:

domain/cartoon-series/series-name

J'aimerais que l'URL de l'épisode soit:

domain/cartoon-series/series-name/episode-name

Qu'est-ce qui me manque? Est-il possible de faire taper un message entier sur l'enfant d'un autre type de message? Alors, je pourrais même obtenir l’URL de la liste des épisodes:

domain/cartoon-series/series-name/episodes

Merci! Matt

Comme demandé, voici le code des deux types de publication personnalisés en question:

$labels = array(
    "name" => "Cartoon Series",
    "singular_name" => "Cartoon Series",
    "menu_name" => "Cartoon Series",
    "all_items" => "All Cartoon Series",
    "add_new" => "Add New",
    "add_new_item" => "Add New Cartoon Series",
    "edit" => "Edit",
    "edit_item" => "Edit Cartoon Series",
    "new_item" => "New Cartoon Series",
    "view" => "View",
    "view_item" => "View Cartoon Series",
    "search_items" => "Search Cartoon Series",
    "not_found" => "No Cartoon Series Found",
    "not_found_in_trash" => "No Cartoon Series Found in Trash",
    "parent" => "Parent Cartoon Series",
    );

$args = array(
    "labels" => $labels,
    "description" => "",
    "public" => true,
    "show_ui" => true,
    "has_archive" => true,
    "show_in_menu" => true,
    "exclude_from_search" => false,
    "capability_type" => "post",
    "map_meta_cap" => true,
    "hierarchical" => true,
    "rewrite" => array( "slug" => "cartoon-series", "with_front" => true ),
    "query_var" => true,
    "supports" => array( "title", "revisions", "thumbnail" ),           );
register_post_type( "cartoon-series", $args );

$labels = array(
    "name" => "Episodes",
    "singular_name" => "Episode",
    );

$args = array(
    "labels" => $labels,
    "description" => "",
    "public" => true,
    "show_ui" => true,
    "has_archive" => true,
    "show_in_menu" => true,
    "exclude_from_search" => false,
    "capability_type" => "post",
    "map_meta_cap" => true,
    "hierarchical" => true,
    "rewrite" => array( "slug" => "episodes", "with_front" => true ),
    "query_var" => true,
    "supports" => array( "title", "revisions", "thumbnail" ),           );
register_post_type( "episodes", $args );

J'utilise le plug-in CPT UI, je ne peux donc pas éditer ce code directement. C’est juste le code d’exportation fourni par l’interface utilisateur CPT.

Je n'ai pas d'autre code reliant les deux CPT. Peut-être que c'est ce qui me manque. Je viens de trouver ce code en ligne qui place la metabox sur la page pour faire le lien. N'est-ce pas suffisant de faire le travail? On dirait que cela définit le post_parent.

Merci! Matt

    
posée Mattaton 13.03.2015 - 23:20

3 réponses

8

Enfin, j'ai trouvé une solution efficace. La série de dessins animés peut être enregistrée comme vous l'avez fait, mais les types de publication d'épisodes personnalisés ne peuvent pas être hiérarchiques (je pense que WordPress s'attend à ce que le contenu parent soit du même type que le contenu enfant si la relation est définie à l'aide de post_parent dans la table de base de données wp_posts ).

Lors de l'enregistrement d'épisodes, la règle de réécriture doit être définie sur le slug souhaité, à savoir cartoon-series/%series_name% . Ensuite, nous pouvons filtrer le lien épisodes pour remplacer %series_name% par le nom réel du type de message parent cartoon-series et une règle de réécriture à indiquer à WordPress lorsqu’un type de message de série de dessin animé est demandé et à quel moment correspond à un épisode.

add_action('init', function(){
    $labels = array(
        "name" => "Cartoon Series",
        "singular_name" => "Cartoon Series",
        "menu_name" => "Cartoon Series",
        "all_items" => "All Cartoon Series",
        "add_new" => "Add New",
        "add_new_item" => "Add New Cartoon Series",
        "edit" => "Edit",
        "edit_item" => "Edit Cartoon Series",
        "new_item" => "New Cartoon Series",
        "view" => "View",
        "view_item" => "View Cartoon Series",
        "search_items" => "Search Cartoon Series",
        "not_found" => "No Cartoon Series Found",
        "not_found_in_trash" => "No Cartoon Series Found in Trash",
        "parent" => "Parent Cartoon Series",
    );

    $args = array(
        "labels" => $labels,
         "description" => "",
        "public" => true,
        "show_ui" => true,
        "has_archive" => true,
        "show_in_menu" => true,
        "exclude_from_search" => false,
        "capability_type" => "post",
        "map_meta_cap" => true,
        "hierarchical" => true,
        "rewrite" => array( "slug" => "cartoon-series", "with_front" => true ),
        "query_var" => true,
        "supports" => array( "title", "revisions", "thumbnail" )
    );

    register_post_type( "cartoon-series", $args );

    $labels = array(
        "name" => "Episodes",
        "singular_name" => "Episode",
    );

    $args = array(
        "labels" => $labels,
        "description" => "",
        "public" => true,
        "show_ui" => true,
        "has_archive" => true,
        "show_in_menu" => true,
        "exclude_from_search" => false,
        "capability_type" => "post",
        "map_meta_cap" => true,
        "hierarchical" => false,
        "rewrite" => array( "slug" => "cartoon-series/%series_name%", "with_front" => true ),
        "query_var" => true,
        "supports" => array( "title", "revisions", "thumbnail" )
    );

    register_post_type( "episodes", $args );

});

add_action('add_meta_boxes', function() {
    add_meta_box('episodes-parent', 'Cartoon Series', 'episodes_attributes_meta_box', 'episodes', 'side', 'default');
});

function episodes_attributes_meta_box($post) {
        $pages = wp_dropdown_pages(array('post_type' => 'cartoon-series', 'selected' => $post->post_parent, 'name' => 'parent_id', 'show_option_none' => __('(no parent)'), 'sort_column'=> 'menu_order, post_title', 'echo' => 0));
        if ( ! empty($pages) ) {
            echo $pages;
        } // end empty pages check
}

add_action( 'init', function() {

    add_rewrite_rule( '^cartoon-series/(.*)/([^/]+)/?$','index.php?episodes=$matches[2]','top' );

});

add_filter( 'post_type_link', function( $link, $post ) {
    if ( 'episodes' == get_post_type( $post ) ) {
        //Lets go to get the parent cartoon-series name
        if( $post->post_parent ) {
            $parent = get_post( $post->post_parent );
            if( !empty($parent->post_name) ) {
                return str_replace( '%series_name%', $parent->post_name, $link );
            }
        } else {
            //This seems to not work. It is intented to build pretty permalinks
            //when episodes has not parent, but it seems that it would need
            //additional rewrite rules
            //return str_replace( '/%series_name%', '', $link );
        }

    }
    return $link;
}, 10, 2 );

REMARQUE : n'oubliez pas de vider les règles de réécriture après avoir enregistré le code ci-dessus et avant de l'essayer. Accédez à wp-admin/options-permalink.php et cliquez sur Enregistrer pour regénérer les règles de réécriture.

NOTE 2 : il est probablement nécessaire d'ajouter davantage de règles de réécriture, par exemple pour travailler avec les publications paginées. De plus, il faudra peut-être plus de travail pour avoir une solution complète, par exemple, lorsque vous supprimez un cartoon-series , supprimez également tous les épisodes enfants? Ajouter un filtre dans l'écran d'édition d'administrateur pour filtrer les épisodes par post parent? Modifier le titre des épisodes dans l'écran de modification de l'administrateur pour afficher le nom de la série parent?

    
réponse donnée cybmeta 14.03.2015 - 21:44
0

Pas besoin de codage dur dans ce cas ... Vous pouvez simplement utiliser ce plugin:

enlace

Vous pouvez même en récupérer le code. Cependant, il se peut que ce ne soit pas une solution complète.

    
réponse donnée T.Todua 07.02.2017 - 09:29
-1

Vous devrez écrire votre propre code d’analyse d’URL car Wordpress doit connaître le type de publication qu’il cherche à extraire de la base de données en fonction de la structure de l’URL et celle-ci ne donne aucune indication à cet égard.

Ceci n’est pas très facile à faire avec l’API de règles de réécriture de wordpress, mais rien ne vous empêche de contourner le mécanisme de réécriture et d’analyser vous-même les URL. Quelque chose comme 1. Exécutez les règles WordPress Rewite. Si un contenu a été trouvé, affiche-le et quitte 2. obtenir la première partie de l'URL, vérifiez s'il existe un message correspondant à ce slug avec le type de message attendu 3. boucle sur les parties restantes de l'URL vérifier que les messages existent et sont dans le bon type. 4. si tout correspond, affiche le dernier message trouvé, sinon affiche une page 404

    
réponse donnée Mark Kaplun 14.03.2015 - 20:28

Lire d'autres questions sur les étiquettes