Jak programowo tworzyć pola?

56

Jak podejść do implementacji następujących elementów w Drupal 7?

To, co muszę zrobić, to utworzyć moduł, który definiuje nowy obiekt z możliwością zmiany nazwy, zwany „Firmą”. Mam listę, powiedzmy, 20 pól, które należy wypełnić w każdej instancji firmy. Te pytania są predefiniowane, a niektóre mogą zawierać niestandardowe sprawdzanie poprawności.

W tej chwili jestem w momencie, gdy mogę dodać nowe pola do podmiotu Spółki. W tej chwili to działa dobrze. Mój problem polega na tym, że potrzebuję wszystkich tych pól, gdy tylko moduł zostanie zainstalowany, więc dodanie ich przez interfejs nie jest opcją.

Zastanawiałem się, jak mogę do tego podejść? Zakładam, że sprowadza się to do możliwości robienia tego, co można zrobić za pomocą interfejsu użytkownika „Zarządzaj polami” programowo.

NRaf
źródło
Nie jestem pewien, jaki jest pełny zakres twoich potrzeb, ale myślę, że ten wątek będzie dla ciebie przydatny: drupal.org/node/721552 Pokazuje przykładowy kod do tworzenia niestandardowego typu zawartości z polami podczas pierwszej instalacji modułu. Prawdopodobnie będziesz musiał przekopać się przez API, aby uzyskać dokładne ustawienia pól, których potrzebujesz, ale byłby to dobry punkt wyjścia. Zasadniczo musisz przyjrzeć się node_type_set_defaults()i node_type_save(), jak również, oczywiście hook_install().
handsofaten
Jeśli robisz to w kodzie w przeciwieństwie do funkcji, spójrz na przykład pól i przykład węzła w projekcie przykładów .
rfay
Kilka słów wskazówek. Jeśli chcesz zachować poziom kontroli nad konfiguracją pól, użyj funkcji, aby je zapisać i zastosować. Jeśli chcesz zdefiniować je jako operację jednorazową i pozwolić na swobodne zastępowanie ich konfiguracji w przyszłości, wybierz rozwiązanie kodowe w pliku .install.
Alfred Armstrong

Odpowiedzi:

41

Użyj field_create_field (), aby utworzyć samo pole, i field_create_instance (), aby mieć instancję dla danego pakietu encji.

Podczas tworzenia pól w ramach modułu niestandardowego możesz chcieć usunąć pole po odinstalowaniu modułu. Aby to zrobić, możesz użyć field_delete_field (), jeśli chcesz usunąć pole i całą instancję pola, lub jeśli chcesz usunąć określone instancje, możesz użyć field_delete_instance () .

tamasd
źródło
Jak usuwamy pola, które utworzyliśmy podczas odinstalowywania modułu?
Ashok KS
Ashok, dodałem wam wyjaśnienie w redakcji, którą właśnie wprowadziłem do odpowiedzi.
Lester Peabody
9

Przykład, jak programowo dodawać pola do profilu użytkownika i jak je wykorzystać, czy nie, w formularzu rejestracji użytkownika.


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
źródło
3
Powinno to zostać zaimplementowane w hook_install ().
rewaguje
Jeśli wszystko, co chcesz zrobić, to dodać nowe pole do istniejącego typu zawartości, a następnie kontynuować w backend, to podejście jest całkowicie w porządku. Aktywuj moduł, dezaktywuj go, gotowe. Nowe pole jest dostępne do edycji, moduł można usunąć.
leymannx
8

Jeśli chcesz szybko utworzyć / usunąć pola z istniejącego typu treści lub encji, bez użycia interfejsu użytkownika ani programowania, możesz użyć tych mało znanych poleceń Drush:

drush field-create <bundle(for nodes)> <field_name>,<field_type>,[widget_name] --entity_type: Rodzaj bytu (np. Węzeł, użytkownik, komentarz). Domyślnie węzeł.

Np .: Utwórz dwa nowe pola dla artykułu:

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

Inne polecenia:

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
źródło
4

Jak wskazują inni, możesz użyć funkcji API Field z implementacji hook_install () modułu, aby utworzyć pola i ich instancje dla swojego typu zawartości. Zobacz node_example_install () na przykład użycie funkcji.

