Как программно создать поля?

56

Как я могу подойти к реализации следующего в Drupal 7?

То, что мне нужно сделать, это создать модуль, который определяет новую полевую сущность, называемую «Компания». У меня есть список, скажем, 20 полей, которые должны быть заполнены каждым экземпляром компании. Эти вопросы предварительно определены, а некоторые могут содержать пользовательские проверки.

В настоящий момент я могу добавить новые поля в сущность Company. Это отлично работает в данный момент. Моя проблема в том, что мне нужно, чтобы все эти поля были там, как только модуль будет установлен, поэтому добавить их через интерфейс не вариант.

Мне было интересно, как я могу подойти к этому? Я предполагаю, что это сводится к возможности делать то, что можно сделать с помощью пользовательского интерфейса «Управление полями» программно.

NRaf
источник
Я не совсем понимаю весь спектр ваших потребностей, но я думаю, что эта ветка будет вам полезна: drupal.org/node/721552 Здесь показан пример кода для создания пользовательского типа контента с полями при первой установке модуля. Вам, вероятно, придется покопаться в API, чтобы получить точные настройки поля, которые вам нужны, но это было бы хорошей отправной точкой. В принципе, вы должны смотреть в node_type_set_defaults()и node_type_save(), а также, конечно, hook_install().
рукопожатие
Если вы делаете это в коде, а не в компонентах, взгляните на Пример полей и Пример узла в Проекте примеров .
rfay
Несколько слов руководства. Если вы хотите сохранить уровень контроля над конфигурацией полей, используйте Функции для записи и применения их. Если вы хотите определить их как однократную операцию и позволить их конфигурации в будущем свободно переопределяться, выберите решение для кода в файле .install.
Альфред Армстронг

Ответы:

41

Используйте field_create_field (), чтобы создать само поле, и field_create_instance (), чтобы иметь экземпляр для данного набора сущностей.

При создании полей как части пользовательского модуля вы можете или не хотите удалять поле при удалении модуля. Для этого вы можете использовать field_delete_field (), если вы хотите удалить поле и весь экземпляр поля, или если вы хотите удалить конкретные экземпляры, вы можете использовать field_delete_instance () .

tamasd
источник
Как мы удаляем поля, которые мы создали при удалении модуля?
Ашок К.С.
Ашок, я добавил для тебя пояснение в правке, которую я только что внес в ответ.
Лестер Пибоди
9

Пример того, как программно добавлять поля в профиль пользователя и как использовать их или нет в форме регистрации пользователя.


function MYMODULE_enable() {
  // Check if our field is not already created.
  if (!field_info_field('field_myField')) {

    // Create the field base.
    $field = array(
      'field_name' => 'field_myField', 
      'type' => 'text', 
    );
    field_create_field($field);

    // Create the field instance on the bundle.
    $instance = array(
      'field_name' => 'field_myField', 
      'entity_type' => 'user', 
      'label' => 'My Field Name', 
      'bundle' => 'user', 
      // If you don't set the "required" property then the field wont be required by default.
      'required' => TRUE,
      'settings' => array(
        // Here you inform either or not you want this field showing up on the registration form.
        'user_register_form' => 1,
      ),
      'widget' => array(
        'type' => 'textfield',
      ), 
    );
    field_create_instance($instance);
  }
}
Франциско Луз
источник
3
Это должно быть реализовано в hook_install ().
Revagomes
Если все, что вы хотите сделать, это добавить новое поле к существующему типу контента и затем продолжить в бэкэнде, этот подход вполне подойдет. Активировать модуль, деактивировать его, готово. Новое поле есть, редактируемое, модуль можно удалить.
leymannx
8

Если вам нужно быстро создать / удалить поля из существующего типа контента или объекта, не используя ни интерфейс, ни программирование, вы можете использовать эти малоизвестные команды Drush:

drush field-create <bundle(for nodes)> <field_name>,<field_type>,[widget_name] --entity_typeТип объекта (например, узел, пользователь, комментарий). По умолчанию для узла.

Например: создайте два новых поля для статьи:

drush field-create article city,text,text_textfield subtitle,text,text_textfield

Другие команды:

drush field-delete <field_name> [--bundle] [--entity_type]
drush field-info [field | types]
drush field-update <field_name> Return URL for field editing web page.
drush field-clone <source_field_name> <dst_field_name>
Interdruper
источник
4

Как указывалось другими, вы можете использовать функции Field API из реализации hook_install () вашего модуля для создания полей и их экземпляров для вашего типа контента. См. Node_example_install () для примера использования функции.

