Creazione programmatica di un tipo di contenuto con campo file in un modulo personalizzato


9

Sto scrivendo un modulo personalizzato, cosa che ho fatto prima, ma questa è la prima volta che ho provato a creare un tipo di contenuto con campi. Ho implementato hook_node_info e il tipo di contenuto viene visualizzato nell'elenco dei tipi di contenuto nel menu a discesa da admin_menu, tuttavia, quando lo sfoglio admin/structure/typesnon è elencato.

Ho implementato hook_install e preso un po 'di codice che ho trovato su un'altra domanda SO. Ho il codice che stampa alcune informazioni di debug nel mio registro degli errori e sembra che funzioni tutto, ma quando sfoglio il Tipo di contenuto della struttura non mostra il campo che ho aggiunto.

Ecco i ganci:

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));
}

Riesco a vedere una tabella chiamata field_data_field_mymod_myfilenel database, quindi so che la prima parte ha funzionato. Tuttavia, la tabella è vuota.

Il registro degli errori mostra il field_create_instance()metodo restituito:

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

Perché il mio campo non viene visualizzato su questo tipo di contenuto?


1
non ti piacciono le caratteristiche? Trovo più semplice creare il Tipo di contenuto usando FieldUI, quindi esportare la Funzione in una "Funzione" (modulo) personalizzata. ... solo per fare in modo che gli array utilizzassero il hook_info che hai qui - e gli array per le definizioni dei campi. Puoi fare un controllo incrociato del tuo lavoro in quel modo.
Tenken

Risposte:


7

Questa non è una risposta tanto quanto un'espansione della risposta precedente.

Ho trovato questi due collegamenti molto utili per capire di cosa ha bisogno il sistema per aggiungere campi personalizzati al tipo di nodo del modulo personalizzato.

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

Buone informazioni aggiuntive: http://public-action.org/content/drupal-7-field-api-drupal-7-adding-custom-content-type-custom-fields-field-api

Il problema che ho avuto è stato che questi (e ogni altro esempio che posso trovare online) sono esempi molto specifici senza sufficiente documentazione per aiutarmi a trovare una soluzione al mio caso d'uso.

Ciò che ha aiutato è stato il commento di Tenken all'OP sull'utilizzo del modulo Caratteristiche per ottenere gli array per i campi personalizzati.

Quindi ho scaricato il modulo Funzionalità e l'ho abilitato: https://drupal.org/project/features

Quindi ho creato i campi sul mio tipo di contenuto, usando l'interfaccia di amministrazione in Drupal come faresti normalmente, che volevo creare il modulo. Quindi ho cercato Struttura> Funzionalità> Crea funzione e ho inserito un nome falso (ho usato "test") per la funzione e poi nell'area componenti fai clic su "Istanze di campo" e seleziona le caselle per i campi personalizzati. Tutti i campi hanno un nome simile a node- [nome macchina del tipo di nodo] - [nome campo], quindi nel mio caso da quando volevo un campo immagine era node-novel_section-field_image.

Dopo aver selezionato i campi personalizzati per il mio tipo di nodo, ho semplicemente fatto clic su "Scarica funzionalità" e salvato il file .tar sul mio desktop, aperto, aperto la cartella "test", quindi visualizzato test.features.field_base.inc e test. features.field_instance.inc per ottenere gli array di cui avevo bisogno per i miei campi.

Quindi ho appena usato la struttura delineata dal primo link che ho pubblicato e successivamente ha funzionato perfettamente. Per me.

Non sono riuscito a trovare alcuna documentazione sulle strutture degli array necessarie per cose come i campi immagine e i campi di riferimento della tassonomia e sembrava che tutti gli altri tutorial e richieste di aiuto online fossero focalizzati su cose specifiche come i campi di testo.

Spero che chiunque abbia gli stessi problemi che stavo avendo vedrà questo ed essere in grado di far funzionare la propria configurazione usando questi esempi e il modulo Caratteristiche come ho fatto io.

Grazie a Tenken per aver sottolineato questa funzionalità del modulo Caratteristiche, non l'avevo mai usato e non sapevo che lo avrebbe fatto.


4

Questo codice che verrà creato un nuovo tipo di contenuto che dovrebbe essere aggiunto al file .install.

Aggiunta di 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);
}
?>

Dovresti creare un messaggio drupal e scrivere questo evento nel registro:

<?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')); 
  }
}
?>

Fornisci hook_uninstall () per rimuovere il tipo di contenuto :

<?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');
}
?>

Grazie per una risposta molto dettagliata, ma come posso aggiungere un campo File al tipo di contenuto dopo che è stato creato?
Kenny Wyland,

Ho usato il tuo codice sopra e dice che il tipo di contenuto è stato aggiunto, ma non viene visualizzatoadmin/structure/types
Kenny Wyland

1
Per farlo funzionare, devi implementare hook_form () nel tuo modulo, altrimenti se guardi nella tabella node_type nel database, noterai che il tuo tipo appena creato è disabilitato. L'implementazione di hook_form () sembra attivarlo (perché è così, non ne ho idea e non ha molto senso). A proposito, questo affronta il tuo secondo commento.
user5013

1

Questo post è un po 'datato, ma se aiuta, ho trovato questo articolo molto chiaro. Ti mostra come creare un nuovo tipo di contenuto passo dopo passo.

Link al tutorial

<?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);

    }

}

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.