Programmgesteuertes Erstellen eines Inhaltstyps mit Dateifeld in einem benutzerdefinierten Modul

9

Ich schreibe ein benutzerdefiniertes Modul, das ich zuvor erstellt habe, aber dies ist das erste Mal, dass ich versucht habe, einen Inhaltstyp mit Feldern zu erstellen. Ich habe hook_node_info implementiert und der Inhaltstyp wird in der Liste der Inhaltstypen in der Dropdown-Liste von admin_menu angezeigt. Wenn ich jedoch zu admin/structure/typesihm navigiere, wird er nicht aufgelistet.

Ich habe hook_install implementiert und mir einen Code geholt, den ich auf einer anderen SO-Frage gefunden habe. Ich habe den Code einige Debug-Informationen in mein Fehlerprotokoll drucken lassen und es sieht so aus, als ob alles funktioniert, aber wenn ich zum Strukturinhaltstyp navigiere, wird das von mir hinzugefügte Feld nicht angezeigt.

Hier sind Haken:

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

Ich kann eine Tabelle field_data_field_mymod_myfilein der Datenbank sehen, daher weiß ich, dass der erste Teil funktioniert hat. Die Tabelle ist jedoch leer.

Das Fehlerprotokoll zeigt die zurückgegebene field_create_instance()Methode:

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

Warum wird mein Feld bei diesem Inhaltstyp nicht angezeigt?

Kenny Wyland
quelle
1
Magst du Features nicht? Ich finde es am einfachsten, den Inhaltstyp mithilfe der FieldUI zu erstellen und das Feature dann in ein benutzerdefiniertes "Feature" (Modul) zu exportieren. ... es werden nur die Arrays verwendet, die die hook_info verwenden, die Sie hier haben - und die Arrays für Felddefinitionen. Auf diese Weise können Sie Ihre Arbeit überprüfen.
Tenken

Antworten:

7

Dies ist weniger eine Antwort als vielmehr eine Erweiterung der vorherigen Antwort.

Ich fand diese beiden Links sehr hilfreich, um herauszufinden, was das System benötigt, damit benutzerdefinierte Felder zu Ihrem benutzerdefinierten Modulknotentyp hinzugefügt werden können.

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

Gute zusätzliche Informationen: http://public-action.org/content/drupal-7-field-api-drupal-7-adding-custom-content-type-custom-fields-field-api

Das Problem, das ich hatte, war, dass diese (und jedes andere Beispiel, das ich online finden kann) sehr spezifische Beispiele ohne ausreichende Dokumentation sind, um eine Lösung für meinen eigenen Anwendungsfall zu finden.

Was half, war Tenkens Kommentar an das OP zur Verwendung des Features-Moduls, um die Arrays für die benutzerdefinierten Felder abzurufen.

Also habe ich das Funktionsmodul heruntergeladen und aktiviert: https://drupal.org/project/features

Dann habe ich die Felder in meinem Inhaltstyp mithilfe der Admin-Oberfläche in Drupal erstellt, wie Sie es normalerweise tun würden, die das Modul erstellen soll. Dann habe ich zu Struktur> Features> Feature erstellen navigiert und einen falschen Namen (ich habe "test" verwendet) für das Feature eingegeben und dann im Komponentenbereich auf "Feldinstanzen" geklickt und die Kontrollkästchen für die benutzerdefinierten Felder aktiviert. Die Felder haben alle den Namen node- [Maschinenname Ihres Knotentyps] - [Feldname]. In meinem Fall war es also, da ich ein Bildfeld wollte, node-Novel_Section-Field_image.

Nachdem ich die benutzerdefinierten Felder für meinen Knotentyp ausgewählt hatte, klickte ich einfach auf "Download-Funktion" und speicherte die .tar-Datei auf meinem Desktop, öffnete sie, öffnete den Ordner "test", sah die Datei test.features.field_base.inc an und testete. features.field_instance.inc, um die Arrays abzurufen, die ich für meine Felder benötigte.

Dann habe ich einfach die Struktur verwendet, die in dem ersten Link beschrieben ist, den ich gepostet habe, und danach hat es perfekt funktioniert. Für mich.

Ich konnte keine Dokumentation zu den Array-Strukturen finden, die für Dinge wie Bildfelder und Taxonomie-Referenzfelder benötigt werden, und es schien, dass sich alle anderen Online-Tutorials und Hilfeanfragen auf bestimmte Dinge wie Textfelder konzentrieren.

Hoffentlich wird jeder, der die gleichen Probleme hat wie ich, dies sehen und in der Lage sein, seine Einrichtung anhand dieser Beispiele und des Funktionsmoduls wie ich zum Laufen zu bringen.

Dank Tenken für den Hinweis auf diese Funktionalität des Features-Moduls hatte ich es nie verwendet und wusste nicht, dass es das tun würde.

Jason Gray
quelle
4

Dieser Code wird als neuer Inhaltstyp erstellt, der in die Installationsdatei eingefügt werden soll.

Hook_install () hinzufügen:

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

Sie sollten eine Drupal-Nachricht erstellen und dieses Ereignis in das Protokoll schreiben:

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

Geben Sie hook_uninstall () ein, um Ihren Inhaltstyp zu entfernen :

<?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
quelle
Vielen Dank für eine sehr detaillierte Antwort, aber wie füge ich dem Inhaltstyp nach seiner Erstellung ein Dateifeld hinzu?
Kenny Wyland
Ich habe Ihren Code oben verwendet und es heißt, dass der Inhaltstyp hinzugefügt wurde, aber er wird nicht angezeigtadmin/structure/types
Kenny Wyland
1
Damit dies funktioniert, müssen Sie hook_form () in Ihrem Modul implementieren. Wenn Sie in der Tabelle node_type in der Datenbank nachsehen, werden Sie feststellen, dass Ihr neu erstellter Typ deaktiviert ist. Die Implementierung von hook_form () scheint es zu aktivieren (warum es so ist, habe ich keine Ahnung und es macht nicht viel Sinn). Dies adressiert übrigens Ihren zweiten Kommentar.
user5013
1

Dieser Beitrag ist etwas veraltet, aber wenn es hilft, habe ich festgestellt, dass dieser Artikel sehr klar ist. Es zeigt Ihnen Schritt für Schritt, wie Sie einen neuen Inhaltstyp erstellen.

Link zum 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);

    }

}
Shlomi Nissan
quelle
Bitte
fügen