CCK for developers

create CCK type in a module

juicytoo - August 1, 2009 - 13:46

Could someone please outline how to create a custom CCK in a module.

I've read the threads:

http://drupal.org/node/348214

also

http://civicactions.com/blog/cck_import_and_update

http://snipplr.com/view/3891/import-cck-definition-from-text-file/

http://groups.drupal.org/node/5272

http://drupal.org/node/128038#comment-921630

specifically:

* @param $module
* @param $dir
*   The module which containing the CCK definitions.
* @param $ext
*   Extension
*/
function cck_install_content_dir($module, $dir = 'content_types', $ext = 'content') {
    $content_types = content_types();
    $files = file_scan_directory(drupal_get_path('module', $module) . '/' . $dir, "\.${ext}$");
    foreach ($files as $file) {
        module_load_include('inc', 'install_profile_api', 'contrib/content_copy');
        install_content_copy_import_from_file($file->filename);
    }
}
In example:
/**
* Implementation of hook_install().
*/

function my_module_install() {
    cck_install_content_dir('my_module');
}

But how to adjust this to a module and NOT in an installation profile.

Do I just put this code in the *.module file.

How does it get triggered in module setup?

The reason?
SO I don't have to reinstall drupal in order to create custom CCKs.

Thanks in advance.

cheers
Ed
geeksupport.com.au

That is not an installation

nevets - August 1, 2009 - 13:55

That is not an installation profile, it's a modules install file that run once when the module is installed and is the appropriate place to do what you are after the reason being that code is meant to only run once. One could make a setting pages that adapts that code to it keeps track of files already loaded and does not load them again.

Programmatic CCK content type creation

juicytoo - August 10, 2009 - 12:38

I found this too.

http://tinpixel.com/node/53

http://thedrupalblog.com/programmatically-create-any-node-type-using-dru...

Step 3: create a PHP function to hold your CCK definition
The template of the function will look like this, prior to pasting the contents of your copy buffer from above (containing the exported CCK content type definition code). We use a separate function just for the definition because it is must be updated with a new export from CCK if we decide to change or tweak our CCK content type later. It makes editing easier and less error prone.

function _modulename_cck_export() {
// paste code after this line.

// paste code before this line.
return $content;
}

Step 6: Write PHP code to actually create the content type
Write the install code to initiate creation of the new content type. This is where we make sure we have the necessary CCK pieces, populate a form using the now hard-coded CCK export, and then use drupal_execute() to submit the form to create the new content type. Here's an example:

function _example_install_cck_node() {
/* get the CCK node types to be created. This is where you load the
* file containing your function from above, if necessary, and then call
* that function.
*/
module_load_include('inc', 'modulename', 'modulename.ccknodedef');
$content = _modulename_cck_export(); // in modulename.ccknodedef.inc

// CCK content_copy.module may not be enabled, so make sure it is included
require_once './' . drupal_get_path('module', 'content')
. '/modules/content_copy/content_copy.module';

$form_state['values']['type_name'] = '';
$form_state['values']['macro'] = '$content = ' . var_export($content, TRUE) . ';';

// form provided by content_copy.module
drupal_execute('content_copy_import_form', $form_state);
content_clear_type_cache();
}

EDIT:
I'm happy to say the following code worked for me. ;-)
I'm also able to use node_import to import values into a newly created CCK node.

in the provider.install file

<?php
// $Id$

/***********************************************************************************************
* Implemenation of hook_install();
*/
function provider_install(){

  watchdog('provider_install.');
provider_update_1();
};


