SlideShare une entreprise Scribd logo
1  sur  106
D7 Entites/Fields
 Cyberswat - Kevin Bridges
                             24. aug 10:00
                             Trellon Room
This is Code Heavy
This is Code Heavy

       • We will be discussing
         code
This is Code Heavy

       • We will be discussing
         code
       • If you are not a coder this
         will probably be
         incredibly boring to you
This is Code Heavy

       • We will be discussing
         code
       • If you are not a coder this
         will probably be
         incredibly boring to you
       • We are not responsible
         for what may happen to
         you if you fall asleep.
The Next Hour
The Next Hour
• Lots of content and fast talking. Save questions
  until the end
The Next Hour
• Lots of content and fast talking. Save questions
  until the end
• Discuss key concepts in Drupal 7: Bundles,
  Entities and Fields
The Next Hour
• Lots of content and fast talking. Save questions
  until the end
• Discuss key concepts in Drupal 7: Bundles,
  Entities and Fields
• Walk through the creation of a content type
  that will add a Bundle of Fields complete
  with custom Formatters to the node Entity
The Next Hour
• Lots of content and fast talking. Save questions
  until the end
• Discuss key concepts in Drupal 7: Bundles,
  Entities and Fields
• Walk through the creation of a content type
  that will add a Bundle of Fields complete
  with custom Formatters to the node Entity
• Explain WTH that last comment meant
The Next Hour
• Lots of content and fast talking. Save questions
  until the end
• Discuss key concepts in Drupal 7: Bundles,
  Entities and Fields
• Walk through the creation of a content type
  that will add a Bundle of Fields complete
  with custom Formatters to the node Entity
• Explain WTH that last comment meant
• Introduce the most excellent node_example
  module
Key Concept
  Entity
Key Concept
                Entity
• An Entity is a container for Bundles.
Key Concept
                Entity
• An Entity is a container for Bundles.
• Entities can contain multiple Bundles.
Key Concept
               Entity
• An Entity is a container for Bundles.
• Entities can contain multiple Bundles.
• Examples are Node, User, File, Taxonomy Term,
  Taxonomy Vocabulary
Key Concept
               Entity
• An Entity is a container for Bundles.
• Entities can contain multiple Bundles.
• Examples are Node, User, File, Taxonomy Term,
  Taxonomy Vocabulary
• Why not make everything an Entity?
Key Concept
  Bundles
Key Concept
                 Bundles

• A Bundle is a set of fields that are treated as a
  group by the Field API
Key Concept
                 Bundles

• A Bundle is a set of fields that are treated as a
  group by the Field API
• Bundles are similar in concept to a node type in
  Drupal 6
Key Concept
   Fields
Key Concept
                  Fields
• A field defines a particular type of data that can
  be attached to any entity and can be shared
  between entities
Key Concept
                  Fields
• A field defines a particular type of data that can
  be attached to any entity and can be shared
  between entities
• A field can have Widgets. A widget is the UI
  element that allows a user to enter data into the
  field
Key Concept
                  Fields
• A field defines a particular type of data that can
  be attached to any entity and can be shared
  between entities
• A field can have Widgets. A widget is the UI
  element that allows a user to enter data into the
  field
• A field can have Formatters. A formatter defines
  how a fields data gets displayed in a view mode
The Examples Module
The Examples Module
• In my mind, the best resource for learning is the
  Examples Modue
The Examples Module
• In my mind, the best resource for learning is the
  Examples Modue
• This module used to live exclusively in CVS but is
  now maintained by rfay, Dave Reid, katbailey
  and ilo in contrib
The Examples Module
• In my mind, the best resource for learning is the
  Examples Modue
• This module used to live exclusively in CVS but is
  now maintained by rfay, Dave Reid, katbailey
  and ilo in contrib
• Documentation can be viewed from
  api.drupal.org by following the Examples link
The Examples Module
• In my mind, the best resource for learning is the
  Examples Modue
• This module used to live exclusively in CVS but is
  now maintained by rfay, Dave Reid, katbailey
  and ilo in contrib
• Documentation can be viewed from
  api.drupal.org by following the Examples link
• drupal.org/project/examples - not just the node
  module
Examples Needs Help
Examples Needs Help
D7 *.install
D7 *.install
• We still implement hook_install() and
  hook_uninstall()
D7 *.install
• We still implement hook_install() and
  hook_uninstall()
• hook_schema() no longer needs to be explicitly
  called
D7 *.install
• We still implement hook_install() and
  hook_uninstall()
• hook_schema() no longer needs to be explicitly
  called
• Database structure will resemble D6 CCK tables
D7 *.install
• We still implement hook_install() and
  hook_uninstall()
• hook_schema() no longer needs to be explicitly
  called
• Database structure will resemble D6 CCK tables
• Database Entity revisions are provided
  automatically
/**
 * Implements hook_install().
 *
 */
function node_example_install() {
 ...
}
/**
 * Implements hook_install().
 *
 */
function node_example_install() {
 ...
}

/**
 * Return a structured array defining the fields created by this content type.
 *
 * This is packaged in a function so it can be used in both hook_install()
 * and hook_uninstall().
 */
function _node_example_installed_fields() {
 ...
}
/**
 * Implements hook_install().
 *
 */
function node_example_install() {
 ...
}

/**
 * Return a structured array defining the fields created by this content type.
 *
 * This is packaged in a function so it can be used in both hook_install()
 * and hook_uninstall().
 */
function _node_example_installed_fields() {
 ...
}

/**
 * Return a structured array defining the instances for this content type.
 *
 * The instance lets Drupal know which widget to use to allow the user to enter
 * data and how to react in different view modes.
 * This is provided as a function so that it can be used in both hook_install()
 * and hook_uninstall().
 */
function _node_example_installed_instances() {
 ...
}
/**
 * Implements hook_install().
 *
 */
function node_example_install() {
 ...
}

/**
 * Return a structured array defining the fields created by this content type.
 *
 * This is packaged in a function so it can be used in both hook_install()
 * and hook_uninstall().
 */
function _node_example_installed_fields() {
 ...
}

/**
 * Return a structured array defining the instances for this content type.
 *
 * The instance lets Drupal know which widget to use to allow the user to enter
 * data and how to react in different view modes.
 * This is provided as a function so that it can be used in both hook_install()
 * and hook_uninstall().
 */
function _node_example_installed_instances() {
 ...
}

/**
 * Implements hook_uninstall().
 *
 */
function node_example_uninstall() {
 ...
}
D7 *.install
D7 *.install

• hook_install() will set up our content type
D7 *.install

• hook_install() will set up our content type
• hook_install() is where we create our fields, if
  needed
D7 *.install

• hook_install() will set up our content type
• hook_install() is where we create our fields, if
  needed
• hook_install() is used to tie our fields to an
  Entity as a Bundle
function node_example_install() {




}
function node_example_install() {
  $types = node_type_get_types();
  node_add_body_field($types['node_example']);




}
function node_example_install() {
  $types = node_type_get_types();
  node_add_body_field($types['node_example']);
    // Load the instance definition for our content type's body
    // http://api.drupal.org/api/function/field_info_instance/7
    $body_instance = field_info_instance('node', 'body', 'node_example');




}
function node_example_install() {
  $types = node_type_get_types();
  node_add_body_field($types['node_example']);
    // Load the instance definition for our content type's body
    // http://api.drupal.org/api/function/field_info_instance/7
    $body_instance = field_info_instance('node', 'body', 'node_example');

    // Add our example_node_list view mode to the body instance display by
    // instructing the body to display as a summary
    $body_instance['type'] = 'text_summary_or_trimmed';




}
function node_example_install() {
  $types = node_type_get_types();
  node_add_body_field($types['node_example']);
    // Load the instance definition for our content type's body
    // http://api.drupal.org/api/function/field_info_instance/7
    $body_instance = field_info_instance('node', 'body', 'node_example');

    // Add our example_node_list view mode to the body instance display by
    // instructing the body to display as a summary
    $body_instance['type'] = 'text_summary_or_trimmed';

    // Save our changes to the body field instance.
    // http://api.drupal.org/api/function/field_update_instance/7
    field_update_instance($body_instance);




}
function node_example_install() {
  $types = node_type_get_types();
  node_add_body_field($types['node_example']);
     // Load the instance definition for our content type's body
     // http://api.drupal.org/api/function/field_info_instance/7
     $body_instance = field_info_instance('node', 'body', 'node_example');

     // Add our example_node_list view mode to the body instance display by
     // instructing the body to display as a summary
     $body_instance['type'] = 'text_summary_or_trimmed';

    // Save our changes to the body field instance.
    // http://api.drupal.org/api/function/field_update_instance/7
    field_update_instance($body_instance);

    // Create all the fields we are adding to our content type.
    // http://api.drupal.org/api/function/field_create_field/7
    foreach (_node_example_installed_fields() as $field) {
      field_create_field($field);
    }




}
function node_example_install() {
  $types = node_type_get_types();
  node_add_body_field($types['node_example']);
     // Load the instance definition for our content type's body
     // http://api.drupal.org/api/function/field_info_instance/7
     $body_instance = field_info_instance('node', 'body', 'node_example');

     // Add our example_node_list view mode to the body instance display by
     // instructing the body to display as a summary
     $body_instance['type'] = 'text_summary_or_trimmed';

    // Save our changes to the body field instance.
    // http://api.drupal.org/api/function/field_update_instance/7
    field_update_instance($body_instance);

    // Create all the fields we are adding to our content type.
    // http://api.drupal.org/api/function/field_create_field/7
    foreach (_node_example_installed_fields() as $field) {
      field_create_field($field);
    }

    // Create all the instances for our fields.
    // http://api.drupal.org/api/function/field_create_instance/7
    foreach (_node_example_installed_instances() as $instance) {
      $instance['entity_type'] = 'node';
      $instance['bundle'] = 'node_example';
      field_create_instance($instance);
    }
}
D7 *.install
D7 *.install


