KEMBAR78
Fields in Core: How to create a custom field | KEY
FIELDS IN CORE:
HOW TO CREATE A CUSTOM
         FIELD
        By Ivan Zugec
WHO AM I?


• Name: Ivan   Zugec

• Drupal   username: Ivan Zugec

• Twitter: http://twitter.com/zugec

• Blog: http://zugec.com
SESSION AGENDA

• What’s   new in Drupal 7

• Understanding   fields

• How   to create a field

• Custom   formatters

• Documentation

• Q&A
WHAT’S NEW IN DRUPAL 7
WHAT’S NEW IN DRUPAL 7



• InDrupal 6 we used the
 CCK module to add fields
 into nodes
WHAT’S NEW IN DRUPAL 7



• In
   Drupal 7 a lot of CCK’s functionality has been moved into
 core

• Not   all CCK modules made it into core
WHAT’S NEW IN DRUPAL 7


• “Node  reference” and “User reference” moved to http://
 drupal.org/project/references

• “Fieldset” moved   to http://drupal.org/project/field_group

• “Contentpermission” moved to http://drupal.org/project/
 field_permissions
WHAT’S NEW IN DRUPAL 7



• Drupal    7 ships with text, options, number and list

• File   and image field all in core
UNDERSTANDING FIELDS
UNDERSTANDING FIELDS


• Pieceof functionality
 attached to an entity (node,
 taxonomy, etc...)

• Example: Date   module
UNDERSTANDING FIELDS

• Fields
     have 4 major
 components

• Field

• Field    type

• Widget

• Formatter
UNDERSTANDING FIELDS



• Field

