Création par programme d'un type de contenu avec un champ de fichier dans un module personnalisé

9

J'écris un module personnalisé, ce que j'ai fait auparavant, mais c'est la première fois que j'essaie de créer un type de contenu avec des champs. J'ai implémenté hook_node_info et le type de contenu apparaît dans la liste des types de contenu dans la liste déroulante de admin_menu, cependant, lorsque je le navigue, admin/structure/typesil n'est pas répertorié.

J'ai implémenté hook_install et récupéré du code que j'ai trouvé sur une autre question SO. J'ai le code imprimer des informations de débogage dans mon journal d'erreurs et il semble que tout fonctionne, mais lorsque je navigue vers le type de contenu de la structure, il n'affiche pas le champ que j'ai ajouté.

Voici des crochets:

function mymod_node_info() {
  return array(
    'mymod_content' => array(
      'name' => t('My Mod'),
      'base' => 'mymod_content',
      'description' => t('A Description'),
    )
  );
}

function mymod_install() {
    error_log('mymod_install');
    $types = node_type_get_types();

    if ( ! field_info_field('field_mymod_myfile') ) {
        $field = array(
            'field_name' => 'field_mymod_myfile',
            'type' => 'file',
        );
        $created_field = field_create_field($field);
        error_log('---- field_create_field -----');
        error_log(var_export($created_field, true));
    }

    $instance = array(
        'field_name' => 'field_mymod_myfile',
        'entity_type' => 'mymod_content',
        'bundle' => 'mymod_content',
        'required' => TRUE,
    );
    $created_instance = field_create_instance($instance);
    error_log('---- field_create_instance -----');
    error_log(var_export($created_instance, true));
}

Je peux voir un tableau appelé field_data_field_mymod_myfiledans la base de données, donc je sais que la première partie a fonctionné. Cependant, la table est vide.

Le journal des erreurs montre la field_create_instance()méthode retournée ceci:

array (
  'field_name' => 'field_mymod_myfile',
  'entity_type' => 'mymod_content',
  'bundle' => 'mymod_content',
  'required' => true,
  'field_id' => '5',
)

Pourquoi mon champ n'apparaît-il pas sur ce type de contenu?

Kenny Wyland
la source
1
vous n'aimez pas les fonctionnalités? Je trouve plus facile de créer le type de contenu à l'aide de FieldUI, puis d'exporter la fonctionnalité vers une "fonctionnalité" (module) personnalisée. ... il suffit que les tableaux utilisent le hook_info que vous avez ici - et les tableaux pour les définitions de champs. Vous pouvez recouper votre travail de cette façon.
tenken

Réponses:

7

Ce n'est pas tant une réponse que c'est une extension de la réponse précédente.

J'ai trouvé ces deux liens très utiles pour déterminer ce dont le système a besoin pour que les champs personnalisés soient ajoutés à votre type de nœud de module personnalisé.

Meilleur: http://www.sitepoint.com/creating-a-new-drupal-node-type/

Bonne information supplémentaire: http://public-action.org/content/drupal-7-field-api-drupal-7-adding-custom-content-type-custom-fields-field-api

Le problème que j'ai eu, c'est que ceux-ci (et tous les autres exemples que je peux trouver en ligne) sont des exemples très spécifiques sans documentation suffisante pour m'aider à trouver une solution à mon propre cas d'utilisation.

Ce qui a aidé, c'est le commentaire de tenken au PO sur l'utilisation du module Fonctionnalités pour obtenir les tableaux pour les champs personnalisés.

J'ai donc téléchargé le module Fonctionnalités et l'ai activé: https://drupal.org/project/features

Ensuite, j'ai créé les champs de mon type de contenu, en utilisant l'interface d'administration de Drupal comme vous le feriez normalement, que je voulais que le module crée. Ensuite, j'ai navigué jusqu'à Structure> Fonctionnalités> Créer une fonctionnalité et mis un faux nom (j'ai utilisé "test") pour la fonctionnalité, puis dans la zone des composants, cliquez sur "Instances de champ" et cochez les cases pour les champs personnalisés. Les champs sont tous nommés quelque chose comme node- [votre nom de machine de type de noeud] - [nom de champ], donc dans mon cas, puisque je voulais un champ d'image, c'était node-novel_section-field_image.

Après avoir sélectionné les champs personnalisés pour mon type de nœud, je viens de cliquer sur "Télécharger" et j'ai enregistré le fichier .tar sur mon bureau, l'ai ouvert, ouvert le dossier "test", puis j'ai consulté le test.features.field_base.inc et le test. features.field_instance.inc pour obtenir les tableaux dont j'avais besoin pour mes champs.

Ensuite, j'ai simplement utilisé la structure décrite par ce premier lien que j'ai publié et après cela, cela a fonctionné parfaitement. Pour moi.

Je n'ai pas pu trouver de documentation sur les structures de tableaux nécessaires pour des choses comme les champs d'image et les champs de référence de taxonomie et il semble que tous les autres didacticiels et demandes d'aide en ligne se concentrent sur des choses spécifiques comme les champs de texte.

J'espère que toute personne ayant le même problème que moi verra cela et pourra faire fonctionner sa configuration en utilisant ces exemples et le module Fonctionnalités comme je l'ai fait.

Merci à tenken d'avoir souligné cette fonctionnalité du module Fonctionnalités, je ne l'avais jamais utilisé et je ne savais pas que cela ferait cela.