• The node_example module defines and invokes
  3 distinct fields
D7 *.install


• The node_example module defines and invokes
  3 distinct fields
• We place these in a helper function so that it can
  be called as needed in functions like
  hook_install() and hook_uninstall()
function _node_example_installed_fields() {
 $t = get_t();
 return array(




    );
}
function _node_example_installed_fields() {
 $t = get_t();
 return array(
    'node_example_color' => array(
      'field_name' => 'node_example_color',
      'label'     => $t('The colors available for this object.'),
      'cardinality' => 3,
      'type'       => 'text',
      'settings'    => array(
        'max_length' => 60,
      ),
    ),




    );
}
function _node_example_installed_fields() {
 $t = get_t();
 return array(
    'node_example_color' => array(
      'field_name' => 'node_example_color',
      'label'     => $t('The colors available for this object.'),
      'cardinality' => 3,
      'type'       => 'text',
      'settings'    => array(
        'max_length' => 60,
      ),
    ),
    'node_example_quantity' => array(
      'field_name' => 'node_example_quantity',
      'type'    => 'text',
    ),




    );
}
function _node_example_installed_fields() {
 $t = get_t();
 return array(
    'node_example_color' => array(
      'field_name' => 'node_example_color',
      'label'     => $t('The colors available for this object.'),
      'cardinality' => 3,
      'type'       => 'text',
      'settings'    => array(
        'max_length' => 60,
      ),
    ),
     'node_example_quantity' => array(
        'field_name' => 'node_example_quantity',
        'type'      => 'text',
     ),
      'node_example_image' => array(
         'field_name' => 'node_example_image',
         'type'      => 'image',
         'cardinality' => 1,
      ),
    );
}
D7 *.install


• This is the fun part ... we get to apply formatters
  to the instances to control their display and
  widgets to control the input
$t = get_t();
return array(




);
$t = get_t();
return array(

     'node_example_color' => array(
       'field_name' => 'node_example_color',
       'label'      => $t('The colors available for this object.'),
       'cardinality' => 3,
       'widget'      => array(
         'type' => 'text_textfield',
       ),
       'display' => array(
         'example_node_list' => array(
           'label' => 'hidden',
           'type' => 'node_example_colors',
         ),
       ),
     ),




);
$t = get_t();
return array(

     'node_example_color' => array(
       'field_name' => 'node_example_color',
       'label'      => $t('The colors available for this object.'),
       'cardinality' => 3,
       'widget'      => array(
         'type' => 'text_textfield',
       ),
       'display' => array(
         'example_node_list' => array(
           'label' => 'hidden',
           'type' => 'node_example_colors',
         ),
       ),
     ),
     'node_example_quantity' => array(
       'field_name' => 'node_example_quantity',
       'type'       => 'text',
       'widget'      => array(
         'type' => 'text_textfield',
       ),
       'display' => array(
         'example_node_list' => array(
           'label' => 'hidden',
           'type' => 'hidden',
         ),
       ),
     ),




);
$t = get_t();
return array(

     'node_example_color' => array(
       'field_name' => 'node_example_color',
       'label'      => $t('The colors available for this object.'),
       'cardinality' => 3,
       'widget'      => array(
         'type' => 'text_textfield',
       ),
       'display' => array(
         'example_node_list' => array(
           'label' => 'hidden',
           'type' => 'node_example_colors',
         ),
       ),
     ),
     'node_example_quantity' => array(
       'field_name' => 'node_example_quantity',
       'type'          => 'text',
       'widget'         => array(
          'type' => 'text_textfield',
       ),
       'display' => array(
          'example_node_list' => array(
             'label' => 'hidden',
             'type' => 'hidden',
          ),
       ),
     ),
     'node_example_image' => array(
        'field_name' => 'node_example_image',
        'label'        => $t('Upload an image:'),
        'required' => FALSE,
        'widget' => array(
           'type' => 'image_image',
           'weight' => 2.10,
        ),
        'display' => array(
           'example_node_list' => array(
              'label' => 'hidden',
              'type' => 'image_link_content__thumbnail',
           ),
        ),
     ),

);
D7 *.install
D7 *.install

• hook_uninstall() is used to clean up the data
  created with the node_example module
D7 *.install

• hook_uninstall() is used to clean up the data
  created with the node_example module
• hook_uninstall() deletes our fields and their
  instances
D7 *.install

• hook_uninstall() is used to clean up the data
  created with the node_example module
• hook_uninstall() deletes our fields and their
  instances
• hook_uninstall() deletes our content type
D7 *.install

• hook_uninstall() is used to clean up the data
  created with the node_example module
• hook_uninstall() deletes our fields and their
  instances
