如何以编程方式创建字段?


56

如何在Drupal 7中实现以下内容?

我需要做的是创建一个模块,该模块定义一个称为“公司”的新可现场使用的实体。我有一个清单,假设每个公司实例需要填写20个字段。这些问题是预定义的,有些可能包含自定义验证。

目前,我可以将新字段添加到Company实体。目前,这可以正常工作。我的问题是,安装模块后,我需要所有这些字段,因此无法通过界面添加它们。

我想知道如何解决这个问题?我以为它可以通过编程方式使用“管理字段” UI来完成。


我尚不清楚您需要的全部内容,但我认为该线程对您有用:drupal.org/node/721552它显示了示例代码,用于在首次安装模块时使用字段创建自定义内容类型。您可能必须深入研究API才能获得所需的确切字段设置,但这将是一个不错的起点。基本上,您将需要研究node_type_set_defaults()node_type_save(),当然还有hook_install()
handsofaten 2011年

如果您使用代码而不是功能来执行此操作,请查看Examples项目中的Fields示例和Node示例。
rfay 2011年

几句话的指导。如果要保留对字段配置的控制级别,请使用“功能”记录并应用它们。如果要将它们定义为一次性操作,并希望以后自由覆盖它们的配置,请在.install文件中选择一种代码解决方案。
2013年

Answers:


41

使用field_create_field()创建领域本身field_create_instance()来对给定实体捆绑一个实例。

在将字段创建为自定义模块的一部分时,您可能会或可能不想在卸载模块时删除该字段。要做到这一点,你可以使用field_delete_field()如果你想删除字段和所有字段实例,或者如果你想删除特定的情况下,你可以使用field_delete_instance()


卸载模块时如何删除创建的字段?
Ashok KS 2013年

Ashok,我在对答案进行的修改中为您添加了一个说明。
Lester Peabody 2013年

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

如果您需要在不使用UI或编程的情况下从现有“内容类型”或“实体”快速创建/删除字段,则可以使用以下鲜为人知的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>

4

正如其他人指出的那样,您可以使用模块的hook_install()实现中的Field API函数来为您的内容类型创建字段及其实例。有关该函数的示例用法,请参见node_example_install()

另一种解决方案是使用功能模块。功能部件可以将各种站点组件导出为模块中的代码。内容类型和字段可在其中导出。您可以生成功能模块并覆盖现有代码,然后功能将尽最大努力避免破坏您的代码。或者,您可以生成虚拟模块,然后将与字段相关的代码复制/粘贴到模块中。这需要对功能的工作原理有基本的了解。


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_instancefield_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

最近,我对一个项目也有类似的需求,这是我的工作方式,希望对您有所帮助。

基本上,您将使用字段UI创建所需的字段,将其导出为代码,然后将其包含在自定义模块中。您将需要启用Devel模块。

我还使用此信息创建了 要点

开始了....

  1. 使用常规的Drupal UI创建所需的字段。
  2. 在同一站点上,转到example.com/devel/php
  3. 将以下代码粘贴到“要执行的PHP代码”文本框中。
  4. 设置前三个变量,然后单击执行

    $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文件中。将mymodule的所有实例替换为实际的模块名称。将代码从开发输出中粘贴到_mymodule_field_data和_mymodule_instance_data中,如下面各个函数中所述。您可以对任意多个字段执行此操作,只需将所有$ fields数组放入_mymodule_field_data函数,并将所有$ instances放入_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;
}


0

您也可以考虑在安装时使用“功能”模块创建字段。

当功能为字段生成代码时,一种选择就是使用功能模块将代码生成到虚拟模块中,然后将其复制并粘贴到模块的.install文件中。

好处是该模块不依赖于目标环境中的功能模块。


1
完全功能是将字段导出到代码的好方法,而不是如何使用功能。功能部件不使用Field API CRUD从生成的.install创建字段。
皮埃尔·布伊

0

您可以使用下面给出的customcompanymodule代码以编程方式创建具有其各个字段的内容类型。

您可以将此代码添加到自定义模块的.install文件中。它将以编程方式添加一个名为“ company”的内容类型及其各种类型的字段(文本,数字,日期(注意:您将需要安装Date模块,因为默认情况下未提供Date字段),图像,列表)。

我还添加了卸载代码,当您卸载“ customcompanymodule”模块时,该代码将删除内容类型“ company”及其所有字段和数据。

您可以根据需要修改/删除这些字段:

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);
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.