Programowe tworzenie typu zawartości z polem pliku w module niestandardowym

9

Piszę niestandardowy moduł, co zrobiłem wcześniej, ale po raz pierwszy próbowałem utworzyć typ zawartości z polami. Zaimplementowałem hook_node_info, a typ zawartości pojawia się na liście typów zawartości w menu rozwijanym z menu admin_menu, jednak gdy przeglądam, admin/structure/typesnie ma go na liście.

Zaimplementowałem hook_install i wziąłem kod, który znalazłem w innym pytaniu SO. Mam kod, który wypisał niektóre informacje debugowania do mojego dziennika błędów i wygląda na to, że wszystko działa, ale kiedy przeglądam typ zawartości struktury, nie pokazuje dodanego pola.

Oto haki:

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

Widzę tabelę wywoływaną field_data_field_mymod_myfilew bazie danych, więc wiem, że pierwsza część zadziałała. Tabela jest jednak pusta.

Dziennik błędów pokazuje, że field_create_instance()metoda zwróciła to:

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

Dlaczego moje pole nie wyświetla się w przypadku tego typu treści?

Kenny Wyland
źródło
1
nie lubisz funkcji? Uważam, że najłatwiej jest ustawić typ zawartości za pomocą FieldUI, a następnie wyeksportować funkcję do niestandardowej „funkcji” (modułu). ... po prostu sprawia, że ​​tablice wykorzystują informacje hook_info, które masz tutaj - i tablice do definicji pól. W ten sposób możesz sprawdzić swoją pracę.
tenken

Odpowiedzi:

7

To nie tyle odpowiedź, co rozwinięcie poprzedniej odpowiedzi.

Te dwa łącza okazały się bardzo pomocne w ustaleniu, czego potrzebuje system, aby pola niestandardowe zostały dodane do niestandardowego typu węzła modułu.

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

Dobre dodatkowe informacje: http://public-action.org/content/drupal-7-field-api-drupal-7-adding-custom-content-type-custom-fields-field-api

Problem, który miałem, polegał na tym, że te (i każdy inny przykład, który mogę znaleźć w Internecie) są bardzo konkretnymi przykładami bez wystarczającej dokumentacji, która pomogłaby mi znaleźć rozwiązanie mojego własnego przypadku użycia.

Pomógł w tym komentarz Tenkena do OP dotyczący używania modułu Funkcje do uzyskiwania tablic dla pól niestandardowych.

Pobrałem więc moduł Funkcje i włączyłem go: https://drupal.org/project/features

Następnie utworzyłem pola na moim typie zawartości, używając interfejsu administratora w Drupal, tak jak normalnie, że chcę, aby moduł został utworzony. Następnie przejrzałem do Struktura> Funkcje> Utwórz element i wprowadziłem fałszywą nazwę (użyłem „testu”) dla tej funkcji, a następnie w obszarze komponentów kliknij „Instancje pola” i zaznacz pola pól niestandardowych. Wszystkie pola są nazywane czymś w rodzaju węzła- [nazwa komputera typu węzła] - [nazwa pola], więc w moim przypadku, ponieważ chciałem, aby pole obrazu było węzłem-nazwa_sekcji-pole_obraz.

Po wybraniu niestandardowych pól dla mojego typu węzła kliknąłem „Funkcja pobierania” i zapisałem plik .tar na pulpicie, otworzyłem go, otworzyłem folder „test”, a następnie przejrzałem test.features.field_base.inc i przetestowałem. features.field_instance.inc, aby uzyskać tablice potrzebne do moich pól.

Potem użyłem struktury opisanej w pierwszym linku, który opublikowałem, a potem działała idealnie. Dla mnie.

Nie mogłem znaleźć żadnej dokumentacji dotyczącej struktur tablic potrzebnych do takich rzeczy, jak pola obrazu i pola odniesienia taksonomii, i wydawało się, że wszystkie inne samouczki i prośby o pomoc online skupiają się na konkretnych rzeczach, takich jak pola tekstowe.

Mam nadzieję, że każdy, kto miał ten sam problem, co ja, zobaczy to i będzie mógł sprawić, by ich konfiguracja działała na podstawie tych przykładów i modułu Funkcje, tak jak ja.

Dzięki tenken za wskazanie tej funkcji modułu Funkcje nigdy jej nie użyłem i nie wiedziałem, że to zrobi.

Jason Gray
źródło
4

Ten kod, który zostanie utworzony nowy typ zawartości, który powinien zostać dodany do pliku .install.

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

Powinieneś wysłać komunikat drupal i zapisać to zdarzenie w dzienniku:

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

Podaj hook_uninstall (), aby usunąć typ zawartości :

<?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
źródło
Dziękujemy za bardzo szczegółową odpowiedź, ale jak dodać pole Plik do typu zawartości po jego utworzeniu?
Kenny Wyland
Użyłem twojego kodu powyżej i mówi, że typ zawartości został dodany, ale nie pojawia sięadmin/structure/types
Kenny Wyland
1
Aby to zadziałało, musisz zaimplementować hook_form () w swoim module, w przeciwnym razie, jeśli spojrzysz na tabelę typu node_type w bazie danych, zauważysz, że twój nowo utworzony typ jest wyłączony. Implementacja hook_form () wydaje się go aktywować (dlaczego tak jest, nie mam pojęcia i nie ma to większego sensu). Nawiasem mówiąc, to dotyczy drugiego komentarza.
user5013 9.10.13
1

Ten post jest nieco przestarzały, ale jeśli to pomaga, uważam, że ten artykuł jest bardzo jasny. Pokazuje krok po kroku sposób tworzenia nowego typu treści.

Link do samouczka

<?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
źródło
Podaj odpowiedni cytat w swojej odpowiedzi
Pierre.Vriens