• hook_uninstall() deletes our content type
• hook_uninstall purges field data from the system
function node_example_uninstall() {




}
function node_example_uninstall() {
  // Gather all the example content that might have been created while this
  // module was enabled. Simple selects still use db_query().
  // http://api.drupal.org/api/function/db_query/7
  $sql = 'SELECT nid FROM {node} n WHERE n.type = :type';
  $result = db_query($sql, array(':type' => 'node_example'));
  $nids = array();
  foreach ($result as $row) {
    $nids[] = $row->nid;
  }




}
function node_example_uninstall() {
  // Gather all the example content that might have been created while this
  // module was enabled. Simple selects still use db_query().
  // http://api.drupal.org/api/function/db_query/7
  $sql = 'SELECT nid FROM {node} n WHERE n.type = :type';
  $result = db_query($sql, array(':type' => 'node_example'));
  $nids = array();
  foreach ($result as $row) {
    $nids[] = $row->nid;
  }

    // Delete all the nodes at once
    // http://api.drupal.org/api/function/node_delete_multiple/7
    node_delete_multiple($nids);




}
function node_example_uninstall() {
  // Gather all the example content that might have been created while this
  // module was enabled. Simple selects still use db_query().
  // http://api.drupal.org/api/function/db_query/7
  $sql = 'SELECT nid FROM {node} n WHERE n.type = :type';
  $result = db_query($sql, array(':type' => 'node_example'));
  $nids = array();
  foreach ($result as $row) {
    $nids[] = $row->nid;
  }

    // Delete all the nodes at once
    // http://api.drupal.org/api/function/node_delete_multiple/7
    node_delete_multiple($nids);

    // Loop over each of the fields defined by this module and delete
    // all instances of the field, their data, and the field itself.
    // http://api.drupal.org/api/function/field_delete_field/7
    foreach (array_keys(_node_example_installed_fields()) as $field) {
      field_delete_field($field);
    }




}
function node_example_uninstall() {
  // Gather all the example content that might have been created while this
  // module was enabled. Simple selects still use db_query().
  // http://api.drupal.org/api/function/db_query/7
  $sql = 'SELECT nid FROM {node} n WHERE n.type = :type';
  $result = db_query($sql, array(':type' => 'node_example'));
  $nids = array();
  foreach ($result as $row) {
    $nids[] = $row->nid;
  }

    // Delete all the nodes at once
    // http://api.drupal.org/api/function/node_delete_multiple/7
    node_delete_multiple($nids);

    // Loop over each of the fields defined by this module and delete
    // all instances of the field, their data, and the field itself.
    // http://api.drupal.org/api/function/field_delete_field/7
    foreach (array_keys(_node_example_installed_fields()) as $field) {
      field_delete_field($field);
    }

    // Loop over any remaining field instances attached to the node_example
    // content type (such as the body field) and delete them individually.
    // http://api.drupal.org/api/function/field_delete_field/7
    $instances = field_info_instances('node', 'node_example');
    foreach ($instances as $instance_name => $instance) {
      field_delete_instance($instance);
    }




}
function node_example_uninstall() {
  // Gather all the example content that might have been created while this
  // module was enabled. Simple selects still use db_query().
  // http://api.drupal.org/api/function/db_query/7
  $sql = 'SELECT nid FROM {node} n WHERE n.type = :type';
  $result = db_query($sql, array(':type' => 'node_example'));
  $nids = array();
  foreach ($result as $row) {
    $nids[] = $row->nid;
  }

    // Delete all the nodes at once
    // http://api.drupal.org/api/function/node_delete_multiple/7
    node_delete_multiple($nids);

    // Loop over each of the fields defined by this module and delete
    // all instances of the field, their data, and the field itself.
    // http://api.drupal.org/api/function/field_delete_field/7
    foreach (array_keys(_node_example_installed_fields()) as $field) {
      field_delete_field($field);
    }

    // Loop over any remaining field instances attached to the node_example
    // content type (such as the body field) and delete them individually.
    // http://api.drupal.org/api/function/field_delete_field/7
    $instances = field_info_instances('node', 'node_example');
    foreach ($instances as $instance_name => $instance) {
      field_delete_instance($instance);
    }

    // Delete our content type
    // http://api.drupal.org/api/function/node_type_delete/7
    node_type_delete('node_example');




}
function node_example_uninstall() {
  // Gather all the example content that might have been created while this
  // module was enabled. Simple selects still use db_query().
  // http://api.drupal.org/api/function/db_query/7
  $sql = 'SELECT nid FROM {node} n WHERE n.type = :type';
  $result = db_query($sql, array(':type' => 'node_example'));
  $nids = array();
  foreach ($result as $row) {
    $nids[] = $row->nid;
  }

    // Delete all the nodes at once
    // http://api.drupal.org/api/function/node_delete_multiple/7
    node_delete_multiple($nids);

    // Loop over each of the fields defined by this module and delete
    // all instances of the field, their data, and the field itself.
    // http://api.drupal.org/api/function/field_delete_field/7
    foreach (array_keys(_node_example_installed_fields()) as $field) {
      field_delete_field($field);
    }

    // Loop over any remaining field instances attached to the node_example
    // content type (such as the body field) and delete them individually.
    // http://api.drupal.org/api/function/field_delete_field/7
    $instances = field_info_instances('node', 'node_example');
    foreach ($instances as $instance_name => $instance) {
      field_delete_instance($instance);
    }

    // Delete our content type
    // http://api.drupal.org/api/function/node_type_delete/7
    node_type_delete('node_example');

    // Purge all field information
    // http://api.drupal.org/api/function/field_purge_batch/7
    field_purge_batch(1000);
}
D7 *.module
D7 *.module
• Finally on to the module file!
D7 *.module
• Finally on to the module file!
• Let’s start with the hooks we will recognize from
  D6
D7 *.module
• Finally on to the module file!
• Let’s start with the hooks we will recognize from
  D6
• hook_node_info() informs Drupal about our
  content type
D7 *.module
• Finally on to the module file!
• Let’s start with the hooks we will recognize from
  D6
• hook_node_info() informs Drupal about our
  content type
• hook_menu() tells Drupal where our custom
  page is going to live and how to build it
D7 *.module
• Finally on to the module file!
• Let’s start with the hooks we will recognize from
  D6
• hook_node_info() informs Drupal about our
  content type
• hook_menu() tells Drupal where our custom
  page is going to live and how to build it
• hook_help() provides help information for our
  users
/**
 * Implements hook_node_info() to provide our node_example type.
 */
function node_example_node_info() {
  return array(
    'node_example' => array(
      'name' => t('Example Node'),
      'base' => 'node_example',
      'description' => t('This is an example node type with a few fields.'),
      'has_title' => TRUE,
    ),
  );
}
/**
 * Implements hook_node_info() to provide our node_example type.
 */
function node_example_node_info() {
   return array(
     'node_example' => array(
        'name' => t('Example Node'),
        'base' => 'node_example',
        'description' => t('This is an example node type with a few fields.'),
        'has_title' => TRUE,
     ),
   );
}
/**
  * Implements hook_menu().
  *
  * We are providing a default page to illustrate the use of our custom node view
  * mode that will live at http://example.com/?q=examples/node_example
  */
function node_example_menu() {
   $items['examples/node_example'] = array(
      'page callback' => 'node_example_page',
      'access arguments' => array('access content'),
      'title' => 'Node Example',
   );
   return $items;
}
/**
 * Implements hook_node_info() to provide our node_example type.
 */
function node_example_node_info() {
   return array(
     'node_example' => array(
        'name' => t('Example Node'),
        'base' => 'node_example',
        'description' => t('This is an example node type with a few fields.'),
        'has_title' => TRUE,
     ),
   );
}
/**
  * Implements hook_menu().
  *
  * We are providing a default page to illustrate the use of our custom node view
  * mode that will live at http://example.com/?q=examples/node_example
  */
function node_example_menu() {
   $items['examples/node_example'] = array(
      'page callback' => 'node_example_page',
      'access arguments' => array('access content'),
      'title' => 'Node Example',
   );
   return $items;
}
/**
  * Implements hook_help().
  */
function node_example_help($path, $arg) {
   switch ($path) {
      case 'examples/node_example':
        return "<p>" . t(
          "The Node Example module provides a custom node type.
          You can create new nodes using the <a href='!nodeadd'>node add form</a>.
          Nodes that you create will be displayed here.",
          array('!nodeadd' => url('node/add/node-example'))
        ) . "</p>";
   }
}
d7 *.module
d7 *.module


• hook_form() is used to create the basic content
  form
d7 *.module


• hook_form() is used to create the basic content
  form
• hook_theme() informs Drupal of our theme
  callbacks
/**
 * Implement hook_form() with the standard default form.
 */
function node_example_form($node, $form_state) {
  return node_content_form($node, $form_state);
}
/**
 * Implement hook_form() with the standard default form.
 */
function node_example_form($node, $form_state) {
  return node_content_form($node, $form_state);
}


/**
 * Implements hook_theme().
 *
 * This lets us tell Drupal about our theme functions and their arguments.
 */
function node_example_theme($existing, $type, $theme, $path) {
  return array(
    'example_node_color' => array(
      'variables' => array('color' => NULL),
    ),
  );
}
/**
 * Implement hook_form() with the standard default form.
 */
function node_example_form($node, $form_state) {
  return node_content_form($node, $form_state);
}


/**
 * Implements hook_theme().
 *
 * This lets us tell Drupal about our theme functions and their arguments.
 */
function node_example_theme($existing, $type, $theme, $path) {
  return array(
    'example_node_color' => array(
      'variables' => array('color' => NULL),
    ),
  );
}



/**
 * A custom theme function.
 *
 * By using this function to format our node-specific information, themes
 * can override this presentation if they wish. This is a simplified theme
 * function purely for illustrative purposes.
 */
function theme_example_node_color($variables) {
  $output = '<span style="background-color: #ccc; padding: 1em; margin-bottom: 1em; float: left; color: ' .
   $variables['color'] . '">' . $variables['color'] . '</span>';
  return $output;
}
D7 *.module
D7 *.module

• Now for the juicy D7 changes!!!
D7 *.module

• Now for the juicy D7 changes!!!
• hook_entity_info_alter() lets us modify the
  node_entity to use our custom view mode
D7 *.module

• Now for the juicy D7 changes!!!
• hook_entity_info_alter() lets us modify the
  node_entity to use our custom view mode
• hook_field_formatter_view() is where we place
  the details of our custom view mode
/**
 * Implements hook_entity_info_alter().
 *
 * We need to modify the default node entity info by adding a new view mode to
 * be used in functions like node_view() or node_build_content().
 *
 */
