Last updated February 13, 2015. Created on April 12, 2011.
Edited by mikedance, vordude, timodwhit, bfr. Log in to edit this page.

The field_ui module has a built in field management system for your entity bundles. Enabling this system for your entity is a relatively simple process.

This doc will assume that you want to use a similar format to the core modules, that is, stating entity types (bundles) are listed at admin/structure/example; entity types are added at admin/structure/example/add, and existing entity types are managed, edited, and fielded at admin/structure//manage/. If you want your pages somewhere else, just change the addresses appropriately. Obviously you need to replace 'example' with the name of your module, and "bundle_key" can be anything you want - eg. for node.module, it is "content_type".

To implement this, you need to do five basic things:

  • Make your entities fieldable.
  • Implement the required menu structure.
  • Add a listing page for your bundles.
  • Add an edit page for your bundle settings.
  • Add an edit page for your entities.

Make entities fieldable

In your hook_entity_info implementation you need to do two things: First, make your entity fieldable, then declare the management page for each bundle. Your hook_entity_info implementation should include at minimum this:

<?php
/**
 * Implements hook_entity_info().
 */
function example_entity_info() {
 
$entities['example'] = array(
   
'label' => t('Example label'),
   
'fieldable' => TRUE,        // This bit is important
   
'entity keys' => array(
     
'id' => 'example_id',     // eg. 'nid' in node.module
     
'bundle' => 'bundle_key', // eg. 'content_type' in node.module 
   
),
   
'bundle keys' => array(
     
'bundle' => 'bundle_key', // as above.
   
),
   
'bundles' => array(  // This is an array of all your bundles. You'll probably want to create it programatically.
      // ... Bundles need, at minimum:
     
'bundle_one' => array( // This is the bundle_key.
       
'label' => 'Bundle One',
       
'admin' => array(
         
'path' => 'admin/structure/example/manage/%bundle_key',
         
// This is unique to each bundle.
         
'real path' => 'admin/structure/example/manage/bundle_one'
         
'bundle argument' => 4// Arg 4 is %bundle_key.
          // What ever permission that you've assigned in hook_permission.
         
'access arguments' => array('administer example bundles'),
        ),
       
// You might want to also include a bunch of other stuff here,
        // depending on your entity.
     
),
    ),
  );
  return
$entities;
}
?>

Implement the required menu structure.

You need it implement hook_menu implementations for each of the following forms. Here's the basics of what you'll probably want in your hook_menu implementation:

<?php
/**
 * Implements hook_menu().
 */
function example_menu() {
 
$items['admin/structure/example'] = array(
   
//The main list that displays your bundles, and has links to edit pages.
   
'title' => 'Example',
   
'access arguments' => array('administer example'), // Defined in hook_permission
   
'page callback' => 'example_list'// We define this function below.
   
'file' => 'example.admin.inc',      // Not neccesary if defined in the same file
 
);
 
$items['admin/structure/example/list'] = array( // As above.
   
'title' => 'List',
   
'type' => MENU_DEFAULT_LOCAL_TASK,
   
'weight' => -10,
  );
 
$items['admin/structure/example/add'] = array(
   
'title' => 'Add new Example bundle',
   
'access arguments' => array('administer example'),
   
'page callback' => 'drupal_get_form',
   
'page arguments' => array('bundle_key_form'), // we define this form hook below.
   
'type' => MENU_LOCAL_ACTION,
   
'file' => 'example.admin.inc',
  );
 
$items['admin/structure/example/manage/%bundle_key'] = array(
   
'title' => 'Edit example type',
   
'access arguments' => array('administer example'),
   
'page callback' => 'drupal_get_form',
   
'page arguments' => array('bundle_key_form', 4), //same hook as above, also passing %bundle_key
   
'type' => MENU_CALLBACK,
   
'file' => 'example.admin.inc',
  );
 
$items['admin/structure/types/manage/%bundle_key/edit'] = array( // As above.
   
'title' => 'Edit',
   
'type' => MENU_DEFAULT_LOCAL_TASK, // >>> TODO: This tab doesn't display <<<
   
'weight' => -10,
  );
 
$items['example/%example_id'] = array( // Page to display your entities.
   
'title callback' => 'example_page_title',
   
'title arguments' => array(1),
   
'access arguments' => array('access content'),
   
'page callback' => 'example_page'// We define this function below.
   
'page arguments' => array(1),
  );
 
$items['example/%example_id/view'] = array( // As above.
   
'title' => 'View',
   
'type' => MENU_DEFAULT_LOCAL_TASK,
   
'weight' => -10,
  );
 
$items['example/%example_id/edit'] = array( //page to edit your entities.
   
'title' => 'Edit',
   
'access arguments' => array('access content'),
   
'page callback' => 'example_edit'// We define this function below.
   
'page arguments' => array(1),
   
'type' => MENU_LOCAL_TASK,
  );
  return
$items;
}
?>