/***********************************************************************************************
* Implemenation of provider_update_1();
*  just so that i can force build of CCK Types without uninstalling/re-installing
*/
function provider_update_1() {
//
  $ret = array();

watchdog('provider_update_1.');

//
  if (!module_exists("content_copy")) {
    drupal_set_message('Programmatically creating CCK fields requires the Content Copy module. Exiting.');
 
// CCK content_copy.module may not be enabled, so make sure it is included
  require_once './' . drupal_get_path('module', 'content')
      . '/modules/content_copy/content_copy.module';
     
  }

   // add CCK types
  $path = drupal_get_path('module', 'provider') . "/cck_types";
  $cck_types = glob($path . "/*.txt");
  foreach ($cck_types as $cck_type) {
    provider_install_cck_node('<create>', '', $cck_type);
  }

  return $ret;
}

/**
* Programmatically create CCK fields and types using the content copy module
* @param $type string
* content type to create, defaults to new type, if type exists, only fields will be added
* @param $macro array
* exported array from content types -> export. If file is not specified, macro will be used
* @param $file string
* path to file containing content copy exported macro data structure. no escaping needed.
*/
function provider_install_cck_node($type = '<create>', $macro = '', $filename = '') {

watchdog('provider_install_cck_node.');
   
  // Get the files content
  if (file_exists($filename)) {
  $content = implode('', file ($filename));
  }
  else {
    drupal_set_message('Unable to read input file for import. Exiting.');
    return;
  }

  // Build form state
  $form_state = array(
  'values' => array(
    'type_name' => '<create>',
      'macro' => $content,
    ),
);

  // form provided by content_copy.module 
  drupal_execute('content_copy_import_form', $form_state);
  content_clear_type_cache();
}




/***********************************************************************************************
* Implemenation of hook_install();
*/
function provider_uninstall(){
//For hook_uninstall() you can simply do
node_type_delete('provider');
watchdog('provider_uninstall.');

}

in the provider.module file

<?php


/*****************************************************************************
* Implemenation of hook_init(); placeholder, doesn't do anything.
*/
function provider_init(){
}

file structure

module/provider/provider.install
module/provider/provider.module
module/provider/cck_types/apples.txt

where apples.txt is a CCK export of the GUI.

ie

$content['type']  = array (
  'name' => 'Provider',
  'type' => 'provider',
  'description' => 'Provider Description',
  'title_label' => 'Title',
  'body_label' => 'Body',
  'min_word_count' => '0',
  'help' => '',
  'node_options' =>
  array (
  'status' => true,
'promote' => true,
'sticky' => false,
'revision' => false,
),
'language_content_type' => '0',
'upload' => '1',
'old_type' => 'provider',
'orig_type' => '',
'module' => 'node',
'custom' => '1',
'modified' => '1',
'locked' => '0',
'signup_node_default_state' => 'disabled',
'content_profile_use' => false,
'fivestar' => 0,
'fivestar_stars' => 5,
'fivestar_labels_enable' => 1,
'fivestar_label_0' => 'Cancel rating',
'fivestar_label_1' => 'Poor',
'fivestar_label_2' => 'Okay',
'fivestar_label_3' => 'Good',
'fivestar_label_4' => 'Great',
'fivestar_label_5' => 'Awesome',
'fivestar_label_6' => 'Give it @star/@count',
'fivestar_label_7' => 'Give it @star/@count',
'fivestar_label_8' => 'Give it @star/@count',
'fivestar_label_9' => 'Give it @star/@count',
'fivestar_label_10' => 'Give it @star/@count',
'fivestar_style' => 'average',
'fivestar_text' => 'dual',
'fivestar_title' => 1,
'fivestar_feedback' => 1,
'fivestar_unvote' => 0,
'fivestar_position_teaser' => 'hidden',
'fivestar_position' => 'below',
'fivestar_comment' => 0,
'image_attach' => '0',
'image_attach_size_teaser' => 'thumbnail',
'image_attach_weight_teaser' => '0',
'image_attach_size_body' => 'thumbnail',
'image_attach_weight_body' => '0',
'comment' => '2',
'comment_default_mode' => '4',
'comment_default_order' => '1',
'comment_default_per_page' => '50',
'comment_controls' => '3',
'comment_anonymous' => 0,
'comment_subject_field' => '1',
'comment_preview' => '1',
'comment_form_location' => '0',
'event_nodeapi' => 'never',
'location_addanother' => 0,
);

