SlideShare a Scribd company logo
Drupal 7 Entities and Fields
        Kevin Bridges (cyberswat)
D7 Code Sprint
D7 Code Sprint


• We will be discussing code
D7 Code Sprint


• We will be discussing code
• If you are not a coder this
  will probably be incredibly
  boring to you and you risk
  being put to sleep :-D
D7 Code Sprint


• We will be discussing code
• If you are not a coder this
  will probably be incredibly
  boring to you and you risk
  being put to sleep :-D
D7 Code Sprint
D7 Code Sprint




555 17th Street, Downtown Denver - Monday10:00am MST
D7 Code Sprint




555 17th Street, Downtown Denver - Monday10:00am MST
           Matthew Saunders - 720.254.1546
The Next Hour
The Next Hour

• Discuss key concepts in Drupal 7: Bundles,
  Entities and Fields
The Next Hour

• 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

• 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

• 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 Concepts
Key Concepts
• An Entity is a container for Bundles.
  Examples are Node, User, File, Taxonomy
  Term, Taxonomy Vocabulary
Key Concepts
• An Entity is a container for Bundles.
  Examples are Node, User, File, Taxonomy
  Term, Taxonomy Vocabulary
• A Bundle is a set of fields that are treated as
  a group by the Field API. This is similar to
  the concept of a node type in D6
Key Concepts
• An Entity is a container for Bundles.
  Examples are Node, User, File, Taxonomy
  Term, Taxonomy Vocabulary
• A Bundle is a set of fields that are treated as
  a group by the Field API. This is similar to
  the concept of a node type in D6
• Entities can contain multiple Bundles.
Key Concepts
• An Entity is a container for Bundles.
  Examples are Node, User, File, Taxonomy
  Term, Taxonomy Vocabulary
• A Bundle is a set of fields that are treated as
  a group by the Field API. This is similar to
  the concept of a node type in D6
• Entities can contain multiple Bundles.
• A field defines a particular type of data that
  can be attached to any entity and can be
  shared between entities
Key Concepts
• An Entity is a container for Bundles.
  Examples are Node, User, File, Taxonomy
  Term, Taxonomy Vocabulary
• A Bundle is a set of fields that are treated as
  a group by the Field API. This is similar to
  the concept of a node type in D6
• Entities can contain multiple Bundles.
• 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 and formatters
The Examples Module
The Examples Module
• In my mind the best resource for learning is
  The Examples Module.
The Examples Module
• In my mind the best resource for learning is
  The Examples Module.
• This module used to live exclusively in CVS
The Examples Module
• In my mind the best resource for learning is
  The Examples Module.
• This module used to live exclusively in CVS
• Now maintained by rfay, Dave Reid, katbailey
  and ilo ... node_example is a sub-module the
  Examples project
The Examples Module
• In my mind the best resource for learning is
  The Examples Module.
• This module used to live exclusively in CVS
• Now maintained by rfay, Dave Reid, katbailey
  and ilo ... node_example is a sub-module the
  Examples project
• Documentation can be viewed from http://
  api.drupal.org/ by following the Examples link
The Examples Module
• In my mind the best resource for learning is
  The Examples Module.
• This module used to live exclusively in CVS
• Now maintained by rfay, Dave Reid, katbailey
  and ilo ... node_example is a sub-module the
  Examples project
• Documentation can be viewed from http://
  api.drupal.org/ by following the Examples link
• http://drupal.org/project/examples - not just
  the node module
The Examples Module
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
D7 *.install
/**
 * Implements hook_install().
 *
 */
