際際滷

際際滷Share a Scribd company logo
Field API
Practical usage
Presenter
Pavel Makhrinsky
Senior Drupal developer
Berlingske Media
Introducing Field API
 CCK module successor
 The way to store and represent Entities
  properties
 Utilize Form API mechanism
Some terminology
Entities
Field Types
Field Storage
Field Instances
Bundles
Some terminology: structure
Field API
Field Types API
Field Info API
Field CRUD API
Field Storage API
Field API bulk data deletion
Field Language API
Practical tips
   How to use
Implement formatter
Create a presentation of term_reference as a
comma-delimited items
1. hook_field_formatter_info()
2. hook_field_formatter_view()

(option)
3. hook_field_formatter_prepare_view()
Implement formatter: info
function smth_field_formatter_info() {
  return array(
    'taxonomy_comma_links' => array(
      'label' => t('Comma-links'),
      'field types' => array('taxonomy_term_reference'),
    ),
  );
}
Implement formatter: view
function 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: info
function 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: form
function 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
Localized
Single language site


Multilingual site
Site with different content for different languages


Multilingual site with translation
Site with translated content
Language handling
Language handling
Locale module is disabled


1.   $entity->body[und][0][value];
2.   $langcode = entity_language('entity_type', $entity);
3.   $langcode == 'und'
Language handling
Locale and Content translation modules enabled


 1.   $entity->body[und][0][value];
 2.   $langcode = entity_language('entity_type', $entity);
 3.   $langcode == 'en'
Language handling
Locale and Entity translation modules enabled


Shared fields
1. $entity->body[und][0][value];
2. $langcode = entity_language('entity_type', $entity);
3. $langcode == 'en'

Translatable fields
1. $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: metadata
 1.   // hook_entity_property_info_alter
 2.   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.    }
Entity API: metadata
 1.   $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
field
function 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
field
function 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/443536
http://drupal.org/project/entity
http://api.drupal.org/api/drupal/modules%21field%21field.
module/group/field/7
http://drupal.org/project/examples
http://drupal.org/project/edit
http://drupal.org/project/layout
Questions?
Pavel Makhrinsky
drupal.org: http://drupal.org/user/773216
facebook: https://www.facebook.com/gumanist

More Related Content

Drupal Field API. Practical usage

  • 2. Presenter Pavel Makhrinsky Senior Drupal developer Berlingske Media
  • 3. Introducing Field API CCK module successor The way to store and represent Entities properties Utilize Form API mechanism
  • 4. Some terminology Entities Field Types Field Storage Field Instances Bundles
  • 6. Field API Field Types API Field Info API Field CRUD API Field Storage API Field API bulk data deletion Field Language API
  • 7. Practical tips How to use
  • 8. Implement formatter Create a presentation of term_reference as a comma-delimited items 1. hook_field_formatter_info() 2. hook_field_formatter_view() (option) 3. hook_field_formatter_prepare_view()
  • 9. Implement formatter: info function smth_field_formatter_info() { return array( 'taxonomy_comma_links' => array( 'label' => t('Comma-links'), 'field types' => array('taxonomy_term_reference'), ), ); }
  • 10. Implement formatter: view function 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; }
  • 12. Implement widget: info function 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, ), ), ); }
  • 13. Implement widget: form function 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;
  • 15. Language handling: Multilingual types Localized Single language site Multilingual site Site with different content for different languages Multilingual site with translation Site with translated content
  • 17. Language handling Locale module is disabled 1. $entity->body[und][0][value]; 2. $langcode = entity_language('entity_type', $entity); 3. $langcode == 'und'
  • 18. Language handling Locale and Content translation modules enabled 1. $entity->body[und][0][value]; 2. $langcode = entity_language('entity_type', $entity); 3. $langcode == 'en'
  • 19. Language handling Locale and Entity translation modules enabled Shared fields 1. $entity->body[und][0][value]; 2. $langcode = entity_language('entity_type', $entity); 3. $langcode == 'en' Translatable fields 1. $entity->body[en][0][value]; 2. $entity->body[de][0][value]; 3. $langcode = entity_language('entity_type', $entity); 4. $langcode == 'en'
  • 20. 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)
  • 21. Entity API: metadata 1. // hook_entity_property_info_alter 2. 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. }
  • 22. Entity API: metadata 1. $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();
  • 23. 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
  • 24. Add AJAX validation to a specific field function 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; }
  • 25. Add AJAX validation to a specific field function 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, ); }