Другим решением является использование модуля функций . Функции могут экспортировать различные компоненты сайта в код в модуле. Типы содержимого и поля относятся к числу этих экспортируемых. Вы можете сгенерировать модуль Feature и переопределить существующий код, который будет делать все возможное, чтобы не нарушить ваш код. Или вы можете сгенерировать фиктивный модуль и скопировать. / Вставить код, связанный с полями, в свой модуль. Это требует базового понимания работы функций.

Пьер Буйль
источник
3

В вашем установочном файле вам нужно определить и «hook_install», и «hook_uninstall». Пример включен, но читайте все о дополнительных ключах в ссылках API (код не проверен, поэтому там могут быть опечатки).

В hook_installвы можете добавить поля, используя:

field_create_field , эта функция создает шаблон для поля.

field_create_instance Может использоваться после создания поля для добавления его в content_types (также известный как связки).

ПРИМЕЧАНИЕ. Имена различных типов полей можно найти в генерирующих их модулях (это ключ элемента массива в их hook_field_info). Вы можете найти все основные модули реализации полей в папке modules / field / modules.

Настройки также могут быть получены из полевых модулей. Установки, которые вы установили в, field_create_fieldявляются общесистемными. Те, которые вы устанавливаете, field_instance_createявляются специфичными для node_type

    MY_MODULE_install(){
      // Generate the base for the field
      $field = array( 
        'field_name' => 'FIELD_MACHINE_NAME', 
        'type' => 'FIELD_TYPE' // See note above for what to put here
      );
      // Instance 
      $instance = array(
        'field_name' => 'FIELD_MACHINE_NAME', 
        'entity_type' => 'node', 
      ); 

      // Create instances of the field and add them to the content_types
      $node_types = node_type_get_types(); 
      foreach($node_types as $node_type){
         $instance['bundle'] = $node_type->type; 
         field_create_instance($instance); 
      }
    }

в hook_uninstall

field_delete_instance и field_delete_field могут быть использованы для их повторного удаления, field_delete_fieldвызывается автоматически, если вы удаляете последний экземпляр (обычно).

    MY_MODULE_uninstall(){
      $node_types = node_type_get_types(); 
      foreach($node_types as $node_type){
        if($instance = field_info_instance('node', 'FIELD_MACHINE_NAME', $node_type->type)) {
          field_delete_instance($instance);
        }
      }
    }
Суранга Панагамува Гамаж
источник
2

У меня недавно была похожая потребность в проекте, вот как я подошел к нему, надеюсь, он кому-нибудь поможет.

По сути, вы создадите необходимые поля с помощью пользовательского интерфейса полей, экспортируете их в код и затем включаете их в свой пользовательский модуль. Вам понадобится модуль Devel.

Я также создал Gist с этой информацией.

Вот так....

  1. Создайте нужные поля, используя обычный пользовательский интерфейс Drupal.
  2. На том же сайте, перейдите на example.com/devel/php
  3. Вставьте следующий код в текстовое поле «PHP code to execute».
  4. Установите первые 3 переменные и затем нажмите «Выполнить»

    $entity_type = 'node';    
    $field_name = 'body';    
    $bundle_name = 'article'; 
    
    $info_config = field_info_field($field_name);
    $info_instance = field_info_instance($entity_type, $field_name, $bundle_name);
    unset($info_config['id']);
    unset($info_instance['id'], $info_instance['field_id']);
    include_once DRUPAL_ROOT . '/includes/utility.inc';
    $output = "\$fields['" . $field_name . "'] = " . drupal_var_export($info_config) . ";\n";
    $output .= "\$instances['" . $field_name . "'] = " . drupal_var_export($info_instance) . ";";
    drupal_set_message("<textarea rows=30 style=\"width: 100%;\">" . $output . '</textarea>');
    
  5. Вы получите 2 массива, что-то вроде этого, надеюсь, со всеми заполненными свойствами.

$fields['field_some_field'] = array(
  'properties of the field'
);

$instances['field_some_field'] = array(
  'properties of the instance'
);

Теперь добавьте следующий код в ваш файл .install. Замените все экземпляры модуля на действительное имя модуля. Вставьте код из вывода devel в _mymodule_field_data и _mymodule_instance_data, как указано в соответствующих функциях ниже. Вы можете сделать это для любого количества полей, просто поместив все массивы $ fields в функцию _mymodule_field_data и все экземпляры $ в функцию _mymodule_instance_data.

function mymodule_install() {

  // Create all the fields we are adding to our entity type.
  // http://api.drupal.org/api/function/field_create_field/7
  foreach (_mymodule_field_data() as $field) {
    field_create_field($field);
  }

  // Create all the instances for our fields.
  // http://api.drupal.org/api/function/field_create_instance/7
  foreach (_mymodule_instance_data() as $instance) {
    field_create_instance($instance);
  }
}

