Как программно создавать поля?
Как я могу подойти к реализации следующего в Drupal 7?
Что мне нужно сделать, так это создать модуль, который определяет новый объект, который можно использовать, под названием «Компания». У меня есть список, скажем, 20 полей, которые должны заполняться каждым экземпляром компании. Эти вопросы предопределены, а некоторые могут содержать пользовательскую проверку.
В настоящий момент я нахожусь в точке, когда я могу добавить новые поля в компанию. На данный момент это прекрасно работает. Моя проблема в том, что мне нужно, чтобы все эти поля были там, как только модуль был установлен, поэтому добавление их через интерфейс не является вариантом.
Мне было интересно, как я могу подойти к этому? Я предполагаю, что это связано с тем, что можно делать то, что можно сделать с помощью пользовательского интерфейса «Управление полями» программно.
8 ответов
Используйте field_create_field () для создайте само поле и field_create_instance () иметь экземпляр для данного объекта.
При создании полей как части настраиваемого модуля вы можете или не захотите удалить поле при удалении модуля. Для этого вы можете использовать field_delete_field () если вы хотите удалить поле и весь экземпляр поля, или если вы хотите удалить определенные экземпляры, вы можете использовать field_delete_instance () .
Пример того, как программно добавлять поля в профиль пользователя и как их использовать, или нет, в форме регистрации пользователя.
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);
}
}
Если вам нужно быстро создавать /удалять поля из существующего типа контента или или объекта, без использования пользовательского интерфейса или программирования, вы можете использовать эти малоизвестные команды 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>
Как указано другими, вы можете использовать Функции API поля из hook_install () реализация вашего модуля для создания полей и их экземпляров для вашего типа содержимого. См. node_example_install () , например, использование функции.
Другим решением является использование модуля Функции . Возможности могут экспортировать различные компоненты сайта для кодирования в модуле. Типы контента и поля относятся к числу этих экспортируемых. Вы можете либо сгенерировать модуль функций, либо переопределить существующий код, тогда функции сделают все возможное, чтобы не сломать ваш код. Или вы можете создать фиктивный модуль и скопировать /поместить код, связанный с полями, в ваш модуль. Это требует понимания основ того, как работают функции.
В вашем установочном файле вам нужно определить как «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);
}
}
}
Недавно у меня была аналогичная потребность в проекте, вот как я подошел к нему, надеюсь, что это поможет кому-то.
В основном вы создадите поля, которые вам нужны, используя пользовательский интерфейс полей, экспортируйте их в код и затем включите их в свой настраиваемый модуль. Вам понадобится модуль Devel.
Я также создал Gist с этой информацией.
Здесь мы идем ....
- Создайте нужные поля, используя обычный пользовательский интерфейс Drupal.
- На том же сайте перейдите к example.com/devel/php
- Вставьте следующий код в текстовое поле «PHP code to execute».
-
Задайте первые 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>');
-
Вы получите 2 массива, что-то вроде этого, надеюсь, со всеми заполненными свойствами.
$fields['field_some_field'] = array( 'properties of the field' ); $instances['field_some_field'] = array( 'properties of the instance' );
Теперь добавьте следующий код в файл .install. Замените все экземпляры mymodule на фактическое имя модуля. Вставьте код из вывода devel в _mymodule_field_data и _mymodule_instance_data, как указано int соответствующие функции ниже. Вы можете сделать это для столько полей, сколько хотите, просто поместите все массивы $ 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; }
Вы также можете рассмотреть возможность использования модуля «Функции» для создания полей во время установки.
Поскольку функции генерируют код для полей, опция заключается только в том, чтобы использовать модуль Feature для генерации кода в фиктивный модуль, а затем скопировать & вставьте файл .install в свой модуль.
Преимуществом является то, что модуль не зависит от модуля функций в целевой среде.
Вы можете использовать приведенный ниже код customcompanymodule, чтобы программно создать тип контента с его различными полями.
Вы можете добавить этот код в файл .install вашего настраиваемого модуля. Он будет программным образом добавлять тип контента, называемый «компания», и его различные типы полей (текст, число, дата (примечание: вам нужно будет установить модуль «Дата», поскольку по умолчанию не указано поле «Дата»), изображение, список).
Я также добавил код удаления, который удалит тип контента «компания» вместе со всеми его полями и данными, когда вы удалите модуль «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);
}