This seems to be a popular issue.
I just had to insert a field into the imagefield alt / title / description area and was surprised at how hard this was (new to CCK but not Drupal or FAPI)
Is it possible to get something like this added to filefield #process callback?
<?php
// Provides a defacto hook_form_alter on the widget
$extra_values = isset($element['#value']['data']) ? $element['#value']['data'] : array();
$extra_fields = module_invoke_all('filefield_alter_widget', $element, $extra_values);
foreach ($extra_fields as $key => $field) {
$element['data'][$key] = $field;
}
// Example usage, a checkbox and wysiwyg textarea into all elements
function isis_filefield_alter_widget($element, $extra_values = array()) {
$extra_fields = array();
$extra_fields['exclude-gallery'] = array(
'#type' => 'checkbox',
'#title' => t('Exclude from gallery'),
'#default_value' => isset($extra_values['exclude-gallery']) ? $extra_values['exclude-gallery'] : 0,
'#attributes' => array('class' => 'imagefield-text'),
'#prefix' => '<div class="form-item">',
'#suffix' => '</div>',
);
$extra_fields['text-example']['body'] = array(
'#type' => 'textarea',
'#title' => t('Text area example'),
'#default_value' => isset($extra_values['text-example']['body']) ? $extra_values['text-example']['body'] : '',
'#attributes' => array('class' => 'imagefield-text'),
);
$parents = array_merge($element['#parents'], array('data', 'text-example', 'format'));
$extra_fields['text-example']['format'] = filter_form(isset($extra_values['text-example']['format']) ? $extra_values['text-example']['format'] : NULL, NULL, $parents);
return $extra_fields;
}
?>
I wrote a 95 line module to do this for the 6.3 branch, but it seems like overkill to just to do this.
<?php
/**
* @file
* Insert additional fields into an ImageField data array.
*/
/**
* Implementation of hook_theme().
*/
function imagefield_alter_theme($existing, $type, $theme, $path) {
return array(
'imagefield_alter_widget' => array(
'arguments' => array('element' => NULL),
)
);
}
/**
* Implementation of hook_widget_info().
*/
function imagefield_alter_widget_info() {
$module_path = drupal_get_path('module', 'imagefield');
return array(
'imagefield_alter_widget' => array(
'label' => t('Image - additional fields'),
'field types' => array('filefield'),
'multiple values' => CONTENT_HANDLE_CORE,
'callbacks' => array('default value' => CONTENT_CALLBACK_CUSTOM),
'description' => t('An edit widget for image files, including a preview of the image.'),
),
);
}
/**
* Implementation of CCK's hook_widget_settings().
*/
function imagefield_alter_widget_settings($op, $widget) {
switch ($op) {
case 'form':
return imagefield_widget_settings_form($widget);
case 'validate':
return imagefield_widget_settings_validate($widget);
case 'save':
return imagefield_widget_settings_save($widget);
}
}
/**
* Implementation of hook_widget().
*/
function imagefield_alter_widget(&$form, &$form_state, $field, $items, $delta = 0) {
$element = module_invoke('imagefield', 'widget', $form, $form_state, $field, $items, $delta);
return $element;
}
/**
* Widget theme callback.
*/
function theme_imagefield_alter_widget(&$element) {
return theme('form_element', $element, $element['#children']);
}
/**
* Implementation of hook_elements().
*/
function imagefield_alter_elements() {
$elements = array();
$elements['imagefield_alter_widget'] = array(
// Indicate to FormAPI that this element needs processing and is not simply a render element.
'#input' => TRUE,
// Delegate element processing to FileField, then call ImageField, then Easy Image Insert.
'#process' => array('filefield_widget_process', 'imagefield_widget_process', 'imagefield_alter_widget_process'),
// See imagefield_widget[#process] documentation.
'#value_callback' => 'imagefield_widget_value',
// Delegate element validation to FileField, then call ImageField.
'#element_validate' => array('filefield_widget_validate', 'imagefield_widget_validate'),
'#description' => t('Changes made to the attachments are not permanent until you save this post.'),
);
return $elements;
}
/**
* Element #process callback function.
*/
function imagefield_alter_widget_process($element, $edit, &$form_state, $form) {
$extra_values = isset($element['#value']['data']) ? $element['#value']['data'] : array();
$extra_fields = module_invoke_all('imagefield_alter_widget', $element, $extra_values);
foreach ($extra_fields as $key => $field) {
$element['data'][$key] = $field;
}
return $element;
}
?>
The only issue I found using the data array at the widget level, was that the values in the data array are lost if they are not available in the new widget when you switch widget types, a feature or a bug. Depends on the usage!
Anyway, happy to release as a module if there is no easier solution to this.
Cheers
| Comment | File | Size | Author |
|---|---|---|---|
| #1 | imagefield_extended.zip | 3.32 KB | alan d. |
Comments
Comment #1
alan d. commentedI'm just following up. We've used the same approach for 4 projects now and have written & released a module to automate this.
It is a bit more advanced using hook_widget_settings() to add some defaults that sort of come up a lot in our workplace via a simple interface;
Text with display options of single, multi, wysiwyg. Eg: For caption, copyright fields
Checkboxes. Eg: For workflow related flags; node image, gallery and featured checkboxes
And I use hook_elements to add a new #process callback to create the new elements above and do a module_invoke_all within this to allow other modules to interact, adding their own elements to the data element.
The module has been released, Imagefield extended, making the attached module obsolete.
Moving back to ImageField as it is more specific to this. It would be great to be able to hook directly into both the File and ImageField widgets without having to extend both.
Anyway, I'd love to hear your thoughts.
Comment #2
alan d. commentedThe above solution seems to keep people happy enough :)