Drupal 6 CCK hook mysteries
March 11, 2009 11:10 AM   Subscribe

In Drupal's CCK, how do I add additional global settings to fields?

Disclaimer: I'm a Rails developer who is plenty familiar with PHP, but Drupal's learning curve is a little steeper than one morning. Pointing me to the right hooks or a module that does the same type of thing as I'm doing should be just as good as spelling out what to do.

I'm working with Content Profile and need to add a(n integer) setting for every field that's created under the Profile content type. Let's call it Priority. It'd be like the "Maximum length" setting in terms of numerality and globalness, but I need to add it via a module. hook_field_settings looks promising, but I can't figure out how to get in there on top of an existing field type - there are plenty of articles out there that show me how to do this if I was making a whole new field type, but I'd rather attach this to all of the existing ones.

Bonus points for getting this value to appear as a column on the top level 'Manage fields' page. Even more bonus points for the go-to (e)book for Drupal development.
posted by soma lkzx to Computers & Internet (8 answers total) 1 user marked this as a favorite
Response by poster: (If it matters, it's Drupal 6)
posted by soma lkzx at 11:11 AM on March 11, 2009

Best answer: I'll be interested to see what others say about this. As for myself, I can't speak authoritatively, but here are my suspicions:

a) Creating a new setting for all fields with the generality of #title or #tree would involve hacking the Form API.

b) Adding this setting as a column on the Manage Fields page would involve hacking CCK.

I don't recommend either of those approaches because they will come back to bite you, particularly whenever you upgrade.

Having said that, my suggestions would be, either find one of the global settings that you can hijack for your purposes, or add this setting to every field using hook_form_alter and hook_nodeapi. The latter approach shouldn't be too difficult.

Have you posted this in the Drupal module development forum?
posted by bricoleur at 11:38 AM on March 11, 2009

Response by poster: Have you posted this in the Drupal module development forum?

I'll take a look at hook_form_alter and hook_nodeapi, but that's a good idea - posted.
posted by soma lkzx at 11:51 AM on March 11, 2009

CCK's settings-related hooks are all only triggered for the specific module responsible for a given field. In theory, you can use hook_form_alter() and nodeapi -- as bricoleur suggested -- to do it. There isn't a way to inherently add new kinds of meta-meta-data to CCK's meta-data, though.
posted by verb at 1:41 PM on March 11, 2009

Response by poster: I almost died trying to get this to work. It didn't take too long to figure out form_alter, but actually getting the data into the database was terrible. The secret ended up being schema_alter, because Drupal apparently never actually looks at the database, and if a module never says "Hey I added a field" it'll just silently fail on putting the field into the database. Forever and ever.

What I ended up doing adds new column for priority (needed it for indexing), but if anyone wants to do it via the global_settings string you can add $form["#submit"][] = 'priority_form_submit' to the end of the form_alter to force a callback, make a priority_form_submit function and just put whatever you want into $form['global_settings']['variablename']. It's hard to put your own data into global_settings since it only pulls max/min/whatever for applicable types (Decimal, Text, etc) and they're hardcoded in a nodeapi callback.

Anyway, in case anyone needs to know how to do this, code's below.
function priority_form_alter(&$form, $form_state, $form_id) {
  if($form_id == "content_field_edit_form") {
    $form['field']['priority'] = array(
      '#type' => 'select',
      '#title' => t('Priority'),
      '#options' => array(NULL, 1, 2, 3, 4, 5, 6, 7),
      '#weight' => 0,
      '#default_value' => $form["#field"]['priority'],
      '#description' => t('Priority')

function priority_install() {
  db_add_field($ret, 'content_node_field', 'priority', array('type' => 'int', 'not null' => FALSE, 'default' => NULL));
  db_add_index($ret, 'content_node_field', 'priority', array('priority'));

function priority_schema_alter(&$schema) {
  $schema['content_node_field']['fields']['priority'] = array('type' => 'int', 'not null' => FALSE, 'default' => NULL);

posted by soma lkzx at 5:29 PM on March 11, 2009

soma, I would be VERY very careful about that approach: it's tremendously brittle, because CCK can shuffle the underlying table structure around depending on how you've configured it. (If it's a multivalue field, for example, it will be in its own dedicated table). Customarily, if your module is managing its own data, it's responsible for creating it's own auxiliary table and using hook_nodeapi() to read and write the data there.

If you're super-hardcore, and are willing to watch very carefully to make sure this code doesn't collide with other code, I will give major awesome points for the cool hack, though. hook_schema_alter() is not for the faint of heart and you are now on my Ninja list.
posted by verb at 7:06 PM on March 11, 2009

Response by poster: I'm thinking I might not have to worry about the multivalue field issue because I'm doing this on a per-content_node_field basis as opposed to a content_node_field_instance basis. But if I run into issues, my line of thought for this goes:

Drupal doesn't use ids, so I have to key off of field_name and type_name for a content_node_field (cck/includes/content.crud.inc:421). Drupal's node callbacks are basically owned by the module writer, so my hook would need to be adding through a submit hook to the form, and in that function I'd scrape out the previous and current field_name and type_name from it and creating/update a row in a priorities table based on that.

I bet there's something about hook_nodeapi() that I'm missing that would make my life a whole lot simpler.

throws down smokebomb, fades into shadows
posted by soma lkzx at 7:01 AM on March 12, 2009

I agree with verb that you deserve Ninja Mantle. Just trying to think through your code is giving me a headache and I'm going to stop now.

I also agree with him about it being somewhat brittle. I think you will be fine for the time being but experience some regrets when it's time to upgrade CCK or Drupal itself. In particular, I'd look through the CCK .install files carefully to see what database changes are entailed before proceeding with any upgrade there.

Also, here's some info about nodeapi that I found helpful when I was struggling with a similar problem.
posted by bricoleur at 1:00 PM on March 12, 2009

« Older Pick a Harddrive for my mac   |   Will a publicist help me reach for the stars? Newer »
This thread is closed to new comments.