Bagaimana cara pemrograman membuat Fields?

56

Bagaimana saya bisa mendekati penerapan hal berikut di Drupal 7?

Yang perlu saya lakukan adalah membuat modul yang mendefinisikan entitas fieldable baru, yang disebut 'Perusahaan'. Saya punya daftar, katakanlah, 20 bidang yang perlu diisi oleh setiap instance Perusahaan. Pertanyaan-pertanyaan ini sudah ditentukan sebelumnya dan beberapa mungkin berisi validasi khusus.

Saat ini, saya pada titik ketika saya dapat menambahkan bidang baru ke entitas Perusahaan. Ini berfungsi dengan baik saat ini. Masalah saya adalah bahwa saya perlu semua bidang ini ada di sana segera setelah modul diinstal, jadi menambahkannya melalui antarmuka bukanlah pilihan.

Saya bertanya-tanya bagaimana saya bisa mendekati ini? Saya berasumsi bahwa ini adalah kemampuan untuk melakukan apa yang dapat dilakukan dengan menggunakan UI 'Manage Fields' secara terprogram.

NRaf
sumber
Saya tidak jelas tentang cakupan penuh kebutuhan Anda, tetapi saya pikir utas ini akan berguna bagi Anda: drupal.org/node/721552 Ini menunjukkan kode sampel untuk membuat jenis konten khusus dengan bidang ketika modul pertama kali dipasang. Anda mungkin harus menggali melalui API untuk mendapatkan pengaturan bidang yang Anda butuhkan, tetapi ini akan menjadi titik awal yang baik. Pada dasarnya, Anda perlu melihat ke dalam node_type_set_defaults()dan node_type_save(), juga, tentu saja hook_install(),.
handsofaten
Jika Anda melakukan ini dalam kode yang bertentangan dengan Fitur, lihat Contoh Bidang dan Contoh Node dalam Proyek Contoh .
rfay
Beberapa kata panduan. Jika Anda ingin mempertahankan tingkat kendali atas konfigurasi bidang, gunakan Fitur untuk merekam dan menerapkannya. Jika Anda ingin mendefinisikannya sebagai operasi satu-shot dan membiarkan konfigurasi mereka ditimpa secara bebas di masa mendatang, pilih solusi kode dalam file .install.
Alfred Armstrong

Jawaban:

41

Gunakan field_create_field () untuk membuat bidang itu sendiri dan field_create_instance () untuk memiliki instance untuk bundel entitas yang diberikan.

Saat membuat bidang sebagai bagian dari modul khusus, Anda mungkin atau mungkin tidak ingin menghapus bidang ketika modul dihapus. Untuk melakukannya, Anda bisa menggunakan field_delete_field () jika Anda ingin menghapus bidang dan semua instance bidang, atau jika Anda ingin menghapus instance tertentu Anda dapat menggunakan field_delete_instance () .

tamasd
sumber
Bagaimana kami menghapus bidang yang kami buat saat mencopot modul?
Ashok KS
Ashok, saya menambahkan klarifikasi untuk Anda dalam suntingan yang baru saja saya buat untuk jawabannya.
Lester Peabody
9

Contoh tentang cara menambahkan bidang ke profil pengguna secara sistematis dan bagaimana memanfaatkannya, atau tidak, ke dalam formulir Registrasi Pengguna.


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);
  }
}
Francisco Luz
sumber
3
Ini harus diimplementasikan di hook_install ().
Revagom
Jika semua yang ingin Anda lakukan adalah menambahkan bidang baru ke jenis konten yang ada dan dari sana melanjutkan di backend, pendekatan itu benar-benar baik-baik saja. Aktifkan modul, nonaktifkan, selesai. Kolom baru ada di sana, dapat diedit, modul dapat dihapus.
leymannx
8

Jika Anda perlu membuat / menghapus bidang dengan cepat dari Tipe Konten atau atau Entitas yang ada, tanpa menggunakan UI atau pemrograman, Anda dapat menggunakan perintah Drush yang kurang dikenal ini:

drush field-create <bundle(for nodes)> <field_name>,<field_type>,[widget_name] --entity_type: Jenis entitas (mis. Simpul, pengguna, komentar). Default ke simpul.

Misalnya: Buat dua bidang baru untuk Artikel:

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

Perintah lain:

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
sumber
4

Seperti yang ditunjukkan oleh orang lain, Anda dapat menggunakan fungsi API Bidang dari implementasi hook_install () modul Anda untuk membuat bidang dan instansnya untuk tipe konten Anda. Lihat node_example_install () untuk contoh penggunaan fungsi.

