Creating Content Types Programmatically

Posted on Mar 3, 2012

There are two ways to create content types in Drupal. The first is using hook_node_info in your module. When using this method, this only creates a content type with a title and a body (providing you implement the hook_form() function.)

function blog_node_info() {
  return array(
    'blog' => array(
      'name' => t('Blog entry'),
      'module' => 'blog',
      'description' =&gt; t('A <em>blog entry</em> is a single post to an online journal, or <em>blog</em>.'),
      'has_title' =&gt; TRUE,
      'has_body' =&gt; TRUE,
    )
  );
}
function blog_form($node, $form_state) {
    return node_content_form($node, $form_state);
}

The other way is to programmically recreate a content type by exporting the content type with the Content Copy module. For example, you’re working on module that relies on content type that you created along with a number of CCK fields. The first step in this method is to enable the Content Copy module.  Once the module is enabled head over to admin/content/types/export to select the content type you wish to export. The export will be an array so you can use it in a module.

$content['type']  = array (
  'name' =&gt; 'Membership',
  'type' =&gt; 'product',
  'description' =&gt; 'This node displays the representation of a membership for sale on the website. ',
  'title_label' =&gt; 'Name',
  'body_label' =&gt; 'Description',
  'min_word_count' =&gt; '0',
  'help' =&gt; '',
  'node_options' =&gt;
  array (
    'status' =&gt; true,
    'revision' =&gt; true,
    'promote' =&gt; false,
    'sticky' =&gt; false,
  ),
  'old_type' =&gt; 'product',
  'orig_type' =&gt; 'product',
  'module' =&gt; 'uc_product',
  'custom' =&gt; '0',
  'modified' =&gt; '1',
  'locked' =&gt; '1',
  'reset' =&gt; 'Reset to defaults',
  'uc_product_shippable' =&gt; 0,
  'uc_image' =&gt; '',
  'comment' =&gt; '0',
  'comment_default_mode' =&gt; '4',
  'comment_default_order' =&gt; '1',
  'comment_default_per_page' =&gt; '50',
  'comment_controls' =&gt; '3',
  'comment_anonymous' =&gt; 0,
  'comment_subject_field' =&gt; '1',
  'comment_preview' =&gt; '1',
  'comment_form_location' =&gt; '0',
);
$content['fields']  = array (
  0 =&gt;
  array (
    'label' =&gt; 'Image',
    'field_name' =&gt; 'field_image',
    'type' =&gt; 'filefield',
    'widget_type' =&gt; 'imagefield_widget',
    'change' =&gt; 'Change basic information',
    'weight' =&gt; '31',
    'file_extensions' =&gt; 'png gif jpg jpeg',
    'progress_indicator' =&gt; 'bar',
    'file_path' =&gt; '',
    'max_filesize_per_file' =&gt; '',
    'max_filesize_per_node' =&gt; '',
    'max_resolution' =&gt; 0,
    'min_resolution' =&gt; 0,
    'custom_alt' =&gt; 0,
    'alt' =&gt; '',
    'custom_title' =&gt; 0,
    'title_type' =&gt; 'textfield',
    'title' =&gt; '',
    'use_default_image' =&gt; 0,
    'default_image_upload' =&gt; '',
    'default_image' =&gt; NULL,
    'description' =&gt; '',
    'required' =&gt; 0,
    'multiple' =&gt; '1',
    'list_field' =&gt; '0',
    'list_default' =&gt; 1,
    'description_field' =&gt; '0',
    'op' =&gt; 'Save field settings',
    'module' =&gt; 'filefield',
    'widget_module' =&gt; 'imagefield',
    'columns' =&gt;
    array (
      'fid' =&gt;
      array (
        'type' =&gt; 'int',
        'not null' =&gt; false,
        'views' =&gt; true,
      ),
      'list' =&gt;
      array (
        'type' =&gt; 'int',
        'size' =&gt; 'tiny',
        'not null' =&gt; false,
        'views' =&gt; true,
      ),
      'data' =&gt;
      array (
        'type' =&gt; 'text',
        'serialize' =&gt; true,
        'views' =&gt; true,
      ),
    ),
    'display_settings' =&gt;
    array (
      'label' =&gt;
      array (
        'format' =&gt; 'above',
        'exclude' =&gt; 0,
      ),
      'teaser' =&gt;
      array (
        'format' =&gt; 'image_plain',
        'exclude' =&gt; 0,
      ),
      'full' =&gt;
      array (
        'format' =&gt; 'image_plain',
        'exclude' =&gt; 0,
      ),
      4 =&gt;
      array (
        'format' =&gt; 'image_plain',
        'exclude' =&gt; 0,
      ),
      'token' =&gt;
      array (
        'format' =&gt; 'image_plain',
        'exclude' =&gt; 0,
      ),
    ),
  ),
);
$content['extra']  = array (
  'title' =&gt; '-5',
  'body_field' =&gt; '-4',
  'revision_information' =&gt; '20',
  'author' =&gt; '20',
  'options' =&gt; '25',
  'comment_settings' =&gt; '30',
  'menu' =&gt; '0',
  'path' =&gt; '30',
  'shipping' =&gt; '0',
  'base' =&gt; '-1',
  'body' =&gt; '1',
);

