วิธีสร้างฟิลด์โดยทางโปรแกรม


56

ฉันจะใช้งานสิ่งต่อไปนี้ใน Drupal 7 ได้อย่างไร

สิ่งที่ฉันต้องทำคือสร้างโมดูลที่กำหนดเอนทิตีที่เป็นฟิลด์ใหม่ที่เรียกว่า 'บริษัท ' ฉันมีรายชื่อสมมติว่ามี 20 ฟิลด์ที่ต้องกรอกโดยแต่ละอินสแตนซ์ของ บริษัท คำถามเหล่านี้มีการกำหนดไว้ล่วงหน้าและบางส่วนอาจมีการตรวจสอบที่กำหนดเอง

ในขณะนี้ฉันมาถึงจุดที่ฉันสามารถเพิ่มเขตข้อมูลใหม่ไปยังเอนทิตี บริษัท ใช้งานได้ดีในขณะนี้ ปัญหาของฉันคือฉันต้องการฟิลด์เหล่านี้ทั้งหมดเพื่อให้มีทันทีที่ติดตั้งโมดูลดังนั้นการเพิ่มพวกเขาผ่านทางอินเตอร์เฟสไม่ใช่ตัวเลือก

ฉันสงสัยว่าฉันจะเข้าถึงสิ่งนี้ได้อย่างไร ฉันคิดว่ามันสามารถทำสิ่งที่สามารถทำได้โดยใช้ UI 'จัดการฟิลด์' โดยทางโปรแกรม


ฉันยังไม่ชัดเจนเกี่ยวกับความต้องการของคุณ แต่ฉันคิดว่าเธรดนี้จะมีประโยชน์สำหรับคุณ: drupal.org/node/721552มันแสดงรหัสตัวอย่างสำหรับการสร้างประเภทเนื้อหาที่กำหนดเองพร้อมฟิลด์เมื่อติดตั้งโมดูลเป็นครั้งแรก คุณอาจต้องขุดผ่าน API เพื่อรับการตั้งค่าฟิลด์ที่แน่นอนที่คุณต้องการ แต่นี่จะเป็นจุดเริ่มต้นที่ดี โดยทั่วไปคุณจะต้องมองไปnode_type_set_defaults()และเช่นเดียวกับของหลักสูตรnode_type_save() hook_install()
Handsofaten

หากคุณกำลังทำเช่นนี้ในรหัสเมื่อเทียบกับคุณสมบัติให้ดูที่ตัวอย่างทุ่งและตัวอย่างโหนดในส่วนโครงการตัวอย่าง
rfay

คำแนะนำเล็กน้อย หากคุณต้องการรักษาระดับการควบคุมการกำหนดค่าของเขตข้อมูลใช้ฟีเจอร์เพื่อบันทึกและนำไปใช้ หากคุณต้องการกำหนดให้เป็นการดำเนินการแบบครั้งเดียวและปล่อยให้การกำหนดค่าถูกแทนที่อย่างอิสระในอนาคตให้เลือกโซลูชันรหัสในไฟล์. install
Alfred Armstrong

คำตอบ:


41

ใช้field_create_field ()เพื่อสร้างฟิลด์เองและfield_create_instance ()เพื่อให้มีอินสแตนซ์สำหรับบันเดิลเอนทิตีที่กำหนด

เมื่อสร้างฟิลด์เป็นส่วนหนึ่งของโมดูลที่กำหนดเองคุณอาจต้องการลบฟิลด์เมื่อไม่ได้ติดตั้งโมดูล ต้องการทำเช่นนั้นคุณสามารถใช้field_delete_field ()ถ้าคุณต้องการที่จะลบข้อมูลและอินสแตนซ์ฟิลด์ทั้งหมดหรือถ้าต้องการลบกรณีเฉพาะที่คุณสามารถใช้field_delete_instance ()


เราจะลบฟิลด์ที่เราสร้างขึ้นเมื่อถอนการติดตั้งโมดูลได้อย่างไร
Ashok KS

Ashok ฉันเพิ่มคำอธิบายสำหรับคุณในการแก้ไขที่ฉันทำกับคำตอบ
Lester Peabody

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

หากคุณต้องการสร้าง / ลบฟิลด์อย่างรวดเร็วจาก Content Type หรือ Entity ที่มีอยู่โดยไม่ต้องใช้ 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

ตามที่คนอื่น ๆ คุณสามารถใช้ฟังก์ชั่น Field APIจากการใช้งานhook_install ()ของโมดูลของคุณเพื่อสร้างฟิลด์และอินสแตนซ์ของพวกเขาสำหรับประเภทเนื้อหาของคุณ ดูที่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_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

ฉันเพิ่งมีความต้องการที่คล้ายกันสำหรับโครงการนี่คือวิธีที่ฉันเข้าหามันหวังว่าจะช่วยใครซักคน

โดยทั่วไปคุณจะสร้างฟิลด์ที่คุณต้องการโดยใช้ UI ของฟิลด์ส่งออกเป็นรหัสแล้วรวมไว้ในโมดูลที่กำหนดเองของคุณ คุณจะต้องเปิดใช้งานโมดูล Devel

ฉันยังสร้าง Gistด้วยข้อมูลนี้

ไปเลย....

  1. สร้างเขตข้อมูลที่คุณต้องการโดยใช้ Drupal UI ปกติ
  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 ของคุณ แทนที่ mymodule ทั้งหมดด้วยชื่อโมดูลจริง วางรหัสจากเอาต์พุต devel ลงใน _mymodule_field_data และ _mymodule_instance_data ดังที่บันทึกไว้ int ของฟังก์ชันที่เกี่ยวข้องด้านล่าง คุณสามารถทำสิ่งนี้ได้หลายฟิลด์ตามที่คุณต้องการเพียงแค่ใส่ $ field array ทั้งหมดในฟังก์ชัน _mymodule_field_data และ $ instance ทั้งหมดในฟังก์ชัน _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
ฟีเจอร์ของ Altough เป็นวิธีที่ดีในการส่งออกฟิลด์ไปยังโค้ดนั่นไม่ใช่วิธีการใช้ฟีเจอร์ ฟีเจอร์ไม่ได้ใช้ Field API CRUD เพื่อสร้างฟิลด์จาก. install ที่สร้างขึ้น
Pierre Buyle

0

คุณสามารถใช้รหัส 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);
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.