// Create the array of information about the fields we want to create.
function _mymodule_field_data() {
  $fields = array();
  // Paste $fields data from devel ouput here.
  return $fields;
  }

// Create the array of information about the instances we want to create.
function _mymodule_instance_data() {
  $instances = array();
  // Paste $instances data from devel output here.
  return $instances;
}
Джон Лэйн
источник
h / t steindom.com/articles/…
MikeNGarrett
0

Вы также можете рассмотреть возможность использования модуля Features для создания полей во время установки.

Поскольку Feature генерирует код для полей, можно просто использовать модуль Feature, чтобы сгенерировать код в фиктивном модуле, а затем скопировать и вставить в файл .install вашего модуля.

Преимущество заключается в том, что модуль не зависит от модуля «Функции» в вашей целевой среде.


источник
1
Altough Features - это хороший способ экспортировать поля в код, а не использовать его. Компоненты не используют Field API CRUD для создания полей из сгенерированного .install.
Пьер Байл
0

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

Вы можете добавить этот код в файл .install своего пользовательского модуля. Он программно добавит тип контента с названием «company» и различные типы полей (текст, число, дата) (примечание: вам нужно установить модуль Date, так как поле Date по умолчанию не предусмотрено), изображение, список).

Я также добавил код удаления, который удалит тип контента «компания» вместе со всеми его полями и данными, когда вы удалите свой модуль «customcompanymodule».

Вы можете изменить / удалить эти поля в соответствии с вашими потребностями:

function customcompanymodule_install() {
     $t = get_t();
     node_types_rebuild();
     $company = array(
    'type' => 'company',
    'name' => $t('Company'),
    'base' => 'node_content',
    'module' => 'node',
    'description' => $t('Content type to handle companys.'),
    'body_label' => $t('Company Description'),
    'title_label' => $t('Company Title'),
    'promote' => 0,
    'status' => 1,
    'comment' => 0,
);
$content_type = node_type_set_defaults($company);

node_type_save($content_type);

foreach (_company_installed_fields() as $field) {
    field_create_field($field);
}

foreach (_company_installed_instances() as $instance) {
    $instance['entity_type'] = 'node';
    $instance['bundle'] = 'company';
    field_create_instance($instance);
}

$weight = db_query("SELECT weight FROM {system} WHERE name = :name",    array(':name' => 'categories'))->fetchField();
db_update('system')->fields(array(
            'weight' => $weight + 1,
        ))
        ->condition('name', 'company')
        ->execute();
}

function _company_installed_fields() {
$t = get_t();
$fields = array(
    'company_startdate' => array(
        'field_name' => 'company_startdate',
        'label' => $t('Company Start Date'),
        'cardinality' => 1,
        'type' => 'datetime',
        'module' => 'date',
        'settings' => array(
            'granularity' => array(
                'month' => 'month',
                'day' => 'day',
                'hour' => 'hour',
                'minute' => 'minute',
                'year' => 'year',
                'second' => 0,
            ),
            'tz_handling' => 'site',
            'timezone_db' => 'UTC',
            'cache_enabled' => 0,
            'cache_count' => '4',
            'todate' => 'required',
        ),
    ),
    'company_totalwinners' => array(
        'field_name' => 'company_totalwinners',
        'label' => $t('Maximum Company Winners'),
        'cardinality' => 1,
        'type' => 'number_integer',
        'module' => 'number',
        'settings' => array(
            'max_length' => 10000,
        ),
    ),
    'company_minwinner' => array(
        'field_name' => 'company_minwinner',
        'label' => $t('Minimum Entries for Company to Activate'),
        'cardinality' => 1,
        'type' => 'number_integer',
        'module' => 'number',
        'settings' => array(
            'max_length' => 10000,
        ),
    ),
    'company_totalentries' => array(
        'field_name' => 'company_totalentries',
        'label' => $t('Company Total Entries'),
        'cardinality' => 1,
        'type' => 'number_integer',
        'module' => 'number',
        'settings' => array(
            'max_length' => 10000,
        ),
    ),
    'company_points' => array(
        'field_name' => 'company_points',
        'label' => $t('Company Points'),
        'cardinality' => 1,
        'type' => 'number_integer',
        'module' => 'number',
        'settings' => array(
            'max_length' => 10000,
        ),
    ),
    'company_image' => array(
        'field_name' => 'company_image',
        'label' => $t('Image'),
        'cardinality' => 1,
        'type' => 'image',
        'settings' => array(
            'default_image' => 0,
            'uri_scheme' => 'public',
        ),
    ),
    'company_description' => array(
        'field_name' => 'company_description',
        'label' => $t('Company Description'),
        'cardinality' => 1,
        'type' => 'text',
        'module' => 'text',
        'length' => '255'
    ),
    'company_winner' => array(
        'field_name' => 'company_winner',
        'label' => $t('Company Description'),
        'cardinality' => 1,
        'type' => 'text',
        'module' => 'text',
        'length' => '255'
    ),
    'field_autowinnerselection' => array(
        'field_name' => 'field_autowinnerselection',
        'label' => $t('Auto Company Winner Selection'),
        'type' => 'list_boolean',
        'module' => 'list',
        'active' => '1',
        'locked' => '0',
        'cardinality' => '1',
        'deleted' => '0'
    ),
);
return $fields;
}