Jason Gray
la source
4

Ce code qui sera créé nouveau type de contenu qui devrait ajouter dans le fichier .install.

Ajout de hook_install ():

<?php
function your_module_name_install() {
  // use get_t() to get the name of our localization function for translation
  // during install, when t() is not available.
  $t = get_t();

  // Define the node type.
  $node_example = array(
    'type' => 'node_example',
    'name' => $t('Example Node'),
    'base' => 'node_content',
    'description' => $t('This is an example node type with a few fields.'),
    'body_label' => $t('Example Description')
  );

  // Complete the node type definition by setting any defaults not explicitly
  // declared above.
  // http://api.drupal.org/api/function/node_type_set_defaults/7
  $content_type = node_type_set_defaults($node_example);
  node_add_body_field($content_type);

  // Save the content type
  node_type_save($content_type);
}
?>

Vous devriez faire un message drupal et écrire cet événement dans le journal:

<?php
function your_module_name_install() {
  $t = get_t();
  $node_example = array(
    'type' => 'node_example',
    'name' => $t('Example Node'),
    'base' => 'node_content',
    'description' => $t('This is an example node type with a few fields.'),
    'body_label' => $t('Example Description')
  );
  $content_type = node_type_set_defaults($node_example);
  node_add_body_field($content_type);
// Check if we create content type or update.
  $status = node_type_save($content_type);
// Replacement rule for the messages.
  $t_args = array('%name' => $content_type->name);
  if ($status == SAVED_UPDATED) { // update case
    drupal_set_message($t('The content type %name has been updated.', $t_args));
  } 
  elseif ($status == SAVED_NEW) { // create case
    drupal_set_message($t('The content type %name has been added.', $t_args));
    watchdog('node', 'Added content type %name.', $t_args, WATCHDOG_NOTICE, l($t('view'), 'admin/structure/types')); 
  }
}
?>

Fournissez hook_uninstall () pour supprimer votre type de contenu :

<?php
function your_module_name_uninstall() {
  // Gather all the example content that might have been created while this
  // module was enabled.  Simple selects still use db_query().
  // http://api.drupal.org/api/function/db_query/7
  $sql = 'SELECT nid FROM {node} n WHERE n.type = :type';
  $result = db_query($sql, array(':type' => 'node_example'));
  $nids = array();
  foreach ($result as $row) {
    $nids[] = $row->nid;
  }
  // Delete all the nodes at once
  // http://api.drupal.org/api/function/node_delete_multiple/7
  node_delete_multiple($nids);
  // Delete our content type
  // http://api.drupal.org/api/function/node_type_delete/7
  node_type_delete('node_example');
}
?>
Nitesh Sethia
la source
Merci pour une réponse très détaillée, mais comment ajouter un champ Fichier au type de contenu après sa création?
Kenny Wyland
J'ai utilisé votre code ci-dessus et il dit que le type de contenu a été ajouté, mais il ne s'affiche pasadmin/structure/types
Kenny Wyland
1
Pour que cela fonctionne, vous devez implémenter hook_form () dans votre module, sinon si vous regardez dans la table node_type dans la base de données, vous remarquerez que votre type nouvellement créé est désactivé. L'implémentation de hook_form () semble l'activer (pourquoi c'est ainsi, je n'en ai aucune idée et cela n'a pas beaucoup de sens). Cela répond d'ailleurs à votre deuxième commentaire.
user5013
1

Ce message est un peu dépassé, mais si cela peut aider, j'ai trouvé cet article très clair. Il vous montre comment créer un nouveau type de contenu étape par étape.

Lien vers le tutoriel

<?php

/**
 * Implements hook_install().
 */
function book_install()
{

    $t = get_t();

    // Step 1 - Define the custom content type

    $content_type = array(

        'type'          => 'book',
        'name'          => $t('Book'),
        'description'   => $t('Create a new book'),
        'title_label'   => $t('Book title'),
        'base'          => 'node_content',
        'custom'        => TRUE,

    );

    $node_type = node_type_set_defaults($content_type);

    node_type_save($node_type);

    // Step 2 - Create new fields

    $fields = array(

        // Author’s name

        'book_author_name'  => array(

            'field_name'    => 'book_author_name',
            'type'          => 'text',
            'cardinality'   => 1,

        ),

        // Description

        'book_description'  => array(

            'field_name'    => 'book_description',
            'type'          => 'text_long',
            'cardinality'   => 1,

        ),

    );

    foreach( $fields as $field ) {

        field_create_field($field);

    }

    // Step 3 - Attach fields to content type

    $instances = array(

        // Author’s name

        'book_author_name'  => array(

            'field_name'   => 'book_author_name',
            'label'        => $t('Author Name'),
            'required'     => TRUE,
            'widget'       => array(
                'type'  => 'text_textfield'
            ),

        ),

        // Description

        'book_description'  => array(

            'field_name'   => 'book_description',
            'label'        => $t('Description'),
            'required'     => TRUE,
            'widget'       => array(
                'type'  => 'text_textarea'
            ),

        ),

    );

    foreach( $instances as $instance ) { // Loop through our instances

        $instance['entity_type']   = 'node';
        $instance['bundle']        = 'book'; // Attach the instance to our content type

        field_create_instance($instance);

    }

}
Shlomi Nissan
la source
Veuillez en inclure une citation pertinente dans votre réponse
Pierre.Vriens