function node_example_install() {
 ...
}
D7 *.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() {
 ...
}
D7 *.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() {
 ...
}
/**
 * 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() {
 ...
}
D7 *.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() {
 ...
}
/**
 * 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
D7 *.install
function node_example_install() {




}
D7 *.install
function node_example_install() {

    $types = node_type_get_types();
    node_add_body_field($types['node_example']);




}
D7 *.install
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');




}
D7 *.install
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';




}
D7 *.install
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);




}
D7 *.install
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);
    }




}
D7 *.install
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 uses 3 distinct
  fields
D7 *.install


• The node_example module uses 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()
D7 *.install


• The node_example module uses 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()
• Make sure to see chx’s presentation on Field
  API at 2:15pm in the Aten Design Group
  room
D7 *.install
function _node_example_installed_fields() {
 $t = get_t();
 return array(




    );
}
D7 *.install
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,
       ),
     ),




    );
}
D7 *.install
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',
  ),




    );
}
D7 *.install
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
D7 *.install


• The node_example module uses it’s 3
  defined field as 3 field instances
D7 *.install


• The node_example module uses it’s 3
  defined field as 3 field instances
• We place these in a helper function so that it
  can be called as needed in functions like
  hook_install() and hook_uninstall()
D7 *.install


• The node_example module uses it’s 3
  defined field as 3 field instances
• We place these in a helper function so that it
  can be called as needed in functions like
  hook_install() and hook_uninstall()
• This is the fun part ... we get to apply
  formatters to the instances to control their
  display
function _node_example_installed_instances() {
                                                 D7 *.install
 $t = get_t();
 return array(
function _node_example_installed_instances() {
                                                                   D7 *.install
 $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',
      ),
    ),
  ),
function _node_example_installed_instances() {
                                                                   D7 *.install
 $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',
      ),
    ),
  ),
function _node_example_installed_instances() {
                                                                   D7 *.install
 $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
D7 *.install
function node_example_uninstall() {




}
D7 *.install
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;
    }




}
D7 *.install
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);




}
D7 *.install
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);
    }




}
D7 *.install
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);
    }




}
D7 *.install
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');




}
D7 *.install
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
  users
D7 *.module
/**
 * 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,
    ),
  );
}
D7 *.module
/**
 * 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;
}
D7 *.module
 /**
  * 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
D7 *.module
/**
 * Implement hook_form() with the standard default form.
 */
