Программное создание типа контента с полем файла в пользовательском модуле

9

Я пишу пользовательский модуль, который я делал раньше, но я впервые пытаюсь создать тип контента с полями. Я реализовал hook_node_info, и Тип контента отображается в списке Типов контента в выпадающем меню admin_menu, однако при просмотре admin/structure/typesего нет в списке.

Я реализовал hook_install и собрал некоторый код, который я нашел в другом вопросе SO. У меня есть код, который выводит некоторую отладочную информацию в мой журнал ошибок, и он выглядит так, как будто все работает, но когда я перехожу к типу содержимого структуры, он не показывает добавленное мной поле.

Вот крючки:

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

Я вижу таблицу field_data_field_mymod_myfileв базе данных, поэтому знаю, что первая часть сработала. Однако таблица пуста.

Журнал ошибок показывает, что field_create_instance()метод вернул это:

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

Почему мое поле не отображается в этом типе контента?

Кенни Уайлэнд
источник
1
тебе не нравятся особенности? Я считаю, что проще всего сделать Тип содержимого с помощью FieldUI, а затем экспортировать Элемент в пользовательский «Элемент» (модуль). ... он просто использовал массивы hook_info, которые у вас здесь есть, и массивы для определения полей. Вы можете проверить свою работу таким образом.
Tenken

Ответы:

7

Это не столько ответ, сколько расширение предыдущего ответа.

Я нашел эти две ссылки очень полезными для выяснения того, что нужно системе для добавления пользовательских полей к типу узла вашего пользовательского модуля.

Лучший: http://www.sitepoint.com/creating-a-new-drupal-node-type/

Хорошая дополнительная информация: http://public-action.org/content/drupal-7-field-api-drupal-7-adding-custom-content-type-custom-fields-field-api

Проблема, с которой я столкнулся, заключалась в том, что эти (и все другие примеры, которые я могу найти в Интернете) являются очень конкретными примерами без достаточного количества документации, чтобы помочь мне найти решение для моего собственного варианта использования.

Что помогло, так это комментарий Tenken к OP об использовании модуля Features для получения массивов для пользовательских полей.

Поэтому я скачал модуль «Функции» и включил его: https://drupal.org/project/features

Затем я создал поля для своего типа контента, используя интерфейс администратора в Drupal, как вы обычно это делаете, и хотел, чтобы модуль создавался. Затем я просмотрел «Структура»> «Объекты»> «Создать объект» и добавил поддельное имя (я использовал «test») для объекта, а затем в области компонентов нажмите «Экземпляры полей» и установите флажки для настраиваемых полей. Все поля называются как-то вроде node- [имя вашего компьютера типа узла] - [имя поля], поэтому в моем случае, так как я хотел создать поле изображения, это было node-novel_section-field_image.

После выбора настраиваемых полей для моего типа узла я просто щелкнул «Функция загрузки» и сохранил файл .tar на моем рабочем столе, открыл его, открыл папку «test», затем просмотрел test.features.field_base.inc и test. features.field_instance.inc, чтобы получить массивы, которые мне нужны для моих полей.

Затем я просто использовал структуру, описанную в той первой ссылке, которую я разместил, и после этого она отлично работала. Для меня.

Я не смог найти никакой документации по структурам массивов, необходимых для таких вещей, как поля изображения и справочные поля таксономии, и казалось, что все другие учебные пособия и запросы помощи онлайн сосредоточены на конкретных вещах, таких как текстовые поля.

Надеюсь, любой, у кого возникли те же проблемы, что и у меня, увидит это и сможет выполнить настройку, используя эти примеры и модуль «Функции», как я.

Спасибо tenken за указание на эту функциональность модуля Features, я никогда не использовал его и не знал, что он это сделает.

Джейсон Грей
источник
4

Это код, в котором будет создан новый тип контента, который следует добавить в файл .install.

Добавление 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);
}
?>

Вы должны сделать сообщение drupal и записать это событие в журнал:

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

Предоставьте hook_uninstall () для удаления вашего типа контента :

<?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');
}
?>
Нитеш Сетия
источник
Спасибо за очень подробный ответ, но как добавить поле «Файл» в тип содержимого после его создания?
Кенни Уайлэнд
Я использовал ваш код выше, и он говорит, что тип контента был добавлен, но он не обнаруживаетсяadmin/structure/types
Кенни Уайлэнд
1
Чтобы это работало, вам нужно реализовать hook_form () в вашем модуле, иначе, если вы посмотрите в таблицу node_type в базе данных, вы заметите, что ваш вновь созданный тип отключен. Реализация hook_form (), кажется, активирует его (почему это так, я понятия не имею, и это не имеет особого смысла). Кстати, это ваш второй комментарий.
user5013
1

Этот пост несколько устарел, но если он поможет, я нашел эту статью очень ясной. Он показывает, как создать новый тип контента, шаг за шагом.

Ссылка на учебник

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

    }

}
Шломи Ниссан
источник
Пожалуйста,
включите