In a hook_install or hook_enable function, and after making sure the content type doesn’t already exist, you would do the following:

module_load_include('inc', 'content', 'includes/content.crud');
$content['type']  = array (
  'name' =&gt; 'Membership',
  'type' =&gt; 'product',
  'description' =&gt; 'This node displays the representation of a membership for sale on the website. ',
  'title_label' =&gt; 'Name',
  'body_label' =&gt; 'Description',
  'min_word_count' =&gt; '0',
  'help' =&gt; '',
  'node_options' =&gt;
  array (
    'status' =&gt; true,
    'revision' =&gt; true,
    'promote' =&gt; false,
    'sticky' =&gt; false,
  ),
  'old_type' =&gt; 'product',
  'orig_type' =&gt; 'product',
  'module' =&gt; 'uc_product',
  'custom' =&gt; '0',
  'modified' =&gt; '1',
  'locked' =&gt; '1',
  'reset' =&gt; 'Reset to defaults',
  'uc_product_shippable' =&gt; 0,
  'uc_image' =&gt; '',
  'comment' =&gt; '0',
  'comment_default_mode' =&gt; '4',
  'comment_default_order' =&gt; '1',
  'comment_default_per_page' =&gt; '50',
  'comment_controls' =&gt; '3',
  'comment_anonymous' =&gt; 0,
  'comment_subject_field' =&gt; '1',
  'comment_preview' =&gt; '1',
  'comment_form_location' =&gt; '0',
);
$content['fields']  = array (
  0 =&gt;
  array (
    'label' =&gt; 'Image',
    'field_name' =&gt; 'field_image',
    'type' =&gt; 'filefield',
    'widget_type' =&gt; 'imagefield_widget',
    'change' =&gt; 'Change basic information',
    'weight' =&gt; '31',
    'file_extensions' =&gt; 'png gif jpg jpeg',
    'progress_indicator' =&gt; 'bar',
    'file_path' =&gt; '',
    'max_filesize_per_file' =&gt; '',
    'max_filesize_per_node' =&gt; '',
    'max_resolution' =&gt; 0,
    'min_resolution' =&gt; 0,
    'custom_alt' =&gt; 0,
    'alt' =&gt; '',
    'custom_title' =&gt; 0,
    'title_type' =&gt; 'textfield',
    'title' =&gt; '',
    'use_default_image' =&gt; 0,
    'default_image_upload' =&gt; '',
    'default_image' =&gt; NULL,
    'description' =&gt; '',
    'required' =&gt; 0,
    'multiple' =&gt; '1',
    'list_field' =&gt; '0',
    'list_default' =&gt; 1,
    'description_field' =&gt; '0',
    'op' =&gt; 'Save field settings',
    'module' =&gt; 'filefield',
    'widget_module' =&gt; 'imagefield',
    'columns' =&gt;
    array (
      'fid' =&gt;
      array (
        'type' =&gt; 'int',
        'not null' =&gt; false,
        'views' =&gt; true,
      ),
      'list' =&gt;
      array (
        'type' =&gt; 'int',
        'size' =&gt; 'tiny',
        'not null' =&gt; false,
        'views' =&gt; true,
      ),
      'data' =&gt;
      array (
        'type' =&gt; 'text',
        'serialize' =&gt; true,
        'views' =&gt; true,
      ),
    ),
    'display_settings' =&gt;
    array (
      'label' =&gt;
      array (
        'format' =&gt; 'above',
        'exclude' =&gt; 0,
      ),
      'teaser' =&gt;
      array (
        'format' =&gt; 'image_plain',
        'exclude' =&gt; 0,
      ),
      'full' =&gt;
      array (
        'format' =&gt; 'image_plain',
        'exclude' =&gt; 0,
      ),
      4 =&gt;
      array (
        'format' =&gt; 'image_plain',
        'exclude' =&gt; 0,
      ),
      'token' =&gt;
      array (
        'format' =&gt; 'image_plain',
        'exclude' =&gt; 0,
      ),
    ),
  ),
);
$content['extra']  = array (
  'title' =&gt; '-5',
  'body_field' =&gt; '-4',
  'revision_information' =&gt; '20',
  'author' =&gt; '20',
  'options' =&gt; '25',
  'comment_settings' =&gt; '30',
  'menu' =&gt; '0',
  'path' =&gt; '30',
  'shipping' =&gt; '0',
  'base' =&gt; '-1',
  'body' =&gt; '1',
);
$form_state = array();
$form = content_copy_import_form($form_state, $content['type']['type']);
$form_state['values']['type_name'] = $type_name ? $type_name : '<create>';
$form_state['values']['macro'] = '$content = '. var_export($content, 1) .';';
$form_state['values']['op'] = t('Import');
content_copy_import_form_submit($form, $form_state);