• field.module, field.info   and field.install
UNDERSTANDING FIELDS
                                 /**
                                  * Implements hook_field_schema().
                                  */
                                 function text_field_schema($field) {
                                   switch ($field['type']) {
                                     case 'text':
                                      $columns = array(
                                        'value' => array(
                                          'type' => 'varchar',

• Field   type                            'length' => $field['settings']['max_length'],
                                          'not null' => FALSE,
                                        ),
                                      );
                                      break;

• How  the field will be stored   
                                      case 'text_long':
                                        
       ....

 in the database
                                       break;
                                     }
                                     $columns += array(
                                       'format' => array(
                                         'type' => 'varchar',
                                         'length' => 255,

• Using   hook_field_schema             ),
                                         'not null' => FALSE,

                                     );
                                     return array(
                                       'columns' => $columns,

• Using   hook_field_info               'indexes' => array(

                                       ),
                                         'format' => array('format'),

                                       'foreign keys' => array(
                                         'format' => array(
                                           'table' => 'filter_format',
                                           'columns' => array('format' => 'format'),
                                         ),
                                       ),
                                     );
UNDERSTANDING FIELDS



• Widget

• Form element a user will use
 to enter in the data
UNDERSTANDING FIELDS
UNDERSTANDING FIELDS



• Formatter

• How  to data will be
 displayed
HOW TO CREATE A FIELD
HOW TO CREATE A FIELD

• Createa custom
 “Collaborators” field

• Module will be called
 “collabfield”

• Unlimited value field with a
 Name, Role and Link text
 fields within
HOW TO CREATE A FIELD


• Createa module called
 collabfield

• Createcollabfield.info,
 collabfield.install and
 collabfield.module files
HOW TO CREATE A FIELD
                 collabfield.info


  ; $Id$

  name = Collaborator field
  description = Custom collaborator field.

  dependencies[] = field_ui

  core = 7.x
HOW TO CREATE A FIELD
                 collabfield.install
  <?php
  // $Id$

  /**
   * Implements hook_install().
   */

  function collabfield_install() {
  }

  /**
   * Implements hook_uninstall().
   */

  function collabfield_uninstall() {
  }
HOW TO CREATE A FIELD
  /**
                             collabfield.install
   * Implementation of hook_field_schema().
   */
  function collabfield_field_schema($field) {
    if ($field['type'] == 'collabfield') {
      $schema['columns']['name'] = array(
        'type' => 'varchar',
        'length' => '255',
        'not null' => FALSE,
      );

       $schema['columns']['role'] = array(
         'type' => 'varchar',
         'length' => '255',
         'not null' => FALSE,
       );

       $schema['columns']['link'] = array(
         'type' => 'varchar',
         'length' => '255',
         'not null' => FALSE,
       );

       $schema['indexes'] = array(
         'name' => array('name'),
         'role' => array('role'),
         'link' => array('link'),
       );
       return $schema;
   }
HOW TO CREATE A FIELD
                         collabfield.module
<?php
// $Id$

/**
 * Implementation of hook_field_info().
 */
function collabfield_field_info() {
  return array(
    'collabfield' => array(
      'label' => t('Collaborator'),
      'description' => t('Custom collaborators field.'),
      'default_widget' => 'collabfield_collabfield_form',
      'default_formatter' => 'collabfield_default',
    ),
  );
}
HOW TO CREATE A FIELD
                                   collabfield.module

/**
 * Implementation of hook_field_is_empty().
 */
function collabfield_field_is_empty($item, $field) {
  if ($field['type'] == 'collabfield') {

    if (empty($item['name']) && empty($item['role']) && empty($item['link'])) {
     return TRUE;

 }

  }
  return FALSE;
}
HOW TO CREATE A FIELD

• Create   a widget

• Use hook_field_widget_info
 to setup field

• Use
 hook_field_widget_form for
 the actual form element
HOW TO CREATE A FIELD
/**
 * Implements hook_field_widget_info().
 */
function collabfield_field_widget_info() {
  return array(
    'collabfield_collabfield_form' => array(
      'label' => t('Collabfield form'),
      'field types' => array('collabfield'),
      'behaviors' => array(
        'multiple values' => FIELD_BEHAVIOR_DEFAULT,
        //Use FIELD_BEHAVIOR_NONE for no default value.
        'default value' => FIELD_BEHAVIOR_DEFAULT,
      ),
    ),
  );
}
HOW TO CREATE A FIELD
/**
 * Implementation of hook_field_widget_form().
 */
function collabfield_field_widget_form(&$form, &$form_state, $field, $instance, $langcode, $items, $delta, $element) {

    $base = $element;
    if ($instance['widget']['type'] == 'collabfield_collabfield_form') {
      $widget = $instance['widget'];
      $settings = $widget['settings'];

     $element['name'] = array(
       '#type' => 'textfield',
       '#title' => t('Name'),
       '#default_value' => isset($items[$delta]['name']) ? $items[$delta]['name'] : NULL,
     );
     $element['role'] = array(
       '#type' => 'textfield',
       '#title' => t('Role'),
       '#default_value' => isset($items[$delta]['role']) ? $items[$delta]['role'] : NULL,
     );
     $element['link'] = array(
       '#type' => 'textfield',
       '#title' => t('Link'),
       '#default_value' => isset($items[$delta]['link']) ? $items[$delta]['link'] : NULL,
       '#element_validate' => array('_collabfield_link_validate'),
     );

    }
    return $element;
}
HOW TO CREATE A FIELD

•   To validate an element add #element_validate to the specific
    element
$element['link'] = array(
  '#type' => 'textfield',
  '#title' => t('Link'),
  '#default_value' => isset($items[$delta]['link']) ? $items[$delta]['link'] : NULL,
  '#element_validate' => array('_collabfield_link_validate'),
);

/**
 * Validation callback for a collabfield link element.
 */
function _collabfield_link_validate($element, &$form_state, $form) {
  $value = $element['#value'];
  if (!empty($value) && !valid_url($value, TRUE)) {
    form_error($element, t('Invalid URL.'));
  }

}
HOW TO CREATE A FIELD

• Drupalships with three form element validators in
 field.module

• _element_validate_integer()

• _element_validate_integer_positive()

• _element_validate_number()
HOW TO CREATE A FIELD

• Create   a formatter

• Use
 hook_field_formatter_info
 to setup a formatter

• Use
 hook_field_formatter_view
 for the actual formatter
HOW TO CREATE A FIELD
 /**
  * Implements hook_field_formatter_info().
  */
 function collabfield_field_formatter_info() {
   return array(
     'collabfield_default' => array(
       'label' => t('Default'),
       'field types' => array('collabfield'),
     ),
   );
 }
HOW TO CREATE A FIELD
/**
 * Implements hook_field_formatter_view().
 */
function collabfield_field_formatter_view($entity_type, $entity, $field, $instance, $langcode, $items, $display) {
  $element = array();

    switch ($display['type']) {
      case 'collabfield_default':
       foreach ($items as $delta => $item) {
         $element[$delta]['#markup'] = theme('collabfield_formatter_default', $item);
       }
       break;
    }

    return $element;
}
CUSTOM FORMATTERS
CUSTOM FORMATTERS


• Formatter   to change default term reference link formatter

• Create   as custom module

• Change   URL taxonomy/term/[tid] to whatever/[tid]
CUSTOM FORMATTERS
/**
 * Implements hook_field_formatter_info().
 */
function termpathfield_field_formatter_info() {
  return array(
    'termpathfield_term_reference_link' => array(
      'label' => t('Custom path link'),
      'field types' => array('taxonomy_term_reference'),
      'settings' => array(
        'taxonomy_custom_url' => 'taxonomy/term/[tid]',
      ),
    ),
  );
}
CUSTOM FORMATTERS
/**
 * Implements hook_field_formatter_settings_form().
 */
function termpathfield_field_formatter_settings_form($field, $instance, $view_mode, $form, &$form_state) {
  $display = $instance['display'][$view_mode];
  $settings = $display['settings'];
  $form = array();

    if ($display['type'] == 'termpathfield_term_reference_link') {
      $form['taxonomy_custom_url'] = array(
        '#type' => 'textfield',
        '#title' => t('Custom term page URL'),
        '#default_value' => $settings['taxonomy_custom_url'],
        '#required' => TRUE,
      );
    }

    return $form;
}
CUSTOM FORMATTERS
CUSTOM FORMATTERS
/**
 * Implements hook_field_formatter_settings_summary().
 */
function termpathfield_field_formatter_settings_summary($field, $instance, $view_mode) {
  $display = $instance['display'][$view_mode];
  $settings = $display['settings'];
  $summary = '';

    if ($display['type'] == 'termpathfield_term_reference_link') {
      $summary = $settings['taxonomy_custom_url'];
    }

    return $summary;
}
CUSTOM FORMATTERS
CUSTOM FORMATTERS
/**
 * Implements hook_field_formatter_view().
 */
function termpathfield_field_formatter_view($entity_type, $entity, $field, $instance, $langcode, $items, $display) {
  $result = array();

    switch ($display['type']) {
     case 'termpathfield_term_reference_link':
      foreach ($items as $delta => $item) {
        $term = taxonomy_term_load($item['tid']);

          $uri_path = str_replace('[tid]', $term->tid, $display['settings']['taxonomy_custom_url']);
          $uri = url($uri_path, array('absolute' => TRUE));

          $result[$delta] = array(
            '#type' => 'link',
            '#title' => $term->name,
            '#href' => $uri,
          );
         }
        break;
    }

    return $result;
}
DOCUMENTATION
DOCUMENTATION

• http://api.drupal.org

• Field Types API

 http://api.drupal.org/api/
 drupal/modules--field--
 field.api.php/group/
 field_types/7
DOCUMENTATION


• Other   core field modules

• list.module, number.module,
 options.module and
 text.module

• modules/fields/modules
DOCUMENTATION



• Examples   for Developers

• http://drupal.org/project/
 examples
THE END
Q&A

Fields in Core: How to create a custom field

  • 1.
    FIELDS IN CORE: HOWTO CREATE A CUSTOM FIELD By Ivan Zugec
  • 2.
    WHO AM I? •Name: Ivan Zugec • Drupal username: Ivan Zugec • Twitter: http://twitter.com/zugec • Blog: http://zugec.com
  • 3.
    SESSION AGENDA • What’s new in Drupal 7 • Understanding fields • How to create a field • Custom formatters • Documentation • Q&A
  • 4.
  • 5.
    WHAT’S NEW INDRUPAL 7 • InDrupal 6 we used the CCK module to add fields into nodes
  • 6.
    WHAT’S NEW INDRUPAL 7 • In Drupal 7 a lot of CCK’s functionality has been moved into core • Not all CCK modules made it into core
  • 7.
    WHAT’S NEW INDRUPAL 7 • “Node reference” and “User reference” moved to http:// drupal.org/project/references • “Fieldset” moved to http://drupal.org/project/field_group • “Contentpermission” moved to http://drupal.org/project/ field_permissions
  • 8.
    WHAT’S NEW INDRUPAL 7 • Drupal 7 ships with text, options, number and list • File and image field all in core
  • 9.
  • 10.
    UNDERSTANDING FIELDS • Pieceoffunctionality attached to an entity (node, taxonomy, etc...) • Example: Date module
  • 11.
    UNDERSTANDING FIELDS • Fields have 4 major components • Field • Field type • Widget • Formatter
  • 12.
    UNDERSTANDING FIELDS • Field •field.module, field.info and field.install
  • 13.
    UNDERSTANDING FIELDS /** * Implements hook_field_schema(). */ function text_field_schema($field) { switch ($field['type']) { case 'text': $columns = array( 'value' => array( 'type' => 'varchar', • Field type 'length' => $field['settings']['max_length'], 'not null' => FALSE, ), ); break; • How the field will be stored case 'text_long': .... in the database break; } $columns += array( 'format' => array( 'type' => 'varchar', 'length' => 255, • Using hook_field_schema ), 'not null' => FALSE, ); return array( 'columns' => $columns, • Using hook_field_info 'indexes' => array( ), 'format' => array('format'), 'foreign keys' => array( 'format' => array( 'table' => 'filter_format', 'columns' => array('format' => 'format'), ), ), );
  • 14.
    UNDERSTANDING FIELDS • Widget •Form element a user will use to enter in the data
  • 15.
  • 16.
    UNDERSTANDING FIELDS • Formatter •How to data will be displayed
  • 17.
  • 18.
    HOW TO CREATEA FIELD • Createa custom “Collaborators” field • Module will be called “collabfield” • Unlimited value field with a Name, Role and Link text fields within
  • 19.
    HOW TO CREATEA FIELD • Createa module called collabfield • Createcollabfield.info, collabfield.install and collabfield.module files
  • 20.
    HOW TO CREATEA FIELD collabfield.info ; $Id$ name = Collaborator field description = Custom collaborator field. dependencies[] = field_ui core = 7.x
  • 21.
    HOW TO CREATEA FIELD collabfield.install <?php // $Id$ /** * Implements hook_install(). */ function collabfield_install() { } /** * Implements hook_uninstall(). */ function collabfield_uninstall() { }
  • 22.
    HOW TO CREATEA FIELD /** collabfield.install * Implementation of hook_field_schema(). */ function collabfield_field_schema($field) { if ($field['type'] == 'collabfield') { $schema['columns']['name'] = array( 'type' => 'varchar', 'length' => '255', 'not null' => FALSE, ); $schema['columns']['role'] = array( 'type' => 'varchar', 'length' => '255', 'not null' => FALSE, ); $schema['columns']['link'] = array( 'type' => 'varchar', 'length' => '255', 'not null' => FALSE, ); $schema['indexes'] = array( 'name' => array('name'), 'role' => array('role'), 'link' => array('link'), ); return $schema; }
  • 23.
    HOW TO CREATEA FIELD collabfield.module <?php // $Id$ /** * Implementation of hook_field_info(). */ function collabfield_field_info() { return array( 'collabfield' => array( 'label' => t('Collaborator'), 'description' => t('Custom collaborators field.'), 'default_widget' => 'collabfield_collabfield_form', 'default_formatter' => 'collabfield_default', ), ); }
  • 24.
    HOW TO CREATEA FIELD collabfield.module /** * Implementation of hook_field_is_empty(). */ function collabfield_field_is_empty($item, $field) { if ($field['type'] == 'collabfield') { if (empty($item['name']) && empty($item['role']) && empty($item['link'])) { return TRUE; } } return FALSE; }
  • 25.
    HOW TO CREATEA FIELD • Create a widget • Use hook_field_widget_info to setup field • Use hook_field_widget_form for the actual form element
  • 26.
    HOW TO CREATEA FIELD /** * Implements hook_field_widget_info(). */ function collabfield_field_widget_info() { return array( 'collabfield_collabfield_form' => array( 'label' => t('Collabfield form'), 'field types' => array('collabfield'), 'behaviors' => array( 'multiple values' => FIELD_BEHAVIOR_DEFAULT, //Use FIELD_BEHAVIOR_NONE for no default value. 'default value' => FIELD_BEHAVIOR_DEFAULT, ), ), ); }
  • 27.
    HOW TO CREATEA FIELD /** * Implementation of hook_field_widget_form(). */ function collabfield_field_widget_form(&$form, &$form_state, $field, $instance, $langcode, $items, $delta, $element) { $base = $element; if ($instance['widget']['type'] == 'collabfield_collabfield_form') { $widget = $instance['widget']; $settings = $widget['settings']; $element['name'] = array( '#type' => 'textfield', '#title' => t('Name'), '#default_value' => isset($items[$delta]['name']) ? $items[$delta]['name'] : NULL, ); $element['role'] = array( '#type' => 'textfield', '#title' => t('Role'), '#default_value' => isset($items[$delta]['role']) ? $items[$delta]['role'] : NULL, ); $element['link'] = array( '#type' => 'textfield', '#title' => t('Link'), '#default_value' => isset($items[$delta]['link']) ? $items[$delta]['link'] : NULL, '#element_validate' => array('_collabfield_link_validate'), ); } return $element; }
  • 28.
    HOW TO CREATEA FIELD • To validate an element add #element_validate to the specific element $element['link'] = array( '#type' => 'textfield', '#title' => t('Link'), '#default_value' => isset($items[$delta]['link']) ? $items[$delta]['link'] : NULL, '#element_validate' => array('_collabfield_link_validate'), ); /** * Validation callback for a collabfield link element. */ function _collabfield_link_validate($element, &$form_state, $form) { $value = $element['#value']; if (!empty($value) && !valid_url($value, TRUE)) { form_error($element, t('Invalid URL.')); } }
  • 29.
    HOW TO CREATEA FIELD • Drupalships with three form element validators in field.module • _element_validate_integer() • _element_validate_integer_positive() • _element_validate_number()
  • 30.
    HOW TO CREATEA FIELD • Create a formatter • Use hook_field_formatter_info to setup a formatter • Use hook_field_formatter_view for the actual formatter
  • 31.
    HOW TO CREATEA FIELD /** * Implements hook_field_formatter_info(). */ function collabfield_field_formatter_info() { return array( 'collabfield_default' => array( 'label' => t('Default'), 'field types' => array('collabfield'), ), ); }
  • 32.
    HOW TO CREATEA FIELD /** * Implements hook_field_formatter_view(). */ function collabfield_field_formatter_view($entity_type, $entity, $field, $instance, $langcode, $items, $display) { $element = array(); switch ($display['type']) { case 'collabfield_default': foreach ($items as $delta => $item) { $element[$delta]['#markup'] = theme('collabfield_formatter_default', $item); } break; } return $element; }
  • 33.
  • 34.
    CUSTOM FORMATTERS • Formatter to change default term reference link formatter • Create as custom module • Change URL taxonomy/term/[tid] to whatever/[tid]
  • 35.
    CUSTOM FORMATTERS /** *Implements hook_field_formatter_info(). */ function termpathfield_field_formatter_info() { return array( 'termpathfield_term_reference_link' => array( 'label' => t('Custom path link'), 'field types' => array('taxonomy_term_reference'), 'settings' => array( 'taxonomy_custom_url' => 'taxonomy/term/[tid]', ), ), ); }
  • 36.
    CUSTOM FORMATTERS /** *Implements hook_field_formatter_settings_form(). */ function termpathfield_field_formatter_settings_form($field, $instance, $view_mode, $form, &$form_state) { $display = $instance['display'][$view_mode]; $settings = $display['settings']; $form = array(); if ($display['type'] == 'termpathfield_term_reference_link') { $form['taxonomy_custom_url'] = array( '#type' => 'textfield', '#title' => t('Custom term page URL'), '#default_value' => $settings['taxonomy_custom_url'], '#required' => TRUE, ); } return $form; }
  • 37.
  • 38.
    CUSTOM FORMATTERS /** *Implements hook_field_formatter_settings_summary(). */ function termpathfield_field_formatter_settings_summary($field, $instance, $view_mode) { $display = $instance['display'][$view_mode]; $settings = $display['settings']; $summary = ''; if ($display['type'] == 'termpathfield_term_reference_link') { $summary = $settings['taxonomy_custom_url']; } return $summary; }
  • 39.
  • 40.
    CUSTOM FORMATTERS /** *Implements hook_field_formatter_view(). */ function termpathfield_field_formatter_view($entity_type, $entity, $field, $instance, $langcode, $items, $display) { $result = array(); switch ($display['type']) { case 'termpathfield_term_reference_link': foreach ($items as $delta => $item) { $term = taxonomy_term_load($item['tid']); $uri_path = str_replace('[tid]', $term->tid, $display['settings']['taxonomy_custom_url']); $uri = url($uri_path, array('absolute' => TRUE)); $result[$delta] = array( '#type' => 'link', '#title' => $term->name, '#href' => $uri, ); } break; } return $result; }
  • 41.
  • 42.
    DOCUMENTATION • http://api.drupal.org • FieldTypes API http://api.drupal.org/api/ drupal/modules--field-- field.api.php/group/ field_types/7
  • 43.
    DOCUMENTATION • Other core field modules • list.module, number.module, options.module and text.module • modules/fields/modules
  • 44.
    DOCUMENTATION • Examples for Developers • http://drupal.org/project/ examples
  • 45.
  • 46.