function node_example_form($node, $form_state) {
  return node_content_form($node, $form_state);
}
D7 *.module
/**
 * 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),
    ),
  );
}
D7 *.module
/**
 * 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
D7 *.module
/**
 * 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,
  );
}
D7 *.module
  /**
   * 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
D7 *.module
/**
 * 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
Informative Links
• The Field API Tutorial - http://drupal.org/
  node/707832
Informative Links
• The Field API Tutorial - http://drupal.org/
  node/707832
• The Field API Glossary - http://drupal.org/
  node/443540
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
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
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
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/
Share Your Drupal
Share Your Drupal

Examiner.com is moving to Drupal 7 and has been heavily contributing to the Drupal project.

The site is looking for Examiners in the community to write about Drupal - the business of
Drupal, events, interesting tidbits on Theming and Development, and so forth.

It is more than OK to cross post (you retain copyright to the content but do grant
Examiner.com a license to use that content) from your own blog if you already have a home
you write from and, best of all, you get paid for page views.

It is a great way to promote Drupal, increase your own visibility, and/or build your local
Drupal community. If you're interested, contact Stacey at sharrison@examiner.com. Or speak
with us during this Drupalcamp.

More Related Content

KEY
Drupalcon cph
PPT
Synapseindia object oriented programming in php
PPT
Advanced php
PDF
Drupal 8: Theming
KEY
Xtext Eclipse Con
PPTX
Drupal Camp Porto - Developing with Drupal: First Steps
PDF
Intermediate OOP in PHP
PPTX
Real World MVC
Drupalcon cph
Synapseindia object oriented programming in php
Advanced php
Drupal 8: Theming
Xtext Eclipse Con
Drupal Camp Porto - Developing with Drupal: First Steps
Intermediate OOP in PHP
Real World MVC

What's hot (20)

PDF
Using Xcore with Xtext
PPTX
Extending WordPress. Making use of Custom Post Types
PPTX
Oops in php
KEY
Building a Pluggable Plugin
PDF
iPhone Memory Management
PPT
Oops in PHP
PDF
Designing a JavaFX Mobile application
PPTX
Ch8(oop)
PPTX
Oop's in php
PPTX
Omnisearch in AEM 6.2 - Search All the Things
PPTX
One-hour Drupal 8 Theming
PPT
Stoop 301-internal objectstructureinvw
PDF
Moose workshop
PDF
The Naked Bundle - Symfony Barcelona
PDF
Introduction to Moose
KEY
Introduction To Moose
PDF
Puppet Camp Portland 2015: Introduction to Hiera (Beginner)
PDF
Getting Hiera and Hiera
PDF
Multithreading and Parallelism on iOS [MobOS 2013]
PDF
The Naked Bundle - Symfony Usergroup Belgium
Using Xcore with Xtext
Extending WordPress. Making use of Custom Post Types
Oops in php
Building a Pluggable Plugin
iPhone Memory Management
Oops in PHP
Designing a JavaFX Mobile application
Ch8(oop)
Oop's in php
Omnisearch in AEM 6.2 - Search All the Things
One-hour Drupal 8 Theming
Stoop 301-internal objectstructureinvw
Moose workshop
The Naked Bundle - Symfony Barcelona
Introduction to Moose
Introduction To Moose
Puppet Camp Portland 2015: Introduction to Hiera (Beginner)
Getting Hiera and Hiera
Multithreading and Parallelism on iOS [MobOS 2013]
The Naked Bundle - Symfony Usergroup Belgium
Ad

Viewers also liked (20)

PDF
Best economy
PDF
Guru poornimasandesh
PPTX
Eco 2601 终极版
PPTX
Erasmus plus in Tahiti
PPTX
Martien plasmeijer
PPT
计算机媒介学习
PDF
Bal sanskar
PDF
GDC Fall 2010 Interns
PPTX
Weekly news
PDF
Satsang suman
PDF
Sadgunon kikhanhanumanji
PPT
Blogging For Education
PDF
Sada diwalien
PPTX
PPT
Purchase food by phone
PPTX
Edtech survey fan
PPT
Viatge de fi d’estudis 2013
DOC
Xarxes Socials
PDF
Vedantic fearlessness
PDF
心靈雞湯全集英漢對照
Best economy
Guru poornimasandesh
Eco 2601 终极版
Erasmus plus in Tahiti
Martien plasmeijer
计算机媒介学习
Bal sanskar
GDC Fall 2010 Interns
Weekly news
Satsang suman
Sadgunon kikhanhanumanji
Blogging For Education
Sada diwalien
Purchase food by phone
Edtech survey fan
Viatge de fi d’estudis 2013
Xarxes Socials
Vedantic fearlessness
心靈雞湯全集英漢對照
Ad

Similar to D7 entities fields (20)

PDF
Decoupled Libraries for PHP
KEY
modern module development - Ken Barber 2012 Edinburgh Puppet Camp
PPTX
Drupal 7 entities & TextbookMadness.com
PPTX
Top 8 Improvements in Drupal 8
PDF
Web automation with #d8rules (European Drupal Days 2015)
KEY
Open Atrium (DrupalCon Paris 2009, Day 3)
PDF
iOS & Drupal
PDF
Flcamp2015 - R.E.A.D: Four steps for selecting the right modules
PDF
Building a Custom Theme in Drupal 8
PDF
The Naked Bundle - Symfony Live London 2014
PPTX
1. react - native: setup
KEY
Modules Building Presentation
ZIP
Building a Drupal Distribution using Features, Drush Make, Installation Profi...
PDF
Multilingualism makes better programmers
PDF
Drupal 8: Fields reborn
PDF
Migrate to Drupal 8
PPTX
Ready. Set. Drupal! An Intro to Drupal 8, Part 2
PDF
OOPs Interview Questions PDF By ScholarHat
PDF
Migrating to Drupal 8
Decoupled Libraries for PHP
modern module development - Ken Barber 2012 Edinburgh Puppet Camp
Drupal 7 entities & TextbookMadness.com
Top 8 Improvements in Drupal 8
Web automation with #d8rules (European Drupal Days 2015)
Open Atrium (DrupalCon Paris 2009, Day 3)
iOS & Drupal
Flcamp2015 - R.E.A.D: Four steps for selecting the right modules
Building a Custom Theme in Drupal 8
The Naked Bundle - Symfony Live London 2014
1. react - native: setup
Modules Building Presentation
Building a Drupal Distribution using Features, Drush Make, Installation Profi...
Multilingualism makes better programmers
Drupal 8: Fields reborn
Migrate to Drupal 8
Ready. Set. Drupal! An Intro to Drupal 8, Part 2
OOPs Interview Questions PDF By ScholarHat
Migrating to Drupal 8

Recently uploaded (20)

PPTX
Cloud computing and distributed systems.
PPTX
Detection-First SIEM: Rule Types, Dashboards, and Threat-Informed Strategy
PPTX
20250228 LYD VKU AI Blended-Learning.pptx
PPTX
VMware vSphere Foundation How to Sell Presentation-Ver1.4-2-14-2024.pptx
PDF
Machine learning based COVID-19 study performance prediction
PDF
cuic standard and advanced reporting.pdf
PPTX
KOM of Painting work and Equipment Insulation REV00 update 25-dec.pptx
PDF
Dropbox Q2 2025 Financial Results & Investor Presentation
PDF
Profit Center Accounting in SAP S/4HANA, S4F28 Col11
PPTX
Programs and apps: productivity, graphics, security and other tools
PDF
Reach Out and Touch Someone: Haptics and Empathic Computing
PDF
Encapsulation theory and applications.pdf
PDF
NewMind AI Weekly Chronicles - August'25 Week I
PDF
Unlocking AI with Model Context Protocol (MCP)
PPTX
MYSQL Presentation for SQL database connectivity
PDF
Optimiser vos workloads AI/ML sur Amazon EC2 et AWS Graviton
PDF
Build a system with the filesystem maintained by OSTree @ COSCUP 2025
PDF
KodekX | Application Modernization Development
PDF
Peak of Data & AI Encore- AI for Metadata and Smarter Workflows
PDF
How UI/UX Design Impacts User Retention in Mobile Apps.pdf
Cloud computing and distributed systems.
Detection-First SIEM: Rule Types, Dashboards, and Threat-Informed Strategy
20250228 LYD VKU AI Blended-Learning.pptx
VMware vSphere Foundation How to Sell Presentation-Ver1.4-2-14-2024.pptx
Machine learning based COVID-19 study performance prediction
cuic standard and advanced reporting.pdf
KOM of Painting work and Equipment Insulation REV00 update 25-dec.pptx
Dropbox Q2 2025 Financial Results & Investor Presentation
Profit Center Accounting in SAP S/4HANA, S4F28 Col11
Programs and apps: productivity, graphics, security and other tools
Reach Out and Touch Someone: Haptics and Empathic Computing
Encapsulation theory and applications.pdf
NewMind AI Weekly Chronicles - August'25 Week I
Unlocking AI with Model Context Protocol (MCP)
MYSQL Presentation for SQL database connectivity
Optimiser vos workloads AI/ML sur Amazon EC2 et AWS Graviton
Build a system with the filesystem maintained by OSTree @ COSCUP 2025
KodekX | Application Modernization Development
Peak of Data & AI Encore- AI for Metadata and Smarter Workflows
How UI/UX Design Impacts User Retention in Mobile Apps.pdf

D7 entities fields

  • 1. Drupal 7 Entities and Fields Kevin Bridges (cyberswat)
  • 3. D7 Code Sprint • We will be discussing code
  • 4. D7 Code Sprint • We will be discussing code • If you are not a coder this will probably be incredibly boring to you and you risk being put to sleep :-D
  • 5. D7 Code Sprint • We will be discussing code • If you are not a coder this will probably be incredibly boring to you and you risk being put to sleep :-D
  • 7. D7 Code Sprint 555 17th Street, Downtown Denver - Monday10:00am MST
  • 8. D7 Code Sprint 555 17th Street, Downtown Denver - Monday10:00am MST Matthew Saunders - 720.254.1546
  • 10. The Next Hour • Discuss key concepts in Drupal 7: Bundles, Entities and Fields
  • 11. The Next Hour • 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
  • 12. The Next Hour • 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
  • 13. The Next Hour • 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
  • 15. Key Concepts • An Entity is a container for Bundles. Examples are Node, User, File, Taxonomy Term, Taxonomy Vocabulary
  • 16. Key Concepts • An Entity is a container for Bundles. Examples are Node, User, File, Taxonomy Term, Taxonomy Vocabulary • A Bundle is a set of fields that are treated as a group by the Field API. This is similar to the concept of a node type in D6
  • 17. Key Concepts • An Entity is a container for Bundles. Examples are Node, User, File, Taxonomy Term, Taxonomy Vocabulary • A Bundle is a set of fields that are treated as a group by the Field API. This is similar to the concept of a node type in D6 • Entities can contain multiple Bundles.
  • 18. Key Concepts • An Entity is a container for Bundles. Examples are Node, User, File, Taxonomy Term, Taxonomy Vocabulary • A Bundle is a set of fields that are treated as a group by the Field API. This is similar to the concept of a node type in D6 • Entities can contain multiple Bundles. • A field defines a particular type of data that can be attached to any entity and can be shared between entities
  • 19. Key Concepts • An Entity is a container for Bundles. Examples are Node, User, File, Taxonomy Term, Taxonomy Vocabulary • A Bundle is a set of fields that are treated as a group by the Field API. This is similar to the concept of a node type in D6 • Entities can contain multiple Bundles. • 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 and formatters
  • 21. The Examples Module • In my mind the best resource for learning is The Examples Module.
  • 22. The Examples Module • In my mind the best resource for learning is The Examples Module. • This module used to live exclusively in CVS
  • 23. The Examples Module • In my mind the best resource for learning is The Examples Module. • This module used to live exclusively in CVS • Now maintained by rfay, Dave Reid, katbailey and ilo ... node_example is a sub-module the Examples project
  • 24. The Examples Module • In my mind the best resource for learning is The Examples Module. • This module used to live exclusively in CVS • Now maintained by rfay, Dave Reid, katbailey and ilo ... node_example is a sub-module the Examples project • Documentation can be viewed from http:// api.drupal.org/ by following the Examples link
  • 25. The Examples Module • In my mind the best resource for learning is The Examples Module. • This module used to live exclusively in CVS • Now maintained by rfay, Dave Reid, katbailey and ilo ... node_example is a sub-module the Examples project • Documentation can be viewed from http:// api.drupal.org/ by following the Examples link • http://drupal.org/project/examples - not just the node module
  • 28. D7 *.install • We still implement hook_install() and hook_uninstall()
  • 29. D7 *.install • We still implement hook_install() and hook_uninstall() • hook_schema() no longer needs to be explicitly called
  • 30. 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
  • 31. 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
  • 32. D7 *.install /** * Implements hook_install(). * */ function node_example_install() { ... }
  • 33. D7 *.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() { ... }
  • 34. D7 *.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() { ... } /** * 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() { ... }
  • 35. D7 *.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() { ... } /** * 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() { ... }
  • 37. D7 *.install • hook_install() will set up our content type
  • 38. D7 *.install • hook_install() will set up our content type • hook_install() is where we create our fields, if needed
  • 39. 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
  • 41. D7 *.install function node_example_install() { $types = node_type_get_types(); node_add_body_field($types['node_example']); }
  • 42. D7 *.install 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'); }
  • 43. D7 *.install 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'; }
  • 44. D7 *.install 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); }
  • 45. D7 *.install 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); } }
  • 46. D7 *.install 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); } }
  • 48. D7 *.install • The node_example module uses 3 distinct fields
  • 49. D7 *.install • The node_example module uses 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()
  • 50. D7 *.install • The node_example module uses 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() • Make sure to see chx’s presentation on Field API at 2:15pm in the Aten Design Group room
  • 51. D7 *.install function _node_example_installed_fields() { $t = get_t(); return array( ); }
  • 52. D7 *.install 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, ), ), ); }
  • 53. D7 *.install 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', ), ); }
  • 54. D7 *.install 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, ), ); }
  • 56. D7 *.install • The node_example module uses it’s 3 defined field as 3 field instances
  • 57. D7 *.install • The node_example module uses it’s 3 defined field as 3 field instances • We place these in a helper function so that it can be called as needed in functions like hook_install() and hook_uninstall()
  • 58. D7 *.install • The node_example module uses it’s 3 defined field as 3 field instances • We place these in a helper function so that it can be called as needed in functions like hook_install() and hook_uninstall() • This is the fun part ... we get to apply formatters to the instances to control their display
  • 59. function _node_example_installed_instances() { D7 *.install $t = get_t(); return array(
  • 60. function _node_example_installed_instances() { D7 *.install $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', ), ), ),
  • 61. function _node_example_installed_instances() { D7 *.install $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', ), ), ),
  • 62. function _node_example_installed_instances() { D7 *.install $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', ), ), ),
  • 64. D7 *.install • hook_uninstall() is used to clean up the data created with the node_example module
  • 65. 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
  • 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 • hook_uninstall() deletes our content type
  • 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 • hook_uninstall() purges field data from the system
  • 69. D7 *.install 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; } }
  • 70. D7 *.install 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); }
  • 71. D7 *.install 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); } }
  • 72. D7 *.install 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); } }
  • 73. D7 *.install 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'); }
  • 74. D7 *.install 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); }
  • 76. D7 *.module • Finally on to the module file
  • 77. D7 *.module • Finally on to the module file • Let’s start with the hooks we will recognize from D6
  • 78. 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
  • 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 • hook_menu() tells Drupal where our custom page is going to live and how to build it
  • 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 • hook_help() provides help information for users
  • 81. D7 *.module /** * 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, ), ); }
  • 82. D7 *.module /** * 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; }
  • 83. D7 *.module /** * 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>"; }
  • 85. D7 *.module • hook_form() is used to create the basic content form
  • 86. D7 *.module • hook_form() is used to create the basic content form • hook_theme() informs Drupal of our theme callbacks
  • 87. D7 *.module /** * Implement hook_form() with the standard default form. */ function node_example_form($node, $form_state) { return node_content_form($node, $form_state); }
  • 88. D7 *.module /** * 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), ), ); }
  • 89. D7 *.module /** * 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; }
  • 91. D7 *.module • Now for the juicy D7 changes!!!
  • 92. D7 *.module • Now for the juicy D7 changes!!! • hook_entity_info_alter() lets us modify the node_entity to use our custom view mode
  • 93. 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
  • 94. D7 *.module /** * 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, ); }
  • 95. D7 *.module /** * 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'), ), ); }
  • 97. D7 *.module • Last ... but certainly not least
  • 98. D7 *.module • Last ... but certainly not least • hook_field_formatter_view() is where we place the details of our custom view mode
  • 99. D7 *.module /** * 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; }
  • 101. Informative Links • The Field API Tutorial - http://drupal.org/ node/707832
  • 102. Informative Links • The Field API Tutorial - http://drupal.org/ node/707832 • The Field API Glossary - http://drupal.org/ node/443540
  • 103. 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
  • 104. 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
  • 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
  • 106. 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/
  • 108. Share Your Drupal Examiner.com is moving to Drupal 7 and has been heavily contributing to the Drupal project. The site is looking for Examiners in the community to write about Drupal - the business of Drupal, events, interesting tidbits on Theming and Development, and so forth. It is more than OK to cross post (you retain copyright to the content but do grant Examiner.com a license to use that content) from your own blog if you already have a home you write from and, best of all, you get paid for page views. It is a great way to promote Drupal, increase your own visibility, and/or build your local Drupal community. If you're interested, contact Stacey at sharrison@examiner.com. Or speak with us during this Drupalcamp.