function node_example_entity_info_alter(&$entity_info) {
  $entity_info['node']['view modes']['example_node_list'] = array(
    'label' => t('Example Node List'),
    'custom settings' => TRUE,
  );
}
/**
  * Implements hook_entity_info_alter().
  *
  * We need to modify the default node entity info by adding a new view mode to
  * be used in functions like node_view() or node_build_content().
  *
  */
 function node_example_entity_info_alter(&$entity_info) {
   $entity_info['node']['view modes']['example_node_list'] = array(
     'label' => t('Example Node List'),
     'custom settings' => TRUE,
   );
 }


/**
 * Implements hook_field_formatter_info().
 */
function node_example_field_formatter_info() {
  return array(
    'node_example_colors' => array(
      'label' => t('Node Example Color Handle'),
      'field types' => array('text'),
    ),
  );
}
D7 *.module
D7 *.module


• Last ... but certainly not least
D7 *.module


• Last ... but certainly not least
• hook_field_formatter_view() is where we place
  the details of our custom view mode
/**
 * Implements hook_field_formatter_view().
 *
 * @todo: We need to provide a formatter for the colors that a user is allowed to enter
 * during node creation.
 */
function node_example_field_formatter_view($object_type, $object, $field, $instance, $langcode, $items, $display) {
  $element = array();
  switch ($display['type']) {
    case 'node_example_colors':
     foreach ($items as $delta => $item) {
       $element[$delta]['#type'] = 'markup';
       $color = $item['safe_value'];
       $element[$delta]['#markup'] = theme('example_node_color', array('color' => $color));
     }
     break;
  }

    return $element;
}
Informative Links
•   The field API Tutorial - http://drupal.org/node/707832

•   The Field API Glossary - http://drupal.org/node/443540

•   Adding and Reusing a Field - http://drupal.org/node/
    474420

•   Making an Entity Fieldable - http://drupal.org/node/
    474582

•   The Examples Module - http://drupal.org/project/
    examples

•   Drupal API - http://api.drupal.org/

•   Joachim’s http://drupal.org/project/field_convert
http://cph2010.drupal.org/node/13323

Contenu connexe

En vedette

Workplace Economy Slides September 2011 9.7.2011
Workplace Economy Slides September 2011 9.7.2011Workplace Economy Slides September 2011 9.7.2011
Workplace Economy Slides September 2011 9.7.2011Michael Shafran
 
Weekly news 14
Weekly news 14Weekly news 14
Weekly news 14samankit
 
Introduction & trends - Journal Publishing in SA
Introduction & trends - Journal Publishing in SAIntroduction & trends - Journal Publishing in SA
Introduction & trends - Journal Publishing in SAIna Smith
 
EXPERT_Malaga-ESR03
EXPERT_Malaga-ESR03EXPERT_Malaga-ESR03
EXPERT_Malaga-ESR03hpcosta
 
Weekly news 13
Weekly news 13Weekly news 13
Weekly news 13samankit
 
5th weekly news
5th weekly news5th weekly news
5th weekly newssamankit
 
Blogs and wikis keynote
Blogs and wikis keynoteBlogs and wikis keynote
Blogs and wikis keynoteTeresa Wells
 
Weekly news 14
Weekly news 14Weekly news 14
Weekly news 14samankit
 
Trip to Lisbon
Trip to LisbonTrip to Lisbon
Trip to Lisbonsamankit
 
El mecànic de cas concos.
El mecànic de cas concos.El mecànic de cas concos.
El mecànic de cas concos.migjorncasconcos
 
GO Overview
GO OverviewGO Overview
GO OverviewGoingOn
 
C:\Fakepath\Marmoroc Fassaadi Paigaldus
C:\Fakepath\Marmoroc Fassaadi PaigaldusC:\Fakepath\Marmoroc Fassaadi Paigaldus
C:\Fakepath\Marmoroc Fassaadi PaigaldusErek Fassaadid
 
Berghaan 2014 Stellenbosch Toastmasters
Berghaan 2014 Stellenbosch ToastmastersBerghaan 2014 Stellenbosch Toastmasters
Berghaan 2014 Stellenbosch ToastmastersIna Smith
 
Smith uct researchweek
Smith uct researchweekSmith uct researchweek
Smith uct researchweekIna Smith
 
3rd weekly news
3rd weekly news3rd weekly news
3rd weekly newssamankit
 
Mehakate phool
Mehakate phoolMehakate phool
Mehakate phoolgurusewa
 

En vedette (20)

Workplace Economy Slides September 2011 9.7.2011
Workplace Economy Slides September 2011 9.7.2011Workplace Economy Slides September 2011 9.7.2011
Workplace Economy Slides September 2011 9.7.2011
 
Weekly news 14
Weekly news 14Weekly news 14
Weekly news 14
 
Ei99 manual
Ei99 manualEi99 manual
Ei99 manual
 
Elurra
ElurraElurra
Elurra
 
Only One
Only OneOnly One
Only One
 
Introduction & trends - Journal Publishing in SA
Introduction & trends - Journal Publishing in SAIntroduction & trends - Journal Publishing in SA
Introduction & trends - Journal Publishing in SA
 
EXPERT_Malaga-ESR03
EXPERT_Malaga-ESR03EXPERT_Malaga-ESR03
EXPERT_Malaga-ESR03
 
Weekly news 13
Weekly news 13Weekly news 13
Weekly news 13
 
5th weekly news
5th weekly news5th weekly news
5th weekly news
 
Blogs and wikis keynote
Blogs and wikis keynoteBlogs and wikis keynote
Blogs and wikis keynote
 
Weekly news 14
Weekly news 14Weekly news 14
Weekly news 14
 
Trip to Lisbon
Trip to LisbonTrip to Lisbon
Trip to Lisbon
 
El mecànic de cas concos.
El mecànic de cas concos.El mecànic de cas concos.
El mecànic de cas concos.
 
GO Overview
GO OverviewGO Overview
GO Overview
 
C:\Fakepath\Marmoroc Fassaadi Paigaldus
C:\Fakepath\Marmoroc Fassaadi PaigaldusC:\Fakepath\Marmoroc Fassaadi Paigaldus
C:\Fakepath\Marmoroc Fassaadi Paigaldus
 
Bestiario
BestiarioBestiario
Bestiario
 
Berghaan 2014 Stellenbosch Toastmasters
Berghaan 2014 Stellenbosch ToastmastersBerghaan 2014 Stellenbosch Toastmasters
Berghaan 2014 Stellenbosch Toastmasters
 
Smith uct researchweek
Smith uct researchweekSmith uct researchweek
Smith uct researchweek
 
3rd weekly news
3rd weekly news3rd weekly news
3rd weekly news
 
Mehakate phool
Mehakate phoolMehakate phool
Mehakate phool
 

Similaire à Drupalcon cph

Ready. Set. Drupal! An Intro to Drupal 8, Part 2
Ready. Set. Drupal! An Intro to Drupal 8, Part 2Ready. Set. Drupal! An Intro to Drupal 8, Part 2
Ready. Set. Drupal! An Intro to Drupal 8, Part 2Acquia
 
C++ Introduction brown bag
C++ Introduction brown bagC++ Introduction brown bag
C++ Introduction brown bagJacob Green
 
Drupal upgrades and migrations. BAD Camp 2013 version
Drupal upgrades and migrations. BAD Camp 2013 versionDrupal upgrades and migrations. BAD Camp 2013 version
Drupal upgrades and migrations. BAD Camp 2013 versionDavid Lanier
 
Top 8 Improvements in Drupal 8
Top 8 Improvements in Drupal 8Top 8 Improvements in Drupal 8
Top 8 Improvements in Drupal 8Angela Byron
 
Entities in Drupal 8 - Drupal Tech Talk - Bart Feenstra
Entities in Drupal 8 - Drupal Tech Talk - Bart FeenstraEntities in Drupal 8 - Drupal Tech Talk - Bart Feenstra
Entities in Drupal 8 - Drupal Tech Talk - Bart FeenstraTriquanta
 
modern module development - Ken Barber 2012 Edinburgh Puppet Camp
modern module development - Ken Barber 2012 Edinburgh Puppet Campmodern module development - Ken Barber 2012 Edinburgh Puppet Camp
modern module development - Ken Barber 2012 Edinburgh Puppet CampPuppet
 