Solusi lain adalah dengan menggunakan modul Fitur . Fitur dapat mengekspor berbagai komponen situs ke kode dalam sebuah modul. Jenis dan bidang konten di antaranya dapat diekspor. Anda dapat membuat modul Fitur dan mengganti kode yang ada, Fitur kemudian akan melakukan yang terbaik untuk menghindari kerusakan kode Anda. Atau Anda dapat membuat modul dummy dan menyalin./sisipkan kode yang terkait dengan bidang ke modul Anda. Ini membutuhkan pemahaman dasar tentang cara kerja Fitur.

Pierre Buyle
sumber
3

Dalam file instal Anda, Anda harus mendefinisikan 'hook_install' dan 'hook_uninstall'. Contoh disertakan tetapi membaca semua tentang kunci tambahan dalam referensi API (kode tidak diuji sehingga mungkin salah ketik di sana).

Di hook_installAnda dapat menambahkan bidang menggunakan:

field_create_field , Fungsi ini membangun templat untuk bidang.

field_create_instance Dapat digunakan setelah membuat bidang untuk menambahkannya ke content_types (juga dikenal sebagai bundel).

Perhatikan Nama-nama berbagai jenis bidang dapat ditemukan dalam modul yang menghasilkan mereka (itu adalah kunci dari item array di hook_field_info mereka). Anda dapat menemukan semua modul pelaksana bidang inti di folder modules / field / modules.

Pengaturan juga dapat diturunkan dari modul bidang. Pengaturan yang Anda atur di field_create_fieldadalah situs yang lebar. Yang Anda atur field_instance_createadalah yang spesifik 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); 
      }
    }

Dalam hook_uninstall

field_delete_instance dan field_delete_field dapat digunakan untuk menghapusnya lagi, field_delete_fielddipanggil secara otomatis jika Anda menghapus instance terakhir (biasanya).

    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);
        }
      }
    }
Suranga Panagamuwa Gamage
sumber
2

Saya baru-baru ini memiliki kebutuhan yang sama untuk sebuah proyek, di sini adalah bagaimana saya mendekatinya, berharap itu bisa membantu seseorang.

Pada dasarnya Anda akan membuat bidang yang Anda butuhkan menggunakan UI bidang, mengekspornya ke kode dan kemudian memasukkannya ke dalam modul khusus Anda. Anda akan membutuhkan modul Devel diaktifkan.

Saya juga membuat inti dengan info ini.

Kita mulai....

  1. Buat bidang yang Anda butuhkan, menggunakan UI Drupal biasa.
  2. Di situs yang sama, buka example.com/devel/php
  3. Rekatkan kode berikut ke dalam kotak teks "Kode PHP untuk menjalankan".
  4. Setel 3 variabel pertama dan kemudian klik eksekusi

    $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. Anda akan mendapatkan 2 array, kira-kira seperti ini, semoga dengan semua properti terisi.

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

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

Sekarang tambahkan kode berikut ke file .install Anda. Ganti semua instance mymodule dengan nama modul yang sebenarnya. Tempel kode dari output devel ke dalam _mymodule_field_data dan _mymodule_instance_data, seperti yang dicatat di masing-masing fungsi di bawah ini. Anda dapat melakukan ini untuk sebanyak bidang yang Anda suka, cukup letakkan semua array $ field dalam fungsi _mymodule_field_data dan semua $ instance dalam fungsi _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;
}
John Laine
sumber
h / t steindom.com/articles/…
MikeNGarrett
0

Anda juga dapat mempertimbangkan menggunakan modul Fitur untuk membuat bidang pada waktu pemasangan.

Saat Fitur menghasilkan kode untuk bidang, opsi hanya menggunakan modul Fitur untuk menghasilkan kode menjadi modul dummy dan kemudian salin & tempel ke file .install modul Anda.

Manfaatnya adalah modul tidak tergantung pada modul Fitur di lingkungan target Anda.


sumber
1
Fitur Altough adalah cara yang baik untuk mengekspor bidang ke kode, itu bukan cara menggunakan Fitur. Fitur tidak menggunakan CRUD API Bidang untuk membuat bidang dari .install yang dihasilkan.
Pierre Buyle
0

Anda dapat menggunakan kode modul perusahaan khusus yang diberikan di bawah ini untuk membuat tipe konten secara terprogram dengan berbagai bidangnya.

Anda dapat menambahkan kode ini dalam file .install dari modul khusus Anda. Ini secara terprogram akan menambahkan jenis konten yang disebut "perusahaan" dan berbagai jenis bidangnya (teks, angka, tanggal (catatan: Anda harus memasang modul Tanggal karena bidang Tanggal tidak disediakan secara default), gambar, daftar).

Saya juga telah menambahkan kode uninstall yang akan menghapus tipe "perusahaan" konten beserta semua bidang dan datanya ketika Anda akan menghapus modul 'customcompanymodule' Anda.

Anda dapat memodifikasi / menghapus bidang ini sesuai kebutuhan Anda:

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);
}
Nadeem Khan
sumber