Tech Blog :: cck :: cck


Aug 6 '10 1:15pm

Drupal: Impossible to set custom size for embedded video field in a view?

I have an Embedded Media youtube video field shared across multiple content types on a site, and nodequeues for the administrators to pick from these videos and feature them on various landing pages. The designs call for the videos to be different sizes on different pages - sometimes the standard 425px, sometimes 300px, sometimes widescreen 600px. When I saw the designs, I thought "I'm sure that's easy to do," and gave my approval. I'm implementing each "featured video" using a view that pulls from the respective nodequeue and displays the video as a field.

Well... I've spent hours trying to crack this nut, and my conclusion is that it's nearly impossible to do in a clean way. By clean I mean, I want to specify per view what size the video should appear. I can't set it per content type (using the backend UI) because the videos come from many content types, and if I set it by URL, there could be other videos on those pages that don't need special formatting. The settings for the field in Views only have Full and Preview, not custom sizes.

The logical approach seemed to be a hook_views_pre_render like so:
$view->field['field_video_youtube_embed']->content_field['widget']['video_width'] = 300;

That didn't work (still came out 425px), so I decided to go down an academic rabbit hole to figure out why...

The problem seems to arise with the generic content_handler_field::render() class that the field is rendered through. The object has a perfectly good $this->content_field array, which includes my modified width/height. But the function finds it necessary for some reason to get a fresh field array,
$field = content_fields($this->content_field['field_name'], $values->{$this->aliases['type']});
so the parameters are all reset. Why??

I'll just use a fields preprocessor to re-render the field. Should have done that to begin with; this study was intellectually fascinating (in a sad way) but otherwise a huge waste of time.

Jan 11 '10 11:46am
Tags

Drupal: Automating CCK field creation with update hook/deployment

I had a Drupal (6) project recently that involved adding a new computed field to a content type. The field could be added manually on each deployment, or automated with an update hook. I decided to try out the automatic method, here's how to do it:
<?php
// update hook
// see http://api.drupal.org/api/function/hook_update_N for function name, return value
// only works in 6.11+, see http://drupal.org/node/297972
function MYMODULE_update_6101() {
  $ret = array();
 
  $content_type = 'article';
  $new_field_name = 'some_field_name';    // w/o field_
 
  // depends on a bunch of widget modules -- just load them all
  module_load_all();
  // make sure cck admin file is loaded
  include_once drupal_get_path('module', 'content') . '/includes/content.admin.inc';
 
  if (!function_exists('content_field_overview_form') or !function_exists('content_help')) {    // will fail if includes didn't work
    $ret[] = array('success'=>false, 'query'=>'Unable to load necessary include files');
    return $ret;
  }
 
  // does the field already exist?
  // (content_fields() ignores inactive fields, but should be ok - see content.admin.inc for alternative)
  if (content_fields('field_'.$new_field_name, $content_type)) {
    $ret[] = array('success'=>true, 'query'=>"field_{$new_field_name} already exists");
    return $ret;
  }
 
  // enable the 'computed field' module if not already running
  if (! module_exists('computed_field')) {
    module_enable( array('computed_field') );   // (doesn't return anything)
 
    // if not running now, there was an error
    if (! module_exists('computed_field')) {
      $ret[] = array('success'=>false, 'query'=>'Unable to enable computed_field module, can\'t continue.');
      return $ret;
    }
  }
  $ret[] = array('success'=>true, 'query'=>'Computed Field module is enabled.');
 
 
  // simulate the content type add-field form
  $form = array();
 
  // for testing, load the form to view it
  // $form = drupal_retrieve_form('content_field_overview_form', $form_state, $content_type);    // $content_type=>$type_name
  // $ret[]['query'] = '<pre>'.print_r($form,true).'</pre>';
 
  $form_state['values']['_add_new_field']['label'] = 'Name of New Field';
  $form_state['values']['_add_new_field']['field_name'] = $new_field_name;
  $form_state['values']['_add_new_field']['type'] = 'computed';
  $form_state['values']['_add_new_field']['widget_type'] = 'computed';
  $form_state['values']['_add_new_field']['parent'] = 'group_some_group';  // put under fieldgroup (optional)
 
  // generate & submit the form
  drupal_execute('content_field_overview_form', $form_state, $content_type);          // $content_type goes into $type_name
 
  // check if exists now
  if ($new_field = content_fields('field_'.$new_field_name, $content_type)) {
    $ret[] = array('success'=>true, 'query'=>'NEW '.$new_field_name.': <pre>'.print_r($new_field,true).'</pre>');
    return $ret;
  }
  else {
    $ret[] = array('success'=>false, 'query'=>"An error occured creating the new {$new_field_name}, does not exist.");
  }
 
  // for testing
  // $ret[] = array('success'=>true, 'query'=>l('Run update again', 'update.php'));
      // -- reset system.`schema_version` where name='MYMODULE' to run again
 
  return $ret;
}
One major caveat: I discovered the hard way that this doesn't work prior to 6.11. (Fixed: #297972: make the batch API compatible with drupal_execute(), so things like creating a CCK type or adding fields to it (by submitting forms programatically) are possible in update functions). So if for some reason you're stuck on a pre-6.11 core, you're probably best making the fields manually. (In my case it would have been faster to do that from the start, but I wanted to see how this could be done.)