drupal field api. practical usage
DESCRIPTION
Practical usage tips for Drupal's Field APITRANSCRIPT
Field APIPractical usage
Presenter
Pavel MakhrinskySenior Drupal developerBerlingske Media
Introducing Field API
● CCK module successor● The way to store and represent Entities
properties● Utilize Form API mechanism
Some terminology
EntitiesField TypesField StorageField InstancesBundles
Some terminology: structure
Field API
Field Types APIField Info APIField CRUD APIField Storage APIField API bulk data deletionField Language API
Practical tipsHow to use
Implement formatter
Create a presentation of term_reference as a comma-delimited items1. hook_field_formatter_info()2. hook_field_formatter_view()
(option)3. hook_field_formatter_prepare_view()
Implement formatter: infofunction smth_field_formatter_info() { return array( 'taxonomy_comma_links' => array( 'label' => t('Comma-links'), 'field types' => array('taxonomy_term_reference'), ), );}
Implement formatter: viewfunction smth_field_formatter_view($entity_type, $entity, $field, $instance, $langcode, $items, $display){ $element = array(); switch ($display['type']) { case 'taxonomy_comma_links': { $links = array(); foreach ($items as $delta => $item) { $term = taxonomy_term_load($item['tid']); $uri = entity_uri('taxonomy_term', $term); $links[] = l($term->name, $uri['path']); } $element[] = array( '#markup' => implode(', ', $links), ); break; } } return $element;}
Implement widget: view
hook_field_widget_info()hook_field_widget_form()hook_field_is_empty()
Implement widget: infofunction textf_field_widget_info() { return array( 'textf' => array( 'label' => t('Text field'), 'field types' => array('text'), 'settings' => array('size' => 60), 'behaviors' => array( 'multiple values' => FIELD_BEHAVIOR_DEFAULT, 'default value' => FIELD_BEHAVIOR_DEFAULT, ), ), );}
Implement widget: formfunction textf_field_widget_form(&$form, &$form_state, $field, $instance, $langcode, $items, $delta, $element) { switch ($instance['widget']['type']) { case 'textf': $element['textf'] = array( '#type' => 'textfield', '#title' => $element['#title'], '#description' => $element['#description'], '#default_value' => isset($items[$delta]['value']) ? $items[$delta]['value'] : NULL, '#required' => $element['#required'], '#weight' => isset($element['#weight']) ? $element['#weight'] : 0, '#delta' => $delta, ); break; } return $element;
Language API
Language handling: Multilingual types
LocalizedSingle language site
Multilingual siteSite with different content for different languages
Multilingual site with translationSite with translated content
Language handling
Language handlingLocale module is disabled
1. $entity->body[und][0][value];2. $langcode = entity_language('entity_type', $entity);3. $langcode == 'und'
Language handlingLocale and Content translation modules enabled
1. $entity->body[und][0][value];2. $langcode = entity_language('entity_type', $entity);3. $langcode == 'en'
Language handlingLocale and Entity translation modules enabled
Shared fields1. $entity->body[und][0][value];2. $langcode = entity_language('entity_type', $entity);3. $langcode == 'en'
Translatable fields1. $entity->body[en][0][value];2. $entity->body[de][0][value];3. $langcode = entity_language('entity_type', $entity);4. $langcode == 'en'
Getting field data
function field_get_items($entity_type, $entity, $field_name, $langcode = NULL)function field_view_field($entity_type, $entity, $field_name, $display = array(), $langcode = NULL)function field_view_value($entity_type, $entity, $field_name, $item, $display = array(), $langcode = NULL)
Entity API: metadata1. // hook_entity_property_info_alter2. class InviteMetadataController extends EntityDefaultMetadataController {3. public function entityPropertyInfo() {4. $info = parent::entityPropertyInfo();5. $properties = &$info[$this->type]['properties'];6. 7. $properties['inviter'] = array(8. 'label' => t('Inviter'),9. 'type' => 'user',
10. 'getter callback' => 'entity_property_getter_method',11. 'setter callback' => 'entity_property_setter_method',12. 'schema field' => 'uid',13. 'required' => TRUE,14. );15. 16. $properties['invite_accept_link'] = array(17. 'label' => t('Invite action link: accept'),18. 'getter callback' => 'invite_metadata_entity_get_properties',19. 'type' => 'uri',20. 'computed' => TRUE,21. 'entity views field' => TRUE,22. );23. 24. return $info;25. }26. }
Entity API: metadata1. $invite = entity_metadata_wrapper('invite', $entity);2. 3. // Get the value of field_name of the inviter profile.4. $invite ->inviter->profile->field_name->value();5. $invite ->inviter->profile->field_name->set('New name');6. 7. // Value of the invite summary in german language.8. $invite ->language('de')->body->summary->value();9.
10. // Check whether we can edit inviter email address.11. $invite ->inviter->mail->access('edit') ? TRUE : FALSE;12. 13. // Get roles of inviter.14. $invite ->inviter->roles->optionsList();15. 16. // Set description of the first file in field field_files.17. $invite ->field_files[0]->description = 'The first file';18. $invite ->save();19. 20. // Get invite object.21. $invite = $invite->value();
Update a field without Entity$node = node_load($nid);$node->field_fieldname[LANGUAGE_NONE][0]['value'] = 'value';node_save($node);
$node = node_load($nid);$node->field_fieldname[LANGUAGE_NONE][0]['value'] = 'value';field_attach_update('node', $node);
Note:- be careful with security- be careful with caching
Add AJAX validation to a specific fieldfunction smth_link_form_alter(&$form, &$form_state, $form_id) { if ('example_node_form' == $form_id) { $form['field_link'][$language][0]['#process'] =array('link_field_process', '_smth_link_field_link_process'); }} function _smth_link_field_link_process($element, &$form_state, $form) { $element['url']['#description'] = '<div id="example-link"></div>'; $element['url']['#ajax'] = array( 'callback' => 'smth_link_ajax_callback', 'wrapper' => 'example-link', ); return $element;}
Add AJAX validation to a specific fieldfunction kf_link_ajax_callback(&$form, $form_state) { $values = $form_state['values']; $field_link = $values['field_link']; $language = $values['language']; $url = $field_link[$language][0]['url']; $duplicate_nodes = _kf_link_get_url_nid($url); foreach ($duplicate_nodes as $duplicate_node) { if (isset($duplicate_node->nid) && ($duplicate_node->nid !=$values['nid'])) { drupal_set_message(t('This URL already exists in <a href="!url">!title</a>', array('!title' => $duplicate_node->title, '!url' =>"node/{$duplicate_node->nid}")), 'error'); } } $commands = array(); $commands[] = ajax_command_html(NULL, theme('status_messages')); return array( '#type' => 'ajax', '#commands' => $commands, );}
Useful links
http://drupal.org/node/443536http://drupal.org/project/entityhttp://api.drupal.org/api/drupal/modules%21field%21field.module/group/field/7http://drupal.org/project/exampleshttp://drupal.org/project/edithttp://drupal.org/project/layout
Questions?
Pavel Makhrinskydrupal.org: http://drupal.org/user/773216facebook: https://www.facebook.com/gumanist