Add a listing page for your bundles.

Define your

<?php
/**
 * List all example predicates.
 */
function example_list() {
 
// Call your hook_entity_info implementation, 'cause it includes all your bundles.
 
$example = example_entity_info(); 
 
$headers = array(t('Name'), t('Actions')); // Table Headers
 
$rows = array();
  foreach (
$example['example']['bundles'] as $name => $bundle) {
   
// Get the bundle edit link, add it to a table row.
   
$link = l(t('edit'), 'admin/structure/example/manage/' . $name . '/edit');
   
$rows[] = array($bundle['label'], $link);
  }
 
// Format the table array. This is a pretty simple table, you could include
  // links to the field management pages for each bundle too.
 
$output = array(
   
'#theme' => 'table',
   
'#header' => $headers,
   
'#rows' => $rows,
  );
  return
$output;
}
?>

Add an edit page for your bundle settings.

Add the admin/structure/types/manage/%bundle_key/edit page:

<?php
/**
 * Relation example type bundle settings form. This is used for adding and
 * editing bundles.
 */
function example_type_form($form, &$form_state, $bundle = array(), $op = 'edit') {
 
// This function contains all the standard information that your entity
  // bundles need.
}
?>

The above form also needs a example_type_form_submit() function.

Add an edit page for your entities.

Add edit and display pages for your entities.

<?php
/**
 * Example bundle edit page.
 */
function example_edit($example) {
 
$build = array();
 
// Add any form items you need for you standard entity information  in the
  // $build array (eg. node module has stuff here about whether node is
  // published, author details, that kind of thing.
 
  // Somewhere in your function, call field_attach_form to add the field forms
 
field_attach_form('example', $example, $build, $form_state = array());
 
 
// And return your form
 
return $build;
}

/**
 * Example entity display page.
 */
function example_page($example) {
 
$build = array();
 
// Again, load and add all your standard entity data, then call
  // field_atttach_prepare_view somewhere to add the field_display
  // >>>> TODO: THIS IS WRONG <<<<
 
field_attach_prepare_view('example', array($example->example_id => $example), 'full');
 
  return
$build;
}
?>

That's it! If you now go to admin/structure, you'll see your "Example" sub-menu item. If you click there, you'll see a list of bundles, and edit links. You'll also see an "Add new Example bunde" button above the list. If you edit one of the bundles, you'll see the edit form, and two tabs, one for managing fields, one for managing the field display.

Looking for support? Visit the Drupal.org forums, or join #drupal-support in IRC.

Comments

SameerJ’s picture

The 'bundle_key_form' which is supposed to be displayed under the menu item 'admin/structure/example/add' is missing, along with its validation and submit functions.

ADDED LATER - It seems that there is the 'example_type_form'. It is this form that should be mentioned in the menu item 'admin/structure/example/add'. It would be good to give the code for this form along with the validation and submit functions.