Entity API in Drupal 8 (Drupal Tech Talk October 2014)
Entity API in Drupal 8 (Drupal Tech Talk October 2014)Entity API in Drupal 8 (Drupal Tech Talk October 2014)
Entity API in Drupal 8 (Drupal Tech Talk October 2014)Bart Feenstra
 
Chapter15-Presentation.pptx
Chapter15-Presentation.pptxChapter15-Presentation.pptx
Chapter15-Presentation.pptxGFRomano
 
Modules Building Presentation
Modules Building PresentationModules Building Presentation
Modules Building Presentationhtyson
 
Object Oriented Views / Aki Salmi
Object Oriented Views / Aki SalmiObject Oriented Views / Aki Salmi
Object Oriented Views / Aki SalmiAki Salmi
 
Drupal 7 entities & TextbookMadness.com
Drupal 7 entities & TextbookMadness.comDrupal 7 entities & TextbookMadness.com
Drupal 7 entities & TextbookMadness.comJD Leonard
 
drupal 7 amfserver presentation: integrating flash and drupal
drupal 7 amfserver presentation: integrating flash and drupaldrupal 7 amfserver presentation: integrating flash and drupal
drupal 7 amfserver presentation: integrating flash and drupalrolf vreijdenberger
 
ZendCon 2011 UnCon Domain-Driven Design
ZendCon 2011 UnCon Domain-Driven DesignZendCon 2011 UnCon Domain-Driven Design
ZendCon 2011 UnCon Domain-Driven DesignBradley Holt
 
Decoupled Libraries for PHP
Decoupled Libraries for PHPDecoupled Libraries for PHP
Decoupled Libraries for PHPPaul Jones
 
Your first d8 module
Your first d8 moduleYour first d8 module
Your first d8 moduletedbow
 
Cs 1023 lec 8 design pattern (week 2)
Cs 1023 lec 8 design pattern (week 2)Cs 1023 lec 8 design pattern (week 2)
Cs 1023 lec 8 design pattern (week 2)stanbridge
 
Cloud Infrastructures Slide Set 7 - Docker - Neo4j | anynines
Cloud Infrastructures Slide Set 7 - Docker - Neo4j | anyninesCloud Infrastructures Slide Set 7 - Docker - Neo4j | anynines
Cloud Infrastructures Slide Set 7 - Docker - Neo4j | anyninesanynines GmbH
 
Introduction To Design Patterns Class 4 Composition vs Inheritance
 Introduction To Design Patterns Class 4 Composition vs Inheritance Introduction To Design Patterns Class 4 Composition vs Inheritance
Introduction To Design Patterns Class 4 Composition vs InheritanceBlue Elephant Consulting
 