Innym rozwiązaniem jest użycie modułu Funkcje . Funkcje mogą eksportować różne składniki witryny do kodu w module. Typy treści i pola można eksportować. Możesz albo wygenerować moduł Funkcje i zastąpić istniejący kod, wówczas Funkcje dołożą wszelkich starań, aby uniknąć złamania kodu. Lub możesz wygenerować fikcyjny moduł i skopiować / wkleić kod związany z polami do swojego modułu. Wymaga to podstawowej wiedzy na temat działania Funkcji.

Pierre Buyle
źródło
3

W pliku instalacyjnym musisz zdefiniować zarówno „hook_install”, jak i „hook_uninstall”. Przykład zawarty, ale przeczytaj wszystko o dodatkowych kluczach w odwołaniach API (kod jest testowany, więc mogą tam być literówki).

W polu hook_installmożesz dodać pola za pomocą:

field_create_field , Ta funkcja buduje szablon dla pola.

field_create_instance Można użyć po utworzeniu pola w celu dodania go do typów_treści (znanych również jako pakiety).

UWAGA Nazwy różnych typów pól można znaleźć w modułach, które je generują (jest to klucz elementu tablicy w ich informacji o polu_pola). Wszystkie podstawowe moduły implementujące pola można znaleźć w folderze modułów / pól / modułów.

Ustawienia można również wyprowadzić z modułów polowych. Ustawienia, które określisz, field_create_fielddotyczą wszystkich witryn. Te, które ustawisz, field_instance_createsą specyficzne dla typu węzła

    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); 
      }
    }

w hook_uninstall

field_delete_instance i field_delete_field mogą być użyte do ich ponownego usunięcia, field_delete_fieldjest wywoływany automatycznie, jeśli usuniesz ostatnią instancję (normalnie).

    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
źródło
2

Ostatnio miałem podobną potrzebę projektu, oto jak do niego podszedłem, mam nadzieję, że komuś to pomoże.

Zasadniczo utworzysz potrzebne pola za pomocą interfejsu użytkownika pól, wyeksportujesz je do kodu, a następnie umieścisz w niestandardowym module. Musisz włączyć moduł Devel.

Stworzyłem także Gist z tymi informacjami.

No to ruszamy....

  1. Utwórz potrzebne pola, używając zwykłego interfejsu użytkownika Drupal.
  2. W tej samej witrynie przejdź do example.com/devel/php
  3. Wklej następujący kod w polu tekstowym „Kod PHP do wykonania”.
  4. Ustaw pierwsze 3 zmienne, a następnie kliknij przycisk Wykonaj

    $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. Otrzymasz 2 tablice, coś w tym stylu, miejmy nadzieję, że wszystkie właściwości zostaną wypełnione.

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

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

Teraz dodaj następujący kod do pliku .install. Zamień wszystkie wystąpienia mymodułu na rzeczywistą nazwę modułu. Wklej kod z wyjścia devel do _mymodule_field_data i _mymodule_instance_data, jak zauważono w odpowiednich funkcjach poniżej. Możesz to zrobić dla dowolnej liczby pól, po prostu umieść wszystkie tablice $ fields w funkcji _mymodule_field_data i wszystkie instancje $ w funkcji _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
źródło
h / t steindom.com/articles/…
MikeNGarrett 10.10.17
0

Możesz również rozważyć użycie modułu Funkcje do utworzenia pól w czasie instalacji.

Ponieważ Funkcje generują kod dla pól, opcją jest po prostu użycie modułu Funkcji do wygenerowania kodu do modułu zastępczego, a następnie skopiowanie i wklejenie do pliku .install modułu.

Korzyścią jest to, że moduł nie zależy od modułu Funkcje w środowisku docelowym.


źródło
1
Chociaż Funkcje to dobry sposób na eksport pól do kodu, to nie jest sposób korzystania z Funkcji. Funkcje nie używają CRUD interfejsu API pola do tworzenia pól z wygenerowanej instalacji.
Pierre Buyle,
0

Możesz użyć kodu customcompanymodule podanego poniżej, aby programowo utworzyć typ zawartości z różnymi polami.

Możesz dodać ten kod do pliku .install modułu niestandardowego. Programowo doda typ zawartości o nazwie „firma” i jego różne typy pól (tekstowy, numeryczny, data (uwaga: musisz zainstalować moduł Data, ponieważ pole Data nie jest domyślnie dostarczane), obraz, lista).

Dodałem również kod odinstalowujący, który usunie typ zawartości „firma” wraz ze wszystkimi jego polami i danymi, kiedy odinstalujesz moduł „customcompanymodule”.

Możesz zmodyfikować / usunąć te pola zgodnie ze swoimi potrzebami:

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
źródło