$content['fields']  = array (
0 =>
array (
'label' => 'Email',
'field_name' => 'field_email',
'type' => 'email',
'widget_type' => 'email_textfield',
'change' => 'Change basic information',
'weight' => '32',
'size' => '60',
'description' => '',
'default_value' =>
array (
0 =>
array (
'email' => '',
),
),
'default_value_php' => '',
'default_value_widget' => NULL,
'group' => false,
'required' => 0,
'multiple' => '0',
'op' => 'Save field settings',
'module' => 'email',
'widget_module' => 'email',
'columns' =>
array (
'email' =>
array (
'type' => 'varchar',
'length' => 255,
'not null' => false,
'sortable' => true,
),
),
'display_settings' =>
array (
'weight' => '32',
'parent' => '',
'label' =>
array (
'format' => 'inline',
),
'teaser' =>
array (
'format' => 'hidden',
'exclude' => 0,
),
'full' =>
array (
'format' => 'contact',
'exclude' => 0,
),
4 =>
array (
'format' => 'default',
'exclude' => 0,
),
2 =>
array (
'format' => 'default',
'exclude' => 0,
),
3 =>
array (
'format' => 'default',
'exclude' => 0,
),
'token' =>
array (
'format' => 'default',
'exclude' => 0,
),
),
),
1 =>
array (
'label' => 'Website',
'field_name' => 'field_website',
'type' => 'link',
'widget_type' => 'link',
'change' => 'Change basic information',
'weight' => '33',
'description' => '',
'default_value' =>
array (
0 =>
array (
'title' => '',
'url' => '',
),
),
'default_value_php' => '',
'default_value_widget' =>
array (
'field_website' =>
array (
0 =>
array (
'title' => '',
'url' => '',
),
),
),
'group' => false,
'required' => 0,
'multiple' => '0',
'url' => 0,
'title' => 'none',
'title_value' => '',
'enable_tokens' => 0,
'display' =>
array (
'url_cutoff' => '80',
),
'attributes' =>
array (
'target' => 'default',
'rel' => '',
'class' => '',
),
'op' => 'Save field settings',
'module' => 'link',
'widget_module' => 'link',
'columns' =>
array (
'url' =>
array (
'type' => 'varchar',
'length' => 255,
'not null' => false,
'sortable' => true,
),
'title' =>
array (
'type' => 'varchar',
'length' => 255,
'not null' => false,
'sortable' => true,
),
'attributes' =>
array (
'type' => 'text',
'size' => 'medium',
'not null' => false,
),
),
'display_settings' =>
array (
'weight' => '33',
'parent' => '',
'label' =>
array (
'format' => 'inline',
),
'teaser' =>
array (
'format' => 'hidden',
'exclude' => 0,
),
'full' =>
array (
'format' => 'url',
'exclude' => 0,
),
4 =>
array (
'format' => 'default',
'exclude' => 0,
),
2 =>
array (
'format' => 'default',
'exclude' => 0,
),
3 =>
array (
'format' => 'default',
'exclude' => 0,
),
'token' =>
array (
'format' => 'default',
'exclude' => 0,
),
),
),
);
$content['extra']  = array (
'title' => '-5',
'body_field' => '0',
'menu' => '-2',
'attachments' => '30',
);

Enjoy.

cheers
Ed
geeksupport.com.au

extended to an module?

neurovation.kiwi - August 10, 2009 - 17:20

should this be extended in a cck add on module?

drush integration

juicytoo - September 8, 2009 - 14:45

ideally this should be part of drush.

ie.

drush [import cck type] [cck type file]

But I'm using it to create a "custom" module, while leveraging the freebies CCK gives me.

cheers
Ed
geeksupport.com.au

 
 

Drupal is a registered trademark of Dries Buytaert.