function _company_installed_instances() {
$t = get_t();
$instances = array(
    'company_startdate' => array(
        'field_name' => 'company_startdate',
        'label' => $t('Company Lifespan'),
        'cardinality' => 1,
        'widget' => array(
            'type' => 'date_popup',
            'module' => 'date',
            'settings' => array(
                'input_format' => 'm/d/Y - H:i:s',
                'input_format_custom' => '',
                'year_range' => '-3:+3',
                'increment' => '15',
                'label_position' => 'above',
                'text_parts' => array(),
            ),
        ),
    ),
    'company_totalwinners' => array(
        'field_name' => 'company_totalwinners',
        'label' => $t('Maximum Company Winners'),
        'cardinality' => 1,
        'widget' => array(
            'type' => 'number',
            'module' => 'number',
            'settings' => array('size' => 60),
        ),
    ),
    'company_minwinner' => array(
        'field_name' => 'company_minwinner',
        'label' => $t('Minimum Number of Entries for Company to Activate'),
        'cardinality' => 1,
        'required' => 1,
        'widget' => array(
            'type' => 'number',
            'module' => 'number',
            'settings' => array('size' => 60),
        ),
    ),
    'company_totalentries' => array(
        'field_name' => 'company_totalentries',
        'label' => $t('Company Total Entries'),
        'cardinality' => 1,
        'required' => 1,
        'widget' => array(
            'type' => 'number',
            'module' => 'number',
            'settings' => array('size' => 60),
        ),
    ),
    'company_points' => array(
        'field_name' => 'company_points',
        'label' => $t('Company Points'),
        'cardinality' => 1,
        'required' => 1,
        'widget' => array(
            'type' => 'number',
            'module' => 'number',
            'settings' => array('size' => 60),
        ),
    ),
    'company_image' => array(
        'field_name' => 'company_image',
        'label' => $t('Image'),
        'cardinality' => 1,
        'required' => 1,
        'type' => 'company_image',
        'settings' => array(
            'max_filesize' => '',
            'max_resolution' => '213x140',
            'min_resolution' => '213x140',
            'alt_field' => 1,
            'default_image' => 0
        ),
        'widget' => array(
            'settings' => array(
                'preview_image_style' => 'thumbnail',
                'progress_indicator' => 'throbber',
            ),
        ),
        'display' => array(
            'default' => array(
                'label' => 'hidden',
                'type' => 'image',
                'settings' => array('image_style' => 'medium', 'image_link' => ''),
                'weight' => -1,
            ),
            'teaser' => array(
                'label' => 'hidden',
                'type' => 'image',
                'settings' => array('image_style' => 'thumbnail', 'image_link' => 'content'),
                'weight' => -1,
            ),
        ),
    ),
    'company_description' => array(
        'field_name' => 'company_description',
        'label' => $t('Company Description'),
        'cardinality' => 1,
        'widget' => array(
            'weight' => '-3',
            'type' => 'text_textfield',
            'module' => 'text',
            'active' => 1,
            'settings' => array(
                'size' => '1000',
            ),
        ),
    ),
    'company_winner' => array(
        'field_name' => 'company_winner',
        'label' => $t('Company Winner'),
        'cardinality' => 1,
        'widget' => array(
            'weight' => '-3',
            'type' => 'text_textfield',
            'module' => 'text',
            'active' => 1,
            'settings' => array(
                'size' => '60',
            ),
        ),
    ),
    'field_autowinnerselection' => array(
        'field_name' => 'field_autowinnerselection',
        'required' => 1,
        'label' => $t('Auto Company Winner Selection'),
        'widget' => array(
            'weight' => '-3',
            'type' => 'options_buttons',
            'module' => 'options',
            'active' => 1,
            'settings' => array(),
        ),
    ),
);
return $instances;
}

function customcompanymodule_uninstall() {
$content_types = array(
    'name1' => 'company',
);
$sql = 'SELECT nid FROM {node} n WHERE n.type = :type1';
$result = db_query($sql, array(':type1' => $content_types['name1']));
$nids = array();
foreach ($result as $row) {
    $nids[] = $row->nid;
}
node_delete_multiple($nids);
node_type_delete($content_types['name1']);
field_purge_batch(1000);
}
Надим Хан
источник