web-dev-qa-db-fra.com

Comment modéliser une hiérarchie pour les cours, les niveaux et les leçons?

Je suis un peu un wordpress noob et je plonge tête première dans un plugin de création de cours. La structure ira programme> cours> niveau> cours . À l’heure actuelle, les leçons sont définies en tant que type et niveaux de publication personnalisés, les cours et les programmes sont des taxonomies. Fondamentalement, je pourrais utiliser l’aide pour créer un chemin de navigation dans lequel vous choisissez d’abord un programme, puis un cours, puis un niveau, puis une leçon. Je me creuse la tête et je suis un peu coincé. Comme je le disais, Wordpress et php sont relativement nouveaux pour moi ...

Est-ce un moyen viable d’y parvenir en utilisant des types de poteaux et des taxonomies personnalisés? Quelqu'un a-t-il des suggestions ou des ressources? Je ne sais pas si je devrais créer un fichier de modèle de thème personnalisé pour cela, ou simplement utiliser un shortcode dans une page pour la navigation.

                 Program
                    |
                   / \
                  /   \
             Course1 Course2
                /\     /\
               /  \   /  \
             Lv1 Lv2 Lv1 Lv2
            /\   /\   /\   /\
          Lessons Lessons Lessons

Vous trouverez ci-dessous ce que j'ai pour l'instant (désolé, c'est assez long). Cela fonctionne bien, je n’ai tout simplement pas encore compris comment l’organiser. Ci-dessous, je viens de définir le type de message personnalisé et les taxonomies. C'est à peu près ça

<?php
/**
 * Plugin Name: Course Manager
 * Description: Creates Programs, Courses, Levels and Lessons
 * Version: The Plugin's Version Number, e.g.: 0.1
 */
?>
<?php
function cm_lesson_cp(){
  $labels = array(
    'name'               => _x( 'Lesson', 'post type general name' ),
    'singular_name'      => _x( 'Lesson', 'post type singular name' ),
    'add_new'            => _x( 'Add New', 'Lesson' ),
    'add_new_item'       => __( 'Add New Lesson' ),
    'edit_item'          => __( 'Edit Lesson' ),
    'new_item'           => __( 'New Lesson' ),
    'all_items'          => __( 'All Lessons' ),
    'view_item'          => __( 'View Lesson' ),
    'search_items'       => __( 'Search Lessons' ),
    'not_found'          => __( 'No Lessons found' ),
    'not_found_in_trash' => __( 'No lessons found in the Trash' ), 
    'parent_item_colon'  => '',
    'menu_name'          => 'Lessons'
  );
  $args = array(
    'labels'        => $labels,
    'description'   => 'Enter a lesson description here.',
    'public'        => true,
    'menu_position' => 4,
    'supports'      => array( 'title', 'editor', 'excerpt'),
    'has_archive'   => true,
  );
  register_post_type( 'lesson', $args ); 
  flush_rewrite_rules( false );
}
add_action( 'init', 'cm_lesson_cp' );

//Custom messages for custom post type`

function lesson_messages_cp( $messages ) {
  global $post, $post_ID;
  $messages['lesson'] = array(
    0 => '', 
    1 => sprintf( __('Lesson updated. <a href="%s">View Lesson</a>'), esc_url( get_permalink($post_ID) ) ),
    2 => __('Custom field updated.'),
    3 => __('Custom field deleted.'),
    4 => __('Lesson updated.'),
    5 => isset($_GET['revision']) ? sprintf( __('Lesson restored to revision from %s'), wp_post_revision_title( (int) $_GET['revision'], false ) ) : false,
    6 => sprintf( __('Lesson published. <a href="%s">View Lesson</a>'), esc_url( get_permalink($post_ID) ) ),
    7 => __('Lesson saved.'),
    8 => sprintf( __('Lesson submitted. <a target="_blank" href="%s">Preview Lesson</a>'), esc_url( add_query_arg( 'preview', 'true', get_permalink($post_ID) ) ) ),
    9 => sprintf( __('Lesson scheduled for: <strong>%1$s</strong>. <a target="_blank" href="%2$s">Preview Lesson</a>'), date_i18n( __( 'M j, Y @ G:i' ), strtotime( $post->post_date ) ), esc_url( get_permalink($post_ID) ) ),
    10 => sprintf( __('Lesson draft updated. <a target="_blank" href="%s">Preview Lesson</a>'), esc_url( add_query_arg( 'preview', 'true', get_permalink($post_ID) ) ) ),
  );
  return $messages;
}
add_filter( 'post_updated_messages', 'lesson_messages_cp' );


// Register Program Taxonomy


function program_taxonomy_cp() {
  $args = array();
  register_taxonomy( 'program', 'lesson', $args );
}

add_action( 'init', 'program_taxonomy_cp', 0 );

// Customize taxonomy

function program_taxonomy_setting_cp() {
  $labels = array(
    'name'              => _x( 'Program', 'taxonomy general name' ),
    'singular_name'     => _x( 'Program', 'taxonomy name' ),
    'search_items'      => __( 'Search Programs' ),
    'all_items'         => __( 'All Programs' ),
    'parent_item'       => __( 'Parent Program Category' ),
    'parent_item_colon' => __( 'Parent Program Category:' ),
    'edit_item'         => __( 'Edit Program Category' ), 
    'update_item'       => __( 'Update Program' ),
    'add_new_item'      => __( 'Add New Program' ),
    'new_item_name'     => __( 'New Program' ),
    'menu_name'         => __( 'Programs' ),
  );
  $args = array(
    'labels' => $labels,
    'hierarchical' => true,
  );
  register_taxonomy( 'program', 'lesson', $args );
}
add_action( 'init', 'program_taxonomy_setting_cp', 0 );


// Register Course Taxonomy


function course_taxonomy_cp() {
  $args = array();
  register_taxonomy( 'course', 'lesson', $args );
}

add_action( 'init', 'course_taxonomy_cp', 0 );

// Customize taxonomy

function course_taxonomy_setting_cp() {
  $labels = array(
    'name'              => _x( 'Course', 'taxonomy general name' ),
    'singular_name'     => _x( 'Course', 'taxonomy name' ),
    'search_items'      => __( 'Search Courses' ),
    'all_items'         => __( 'All Courses' ),
    'parent_item'       => __( 'Parent Course Category' ),
    'parent_item_colon' => __( 'Parent Course Category:' ),
    'edit_item'         => __( 'Edit Course Category' ), 
    'update_item'       => __( 'Update Course' ),
    'add_new_item'      => __( 'Add New Course' ),
    'new_item_name'     => __( 'New Course' ),
    'menu_name'         => __( 'Courses' ),
  );
  $args = array(
    'labels' => $labels,
    'hierarchical' => true,
  );
  register_taxonomy( 'course', 'lesson', $args );
}
add_action( 'init', 'course_taxonomy_setting_cp', 0 );


// Register Custom Taxonomy "Level"


function level_taxonomy_cp() {
  $args = array();
  register_taxonomy( 'glossary', 'term', $args );
}

add_action( 'init', 'level_taxonomy_cp', 0 );

// Customize taxonomy

function level_taxonomy_setting_cp() {
  $labels = array(
    'name'              => _x( 'Levels', 'taxonomy general name' ),
    'singular_name'     => _x( 'Level', 'taxonomy name' ),
    'search_items'      => __( 'Search Levels' ),
    'all_items'         => __( 'All Levels' ),
    'parent_item'       => __( 'Parent Level Category' ),
    'parent_item_colon' => __( 'Parent Level Category:' ),
    'edit_item'         => __( 'Edit Level Category' ), 
    'update_item'       => __( 'Update Level' ),
    'add_new_item'      => __( 'Add New Level' ),
    'new_item_name'     => __( 'New Level' ),
    'menu_name'         => __( 'Levels' ),
  );
  $args = array(
    'labels' => $labels,
    'hierarchical' => true,
  );
  register_taxonomy( 'level', 'lesson', $args );
}
add_action( 'init', 'level_taxonomy_setting_cp', 0 );
5
user57391

Votre modèle de données est intéressant. Vous pouvez répondre à cette question mieux que moi, mais je ne sais pas si nous pouvons vraiment dire, comme le fait @toscho, qu’une leçon ne sera jamais partagée entre les cours, ou qu’il n’ya pas deux niveaux ayant la même leçon.

Je crois qu'une leçon et un cours sont des choses qui ressemblent à celles d'un post, mais un niveau a moins de sens en soi et nécessite un contexte (c'est-à-dire ses leçons) pour avoir un sens.

Si je construisais cela, je relèguerais le niveau à une taxonomie de leçons, et j’utiliserais la méthode Posts 2 Posts pour relier les leçons aux cours. Ensuite, pour obtenir une leçon, je l'interrogerais directement. Pour un niveau dans un cours, j'interroge les leçons de ce niveau qui sont également liées au cours.

Pour les raisons suivantes:

  • Templating Vous bénéficiez des avantages de single-lesson.php etc. dans la hiérarchie de vos modèles. Si vous le faites à la manière de toscho, si vous souhaitez utiliser différents modèles pour les leçons, les cours, etc., vous devez effectuer quelque chose de légèrement complexe, comme introduire un conditionnel avant le rendu du modèle et le gérer vous-même.

  • Lisibilité Une requête pour post_type=lesson&level=level_one est plus lisible que post_parent=123243 (ou autre).

  • Flexibilité Voulez-vous une leçon partagée entre deux cours? Voulez-vous réutiliser les leçons à travers les niveaux? Tu peux le faire. Avec la hiérarchie simple des postes, vous devez dupliquer du matériel dans la base de données, ce qui est un casse-tête.

  • Simplicité des niveaux J'admets que c'est le point où le système est moins flexible, mais je pense que c'est correct - ce n'est peut-être pas le cas, pour votre cas d'utilisation! Si vous souhaitez avoir le même nom pour les niveaux (par exemple, Niveau 1, Niveau 2, Niveau 3) dans tous vos cours, pourquoi ne pas les avoir au même endroit? Si vous avez besoin de descriptions par cours et par niveau, ajoutez à votre cours un champ post-méta contenant la description. Moins flexible, mais peut-être assez.

1
djb

Vous utilisez des taxonomies pour modéliser une hiérarchie. Je pense que ce n'est pas une bonne solution. Les termes d'une taxonomie ne sont pas mutuellement exclusifs, ils sont destinés à être utilisés dans des relations n: m. En conséquence, chaque niveau de votre configuration peut être compris dans plusieurs cours et dans n'importe quelle leçon à plusieurs niveaux. Ce n'est pas ce que tu veux, non?

register_post_type() prend un argument hierarchical. Définissez-la sur true et utilisez un seul type de publication pour modéliser la hiérarchie. Cours sont désormais tous les articles dont post_parent est 0, niveaux ceux dont post_parent est un cours, etc. Vous pouvez même ajouter des sous-pages pour les leçons ultérieurement si vous en ressentez le besoin.

Vous pouvez obtenir tous les niveaux inférieurs sur chaque point avec get_children().

Cela facilite également l'ajout d'une description longue et formatée et de pièces jointes à chaque cours ou niveau. La recherche intégrée fonctionnera par défaut et le contrôle d’accès sera également plus facile.

2
fuxia