Scriptable Objects in Unity Game Engine (C#)
Scriptable Objects in Unity Game Engine (C#)Scriptable Objects in Unity Game Engine (C#)
Scriptable Objects in Unity Game Engine (C#)Om Shridhar
 

Similaire à Drupalcon cph (20)

Ready. Set. Drupal! An Intro to Drupal 8, Part 2
Ready. Set. Drupal! An Intro to Drupal 8, Part 2Ready. Set. Drupal! An Intro to Drupal 8, Part 2
Ready. Set. Drupal! An Intro to Drupal 8, Part 2
 
C++ Introduction brown bag
C++ Introduction brown bagC++ Introduction brown bag
C++ Introduction brown bag
 
Drupal upgrades and migrations. BAD Camp 2013 version
Drupal upgrades and migrations. BAD Camp 2013 versionDrupal upgrades and migrations. BAD Camp 2013 version
Drupal upgrades and migrations. BAD Camp 2013 version
 
Top 8 Improvements in Drupal 8
Top 8 Improvements in Drupal 8Top 8 Improvements in Drupal 8
Top 8 Improvements in Drupal 8
 
Entities in Drupal 8 - Drupal Tech Talk - Bart Feenstra
Entities in Drupal 8 - Drupal Tech Talk - Bart FeenstraEntities in Drupal 8 - Drupal Tech Talk - Bart Feenstra
Entities in Drupal 8 - Drupal Tech Talk - Bart Feenstra
 
modern module development - Ken Barber 2012 Edinburgh Puppet Camp
modern module development - Ken Barber 2012 Edinburgh Puppet Campmodern module development - Ken Barber 2012 Edinburgh Puppet Camp
modern module development - Ken Barber 2012 Edinburgh Puppet Camp
 
Entity API in Drupal 8 (Drupal Tech Talk October 2014)
Entity API in Drupal 8 (Drupal Tech Talk October 2014)Entity API in Drupal 8 (Drupal Tech Talk October 2014)
Entity API in Drupal 8 (Drupal Tech Talk October 2014)
 
Chapter15-Presentation.pptx
Chapter15-Presentation.pptxChapter15-Presentation.pptx
Chapter15-Presentation.pptx
 
Modules Building Presentation
Modules Building PresentationModules Building Presentation
Modules Building Presentation
 
Object Oriented Views / Aki Salmi
Object Oriented Views / Aki SalmiObject Oriented Views / Aki Salmi
Object Oriented Views / Aki Salmi
 
Drupal 7 entities & TextbookMadness.com
Drupal 7 entities & TextbookMadness.comDrupal 7 entities & TextbookMadness.com
Drupal 7 entities & TextbookMadness.com
 
drupal 7 amfserver presentation: integrating flash and drupal
drupal 7 amfserver presentation: integrating flash and drupaldrupal 7 amfserver presentation: integrating flash and drupal
drupal 7 amfserver presentation: integrating flash and drupal
 
ZendCon 2011 UnCon Domain-Driven Design
ZendCon 2011 UnCon Domain-Driven DesignZendCon 2011 UnCon Domain-Driven Design
ZendCon 2011 UnCon Domain-Driven Design
 
Decoupled Libraries for PHP
Decoupled Libraries for PHPDecoupled Libraries for PHP
Decoupled Libraries for PHP
 
Your first d8 module
Your first d8 moduleYour first d8 module
Your first d8 module
 
Cs 1023 lec 8 design pattern (week 2)
Cs 1023 lec 8 design pattern (week 2)Cs 1023 lec 8 design pattern (week 2)
Cs 1023 lec 8 design pattern (week 2)
 
Cloud Infrastructures Slide Set 7 - Docker - Neo4j | anynines
Cloud Infrastructures Slide Set 7 - Docker - Neo4j | anyninesCloud Infrastructures Slide Set 7 - Docker - Neo4j | anynines
Cloud Infrastructures Slide Set 7 - Docker - Neo4j | anynines
 
Introduction To Design Patterns Class 4 Composition vs Inheritance
 Introduction To Design Patterns Class 4 Composition vs Inheritance Introduction To Design Patterns Class 4 Composition vs Inheritance
Introduction To Design Patterns Class 4 Composition vs Inheritance
 
D7 as D8
D7 as D8D7 as D8
D7 as D8
 
Scriptable Objects in Unity Game Engine (C#)
Scriptable Objects in Unity Game Engine (C#)Scriptable Objects in Unity Game Engine (C#)
Scriptable Objects in Unity Game Engine (C#)
 

Dernier

Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Miguel Araújo
 
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Igalia
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsMaria Levchenko
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreternaman860154
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationRadu Cotescu
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024Rafal Los
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerThousandEyes
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsEnterprise Knowledge
 
How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonetsnaman860154
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘RTylerCroy
 
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...HostedbyConfluent
 
Enhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for PartnersEnhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for PartnersThousandEyes
 
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024BookNet Canada
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking MenDelhi Call girls
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityPrincipled Technologies
 
Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101Paola De la Torre
 
Slack Application Development 101 Slides
Slack Application Development 101 SlidesSlack Application Development 101 Slides
Slack Application Development 101 Slidespraypatel2
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)Gabriella Davis
 
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024BookNet Canada
 
Google AI Hackathon: LLM based Evaluator for RAG
Google AI Hackathon: LLM based Evaluator for RAGGoogle AI Hackathon: LLM based Evaluator for RAG
Google AI Hackathon: LLM based Evaluator for RAGSujit Pal
 

Dernier (20)

Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
 
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed texts
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreter
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organization
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI Solutions
 
How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonets
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘
 
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...
 
Enhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for PartnersEnhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for Partners
 
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivity
 
Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101
 
Slack Application Development 101 Slides
Slack Application Development 101 SlidesSlack Application Development 101 Slides
Slack Application Development 101 Slides
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)
 
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
 
Google AI Hackathon: LLM based Evaluator for RAG
Google AI Hackathon: LLM based Evaluator for RAGGoogle AI Hackathon: LLM based Evaluator for RAG
Google AI Hackathon: LLM based Evaluator for RAG
 

Drupalcon cph

  • 1. D7 Entites/Fields Cyberswat - Kevin Bridges 24. aug 10:00 Trellon Room
  • 2. This is Code Heavy
  • 3. This is Code Heavy • We will be discussing code
  • 4. This is Code Heavy • We will be discussing code • If you are not a coder this will probably be incredibly boring to you
  • 5. This is Code Heavy • We will be discussing code • If you are not a coder this will probably be incredibly boring to you • We are not responsible for what may happen to you if you fall asleep.
  • 7. The Next Hour • Lots of content and fast talking. Save questions until the end
  • 8. The Next Hour • Lots of content and fast talking. Save questions until the end • Discuss key concepts in Drupal 7: Bundles, Entities and Fields
  • 9. The Next Hour • Lots of content and fast talking. Save questions until the end • Discuss key concepts in Drupal 7: Bundles, Entities and Fields • Walk through the creation of a content type that will add a Bundle of Fields complete with custom Formatters to the node Entity
  • 10. The Next Hour • Lots of content and fast talking. Save questions until the end • Discuss key concepts in Drupal 7: Bundles, Entities and Fields • Walk through the creation of a content type that will add a Bundle of Fields complete with custom Formatters to the node Entity • Explain WTH that last comment meant
  • 11. The Next Hour • Lots of content and fast talking. Save questions until the end • Discuss key concepts in Drupal 7: Bundles, Entities and Fields • Walk through the creation of a content type that will add a Bundle of Fields complete with custom Formatters to the node Entity • Explain WTH that last comment meant • Introduce the most excellent node_example module
  • 12. Key Concept Entity
  • 13. Key Concept Entity • An Entity is a container for Bundles.
  • 14. Key Concept Entity • An Entity is a container for Bundles. • Entities can contain multiple Bundles.
  • 15. Key Concept Entity • An Entity is a container for Bundles. • Entities can contain multiple Bundles. • Examples are Node, User, File, Taxonomy Term, Taxonomy Vocabulary
  • 16. Key Concept Entity • An Entity is a container for Bundles. • Entities can contain multiple Bundles. • Examples are Node, User, File, Taxonomy Term, Taxonomy Vocabulary • Why not make everything an Entity?
  • 17. Key Concept Bundles
  • 18. Key Concept Bundles • A Bundle is a set of fields that are treated as a group by the Field API
  • 19. Key Concept Bundles • A Bundle is a set of fields that are treated as a group by the Field API • Bundles are similar in concept to a node type in Drupal 6
  • 20. Key Concept Fields
  • 21. Key Concept Fields • A field defines a particular type of data that can be attached to any entity and can be shared between entities
  • 22. Key Concept Fields • A field defines a particular type of data that can be attached to any entity and can be shared between entities • A field can have Widgets. A widget is the UI element that allows a user to enter data into the field
  • 23. Key Concept Fields • A field defines a particular type of data that can be attached to any entity and can be shared between entities • A field can have Widgets. A widget is the UI element that allows a user to enter data into the field • A field can have Formatters. A formatter defines how a fields data gets displayed in a view mode
  • 25. The Examples Module • In my mind, the best resource for learning is the Examples Modue
  • 26. The Examples Module • In my mind, the best resource for learning is the Examples Modue • This module used to live exclusively in CVS but is now maintained by rfay, Dave Reid, katbailey and ilo in contrib
  • 27. The Examples Module • In my mind, the best resource for learning is the Examples Modue • This module used to live exclusively in CVS but is now maintained by rfay, Dave Reid, katbailey and ilo in contrib • Documentation can be viewed from api.drupal.org by following the Examples link
  • 28. The Examples Module • In my mind, the best resource for learning is the Examples Modue • This module used to live exclusively in CVS but is now maintained by rfay, Dave Reid, katbailey and ilo in contrib • Documentation can be viewed from api.drupal.org by following the Examples link • drupal.org/project/examples - not just the node module
  • 32. D7 *.install • We still implement hook_install() and hook_uninstall()
  • 33. D7 *.install • We still implement hook_install() and hook_uninstall() • hook_schema() no longer needs to be explicitly called
  • 34. D7 *.install • We still implement hook_install() and hook_uninstall() • hook_schema() no longer needs to be explicitly called • Database structure will resemble D6 CCK tables
  • 35. D7 *.install • We still implement hook_install() and hook_uninstall() • hook_schema() no longer needs to be explicitly called • Database structure will resemble D6 CCK tables • Database Entity revisions are provided automatically
  • 36.
  • 37. /** * Implements hook_install(). * */ function node_example_install() { ... }
  • 38. /** * Implements hook_install(). * */ function node_example_install() { ... } /** * Return a structured array defining the fields created by this content type. * * This is packaged in a function so it can be used in both hook_install() * and hook_uninstall(). */ function _node_example_installed_fields() { ... }
  • 39. /** * Implements hook_install(). * */ function node_example_install() { ... } /** * Return a structured array defining the fields created by this content type. * * This is packaged in a function so it can be used in both hook_install() * and hook_uninstall(). */ function _node_example_installed_fields() { ... } /** * Return a structured array defining the instances for this content type. * * The instance lets Drupal know which widget to use to allow the user to enter * data and how to react in different view modes. * This is provided as a function so that it can be used in both hook_install() * and hook_uninstall(). */ function _node_example_installed_instances() { ... }
  • 40. /** * Implements hook_install(). * */ function node_example_install() { ... } /** * Return a structured array defining the fields created by this content type. * * This is packaged in a function so it can be used in both hook_install() * and hook_uninstall(). */ function _node_example_installed_fields() { ... } /** * Return a structured array defining the instances for this content type. * * The instance lets Drupal know which widget to use to allow the user to enter * data and how to react in different view modes. * This is provided as a function so that it can be used in both hook_install() * and hook_uninstall(). */ function _node_example_installed_instances() { ... } /** * Implements hook_uninstall(). * */ function node_example_uninstall() { ... }
  • 42. D7 *.install • hook_install() will set up our content type
  • 43. D7 *.install • hook_install() will set up our content type • hook_install() is where we create our fields, if needed
  • 44. D7 *.install • hook_install() will set up our content type • hook_install() is where we create our fields, if needed • hook_install() is used to tie our fields to an Entity as a Bundle
  • 46. function node_example_install() { $types = node_type_get_types(); node_add_body_field($types['node_example']); }
  • 47. function node_example_install() { $types = node_type_get_types(); node_add_body_field($types['node_example']); // Load the instance definition for our content type's body // http://api.drupal.org/api/function/field_info_instance/7 $body_instance = field_info_instance('node', 'body', 'node_example'); }
  • 48. function node_example_install() { $types = node_type_get_types(); node_add_body_field($types['node_example']); // Load the instance definition for our content type's body // http://api.drupal.org/api/function/field_info_instance/7 $body_instance = field_info_instance('node', 'body', 'node_example'); // Add our example_node_list view mode to the body instance display by // instructing the body to display as a summary $body_instance['type'] = 'text_summary_or_trimmed'; }
  • 49. function node_example_install() { $types = node_type_get_types(); node_add_body_field($types['node_example']); // Load the instance definition for our content type's body // http://api.drupal.org/api/function/field_info_instance/7 $body_instance = field_info_instance('node', 'body', 'node_example'); // Add our example_node_list view mode to the body instance display by // instructing the body to display as a summary $body_instance['type'] = 'text_summary_or_trimmed'; // Save our changes to the body field instance. // http://api.drupal.org/api/function/field_update_instance/7 field_update_instance($body_instance); }
  • 50. function node_example_install() { $types = node_type_get_types(); node_add_body_field($types['node_example']); // Load the instance definition for our content type's body // http://api.drupal.org/api/function/field_info_instance/7 $body_instance = field_info_instance('node', 'body', 'node_example'); // Add our example_node_list view mode to the body instance display by // instructing the body to display as a summary $body_instance['type'] = 'text_summary_or_trimmed'; // Save our changes to the body field instance. // http://api.drupal.org/api/function/field_update_instance/7 field_update_instance($body_instance); // Create all the fields we are adding to our content type. // http://api.drupal.org/api/function/field_create_field/7 foreach (_node_example_installed_fields() as $field) { field_create_field($field); } }
  • 51. function node_example_install() { $types = node_type_get_types(); node_add_body_field($types['node_example']); // Load the instance definition for our content type's body // http://api.drupal.org/api/function/field_info_instance/7 $body_instance = field_info_instance('node', 'body', 'node_example'); // Add our example_node_list view mode to the body instance display by // instructing the body to display as a summary $body_instance['type'] = 'text_summary_or_trimmed'; // Save our changes to the body field instance. // http://api.drupal.org/api/function/field_update_instance/7 field_update_instance($body_instance); // Create all the fields we are adding to our content type. // http://api.drupal.org/api/function/field_create_field/7 foreach (_node_example_installed_fields() as $field) { field_create_field($field); } // Create all the instances for our fields. // http://api.drupal.org/api/function/field_create_instance/7 foreach (_node_example_installed_instances() as $instance) { $instance['entity_type'] = 'node'; $instance['bundle'] = 'node_example'; field_create_instance($instance); } }
  • 53. D7 *.install • The node_example module defines and invokes 3 distinct fields
  • 54. D7 *.install • The node_example module defines and invokes 3 distinct fields • We place these in a helper function so that it can be called as needed in functions like hook_install() and hook_uninstall()
  • 55. function _node_example_installed_fields() { $t = get_t(); return array( ); }
  • 56. function _node_example_installed_fields() { $t = get_t(); return array( 'node_example_color' => array( 'field_name' => 'node_example_color', 'label' => $t('The colors available for this object.'), 'cardinality' => 3, 'type' => 'text', 'settings' => array( 'max_length' => 60, ), ), ); }
  • 57. function _node_example_installed_fields() { $t = get_t(); return array( 'node_example_color' => array( 'field_name' => 'node_example_color', 'label' => $t('The colors available for this object.'), 'cardinality' => 3, 'type' => 'text', 'settings' => array( 'max_length' => 60, ), ), 'node_example_quantity' => array( 'field_name' => 'node_example_quantity', 'type' => 'text', ), ); }
  • 58. function _node_example_installed_fields() { $t = get_t(); return array( 'node_example_color' => array( 'field_name' => 'node_example_color', 'label' => $t('The colors available for this object.'), 'cardinality' => 3, 'type' => 'text', 'settings' => array( 'max_length' => 60, ), ), 'node_example_quantity' => array( 'field_name' => 'node_example_quantity', 'type' => 'text', ), 'node_example_image' => array( 'field_name' => 'node_example_image', 'type' => 'image', 'cardinality' => 1, ), ); }
  • 59. D7 *.install • This is the fun part ... we get to apply formatters to the instances to control their display and widgets to control the input
  • 60. $t = get_t(); return array( );
  • 61. $t = get_t(); return array( 'node_example_color' => array( 'field_name' => 'node_example_color', 'label' => $t('The colors available for this object.'), 'cardinality' => 3, 'widget' => array( 'type' => 'text_textfield', ), 'display' => array( 'example_node_list' => array( 'label' => 'hidden', 'type' => 'node_example_colors', ), ), ), );
  • 62. $t = get_t(); return array( 'node_example_color' => array( 'field_name' => 'node_example_color', 'label' => $t('The colors available for this object.'), 'cardinality' => 3, 'widget' => array( 'type' => 'text_textfield', ), 'display' => array( 'example_node_list' => array( 'label' => 'hidden', 'type' => 'node_example_colors', ), ), ), 'node_example_quantity' => array( 'field_name' => 'node_example_quantity', 'type' => 'text', 'widget' => array( 'type' => 'text_textfield', ), 'display' => array( 'example_node_list' => array( 'label' => 'hidden', 'type' => 'hidden', ), ), ), );
  • 63. $t = get_t(); return array( 'node_example_color' => array( 'field_name' => 'node_example_color', 'label' => $t('The colors available for this object.'), 'cardinality' => 3, 'widget' => array( 'type' => 'text_textfield', ), 'display' => array( 'example_node_list' => array( 'label' => 'hidden', 'type' => 'node_example_colors', ), ), ), 'node_example_quantity' => array( 'field_name' => 'node_example_quantity', 'type' => 'text', 'widget' => array( 'type' => 'text_textfield', ), 'display' => array( 'example_node_list' => array( 'label' => 'hidden', 'type' => 'hidden', ), ), ), 'node_example_image' => array( 'field_name' => 'node_example_image', 'label' => $t('Upload an image:'), 'required' => FALSE, 'widget' => array( 'type' => 'image_image', 'weight' => 2.10, ), 'display' => array( 'example_node_list' => array( 'label' => 'hidden', 'type' => 'image_link_content__thumbnail', ), ), ), );
  • 65. D7 *.install • hook_uninstall() is used to clean up the data created with the node_example module
  • 66. D7 *.install • hook_uninstall() is used to clean up the data created with the node_example module • hook_uninstall() deletes our fields and their instances
  • 67. D7 *.install • hook_uninstall() is used to clean up the data created with the node_example module • hook_uninstall() deletes our fields and their instances • hook_uninstall() deletes our content type
  • 68. D7 *.install • hook_uninstall() is used to clean up the data created with the node_example module • hook_uninstall() deletes our fields and their instances • hook_uninstall() deletes our content type • hook_uninstall purges field data from the system
  • 70. function node_example_uninstall() { // Gather all the example content that might have been created while this // module was enabled. Simple selects still use db_query(). // http://api.drupal.org/api/function/db_query/7 $sql = 'SELECT nid FROM {node} n WHERE n.type = :type'; $result = db_query($sql, array(':type' => 'node_example')); $nids = array(); foreach ($result as $row) { $nids[] = $row->nid; } }
  • 71. function node_example_uninstall() { // Gather all the example content that might have been created while this // module was enabled. Simple selects still use db_query(). // http://api.drupal.org/api/function/db_query/7 $sql = 'SELECT nid FROM {node} n WHERE n.type = :type'; $result = db_query($sql, array(':type' => 'node_example')); $nids = array(); foreach ($result as $row) { $nids[] = $row->nid; } // Delete all the nodes at once // http://api.drupal.org/api/function/node_delete_multiple/7 node_delete_multiple($nids); }
  • 72. function node_example_uninstall() { // Gather all the example content that might have been created while this // module was enabled. Simple selects still use db_query(). // http://api.drupal.org/api/function/db_query/7 $sql = 'SELECT nid FROM {node} n WHERE n.type = :type'; $result = db_query($sql, array(':type' => 'node_example')); $nids = array(); foreach ($result as $row) { $nids[] = $row->nid; } // Delete all the nodes at once // http://api.drupal.org/api/function/node_delete_multiple/7 node_delete_multiple($nids); // Loop over each of the fields defined by this module and delete // all instances of the field, their data, and the field itself. // http://api.drupal.org/api/function/field_delete_field/7 foreach (array_keys(_node_example_installed_fields()) as $field) { field_delete_field($field); } }
  • 73. function node_example_uninstall() { // Gather all the example content that might have been created while this // module was enabled. Simple selects still use db_query(). // http://api.drupal.org/api/function/db_query/7 $sql = 'SELECT nid FROM {node} n WHERE n.type = :type'; $result = db_query($sql, array(':type' => 'node_example')); $nids = array(); foreach ($result as $row) { $nids[] = $row->nid; } // Delete all the nodes at once // http://api.drupal.org/api/function/node_delete_multiple/7 node_delete_multiple($nids); // Loop over each of the fields defined by this module and delete // all instances of the field, their data, and the field itself. // http://api.drupal.org/api/function/field_delete_field/7 foreach (array_keys(_node_example_installed_fields()) as $field) { field_delete_field($field); } // Loop over any remaining field instances attached to the node_example // content type (such as the body field) and delete them individually. // http://api.drupal.org/api/function/field_delete_field/7 $instances = field_info_instances('node', 'node_example'); foreach ($instances as $instance_name => $instance) { field_delete_instance($instance); } }
  • 74. function node_example_uninstall() { // Gather all the example content that might have been created while this // module was enabled. Simple selects still use db_query(). // http://api.drupal.org/api/function/db_query/7 $sql = 'SELECT nid FROM {node} n WHERE n.type = :type'; $result = db_query($sql, array(':type' => 'node_example')); $nids = array(); foreach ($result as $row) { $nids[] = $row->nid; } // Delete all the nodes at once // http://api.drupal.org/api/function/node_delete_multiple/7 node_delete_multiple($nids); // Loop over each of the fields defined by this module and delete // all instances of the field, their data, and the field itself. // http://api.drupal.org/api/function/field_delete_field/7 foreach (array_keys(_node_example_installed_fields()) as $field) { field_delete_field($field); } // Loop over any remaining field instances attached to the node_example // content type (such as the body field) and delete them individually. // http://api.drupal.org/api/function/field_delete_field/7 $instances = field_info_instances('node', 'node_example'); foreach ($instances as $instance_name => $instance) { field_delete_instance($instance); } // Delete our content type // http://api.drupal.org/api/function/node_type_delete/7 node_type_delete('node_example'); }
  • 75. function node_example_uninstall() { // Gather all the example content that might have been created while this // module was enabled. Simple selects still use db_query(). // http://api.drupal.org/api/function/db_query/7 $sql = 'SELECT nid FROM {node} n WHERE n.type = :type'; $result = db_query($sql, array(':type' => 'node_example')); $nids = array(); foreach ($result as $row) { $nids[] = $row->nid; } // Delete all the nodes at once // http://api.drupal.org/api/function/node_delete_multiple/7 node_delete_multiple($nids); // Loop over each of the fields defined by this module and delete // all instances of the field, their data, and the field itself. // http://api.drupal.org/api/function/field_delete_field/7 foreach (array_keys(_node_example_installed_fields()) as $field) { field_delete_field($field); } // Loop over any remaining field instances attached to the node_example // content type (such as the body field) and delete them individually. // http://api.drupal.org/api/function/field_delete_field/7 $instances = field_info_instances('node', 'node_example'); foreach ($instances as $instance_name => $instance) { field_delete_instance($instance); } // Delete our content type // http://api.drupal.org/api/function/node_type_delete/7 node_type_delete('node_example'); // Purge all field information // http://api.drupal.org/api/function/field_purge_batch/7 field_purge_batch(1000); }
  • 77. D7 *.module • Finally on to the module file!
  • 78. D7 *.module • Finally on to the module file! • Let’s start with the hooks we will recognize from D6
  • 79. D7 *.module • Finally on to the module file! • Let’s start with the hooks we will recognize from D6 • hook_node_info() informs Drupal about our content type
  • 80. D7 *.module • Finally on to the module file! • Let’s start with the hooks we will recognize from D6 • hook_node_info() informs Drupal about our content type • hook_menu() tells Drupal where our custom page is going to live and how to build it
  • 81. D7 *.module • Finally on to the module file! • Let’s start with the hooks we will recognize from D6 • hook_node_info() informs Drupal about our content type • hook_menu() tells Drupal where our custom page is going to live and how to build it • hook_help() provides help information for our users
  • 82.
  • 83. /** * Implements hook_node_info() to provide our node_example type. */ function node_example_node_info() { return array( 'node_example' => array( 'name' => t('Example Node'), 'base' => 'node_example', 'description' => t('This is an example node type with a few fields.'), 'has_title' => TRUE, ), ); }
  • 84. /** * Implements hook_node_info() to provide our node_example type. */ function node_example_node_info() { return array( 'node_example' => array( 'name' => t('Example Node'), 'base' => 'node_example', 'description' => t('This is an example node type with a few fields.'), 'has_title' => TRUE, ), ); } /** * Implements hook_menu(). * * We are providing a default page to illustrate the use of our custom node view * mode that will live at http://example.com/?q=examples/node_example */ function node_example_menu() { $items['examples/node_example'] = array( 'page callback' => 'node_example_page', 'access arguments' => array('access content'), 'title' => 'Node Example', ); return $items; }
  • 85. /** * Implements hook_node_info() to provide our node_example type. */ function node_example_node_info() { return array( 'node_example' => array( 'name' => t('Example Node'), 'base' => 'node_example', 'description' => t('This is an example node type with a few fields.'), 'has_title' => TRUE, ), ); } /** * Implements hook_menu(). * * We are providing a default page to illustrate the use of our custom node view * mode that will live at http://example.com/?q=examples/node_example */ function node_example_menu() { $items['examples/node_example'] = array( 'page callback' => 'node_example_page', 'access arguments' => array('access content'), 'title' => 'Node Example', ); return $items; } /** * Implements hook_help(). */ function node_example_help($path, $arg) { switch ($path) { case 'examples/node_example': return "<p>" . t( "The Node Example module provides a custom node type. You can create new nodes using the <a href='!nodeadd'>node add form</a>. Nodes that you create will be displayed here.", array('!nodeadd' => url('node/add/node-example')) ) . "</p>"; } }
  • 87. d7 *.module • hook_form() is used to create the basic content form
  • 88. d7 *.module • hook_form() is used to create the basic content form • hook_theme() informs Drupal of our theme callbacks
  • 89.
  • 90. /** * Implement hook_form() with the standard default form. */ function node_example_form($node, $form_state) { return node_content_form($node, $form_state); }
  • 91. /** * Implement hook_form() with the standard default form. */ function node_example_form($node, $form_state) { return node_content_form($node, $form_state); } /** * Implements hook_theme(). * * This lets us tell Drupal about our theme functions and their arguments. */ function node_example_theme($existing, $type, $theme, $path) { return array( 'example_node_color' => array( 'variables' => array('color' => NULL), ), ); }
  • 92. /** * Implement hook_form() with the standard default form. */ function node_example_form($node, $form_state) { return node_content_form($node, $form_state); } /** * Implements hook_theme(). * * This lets us tell Drupal about our theme functions and their arguments. */ function node_example_theme($existing, $type, $theme, $path) { return array( 'example_node_color' => array( 'variables' => array('color' => NULL), ), ); } /** * A custom theme function. * * By using this function to format our node-specific information, themes * can override this presentation if they wish. This is a simplified theme * function purely for illustrative purposes. */ function theme_example_node_color($variables) { $output = '<span style="background-color: #ccc; padding: 1em; margin-bottom: 1em; float: left; color: ' . $variables['color'] . '">' . $variables['color'] . '</span>'; return $output; }
  • 94. D7 *.module • Now for the juicy D7 changes!!!
  • 95. D7 *.module • Now for the juicy D7 changes!!! • hook_entity_info_alter() lets us modify the node_entity to use our custom view mode
  • 96. D7 *.module • Now for the juicy D7 changes!!! • hook_entity_info_alter() lets us modify the node_entity to use our custom view mode • hook_field_formatter_view() is where we place the details of our custom view mode
  • 97.
  • 98. /** * Implements hook_entity_info_alter(). * * We need to modify the default node entity info by adding a new view mode to * be used in functions like node_view() or node_build_content(). * */ function node_example_entity_info_alter(&$entity_info) { $entity_info['node']['view modes']['example_node_list'] = array( 'label' => t('Example Node List'), 'custom settings' => TRUE, ); }
  • 99. /** * Implements hook_entity_info_alter(). * * We need to modify the default node entity info by adding a new view mode to * be used in functions like node_view() or node_build_content(). * */ function node_example_entity_info_alter(&$entity_info) { $entity_info['node']['view modes']['example_node_list'] = array( 'label' => t('Example Node List'), 'custom settings' => TRUE, ); } /** * Implements hook_field_formatter_info(). */ function node_example_field_formatter_info() { return array( 'node_example_colors' => array( 'label' => t('Node Example Color Handle'), 'field types' => array('text'), ), ); }
  • 101. D7 *.module • Last ... but certainly not least
  • 102. D7 *.module • Last ... but certainly not least • hook_field_formatter_view() is where we place the details of our custom view mode
  • 103.
  • 104. /** * Implements hook_field_formatter_view(). * * @todo: We need to provide a formatter for the colors that a user is allowed to enter * during node creation. */ function node_example_field_formatter_view($object_type, $object, $field, $instance, $langcode, $items, $display) { $element = array(); switch ($display['type']) { case 'node_example_colors': foreach ($items as $delta => $item) { $element[$delta]['#type'] = 'markup'; $color = $item['safe_value']; $element[$delta]['#markup'] = theme('example_node_color', array('color' => $color)); } break; } return $element; }
  • 105. Informative Links • The field API Tutorial - http://drupal.org/node/707832 • The Field API Glossary - http://drupal.org/node/443540 • Adding and Reusing a Field - http://drupal.org/node/ 474420 • Making an Entity Fieldable - http://drupal.org/node/ 474582 • The Examples Module - http://drupal.org/project/ examples • Drupal API - http://api.drupal.org/ • Joachim’s http://drupal.org/project/field_convert

Notes de l'éditeur