- Patch #796658 by yched, andypost: UI for field formatter settings.

merge-requests/26/head
Dries Buytaert 2010-07-17 19:19:39 +00:00
parent ecc7ce0875
commit b135d644fe
6 changed files with 346 additions and 17 deletions

View File

@ -16,35 +16,51 @@
*/
?>
<?php if ($rows): ?>
<div id="field-display-overview-wrapper">
<table id="field-display-overview" class="field-display-overview sticky-enabled">
<thead>
<tr>
<th><?php print t('Field'); ?></th>
<th><?php print t('Weight'); ?></th>
<th><?php print t('Label'); ?></th>
<th><?php print t('Format'); ?></th>
<th colspan="3"><?php print t('Format'); ?></th>
</tr>
</thead>
<tbody>
<tr class="region-message region-visible-message <?php print empty($rows['visible']) ? 'region-empty' : 'region-populated'; ?>">
<td colspan="4"><em><?php print t('No field is displayed'); ?></em></td>
<td colspan="5"><em><?php print t('No field is displayed'); ?></em></td>
</tr>
<?php
$count = 0;
foreach ($rows['visible'] as $row): ?>
<tr class="<?php print $count % 2 == 0 ? 'odd' : 'even'; ?> <?php print $row->class ?>">
<tr id="<?php print $row->id; ?>" class="<?php print $count % 2 == 0 ? 'odd' : 'even'; ?> <?php print $row->class ?>">
<td><span class="<?php print $row->label_class; ?>"><?php print $row->human_name; ?></span></td>
<td><?php print $row->weight . $row->hidden_name; ?></td>
<td><?php if (isset($row->label)) print $row->label; ?></td>
<td><?php print $row->type; ?></td>
<?php if (isset($row->settings_edit_form)) : ?>
<td colspan="3">
<?php print $row->type; ?>
<?php print $row->settings_edit_form; ?>
</td>
<?php else :?>
<td>
<?php print $row->type; ?>
</td>
<td class="field-formatter-summary-cell">
<?php print $row->settings_summary; ?>
</td>
<td>
<?php print $row->settings_edit; ?>
</td>
<?php endif; ?>
</tr>
<?php $count++;
endforeach; ?>
<tr class="region-title region-title-hidden">
<td colspan="4"><?php print t('Hidden'); ?></td>
<td colspan="5"><?php print t('Hidden'); ?></td>
</tr>
<tr class="region-message region-hidden-message <?php print empty($rows['hidden']) ? 'region-empty' : 'region-populated'; ?>">
<td colspan="4"><em><?php print t('No field is hidden'); ?></em></td>
<td colspan="5"><em><?php print t('No field is hidden'); ?></em></td>
</tr>
<?php foreach ($rows['hidden'] as $row): ?>
<tr class="<?php print $count % 2 == 0 ? 'odd' : 'even'; ?> <?php print $row->class ?>">
@ -52,9 +68,16 @@
<td><?php print $row->weight . $row->hidden_name; ?></td>
<td><?php if (isset($row->label)) print $row->label; ?></td>
<td><?php print $row->type; ?></td>
<td class="field-formatter-summary-cell">
<?php print $row->settings_summary; ?>
</td>
<td>
<?php print $row->settings_edit; ?>
</td>
</tr>
<?php $count++;
endforeach; ?>
</tbody>
</table>
</div>
<?php endif; ?>

View File

@ -724,6 +724,10 @@ function field_ui_display_overview_form($form, &$form_state, $entity_type, $bund
return $form;
}
$form_state += array(
'formatter_settings_edit' => NULL,
);
$table = array(
'#theme' => 'field_ui_display_overview_table',
'#field_rows' => array(),
@ -742,7 +746,6 @@ function field_ui_display_overview_form($form, &$form_state, $entity_type, $bund
foreach ($instances as $name => $instance) {
$display = $instance['display'][$view_mode];
$table[$name]['human_name'] = array(
'#markup' => check_plain($instance['label']),
);
@ -762,13 +765,115 @@ function field_ui_display_overview_form($form, &$form_state, $entity_type, $bund
);
$field = field_info_field($instance['field_name']);
// The handling of the 'hidden' region in field_ui.js relies on the
// 'formatter type' select, so it is present in all cases, and hidden with
// CSS when the row is in 'edit settings' mode.
$formatter_options = field_ui_formatter_options($field['type']);
$formatter_options['hidden'] = t('<Hidden>');
$table[$name]['type'] = array(
'#type' => 'select',
'#options' => $formatter_options,
'#default_value' => $display['type'],
'#ajax' => array(
'callback' => 'field_ui_formatter_settings_js',
'wrapper' => 'field-display-overview-wrapper',
'effect' => 'fade',
),
'#field_name' => $name,
'#op' => 'change_type',
);
// Formatter settings.
// Check the currently selected formatter, and merge persisted values for
// formatter settings.
if (isset($form_state['values']['settings'][$name]['type'])) {
$formatter_type = $form_state['values']['settings'][$name]['type'];
}
else {
$formatter_type = $display['type'];
}
if (isset($form_state['formatter_settings'][$name])) {
$settings = $form_state['formatter_settings'][$name];
}
else {
$settings = $display['settings'];
}
$settings += field_info_formatter_settings($formatter_type);
$instance['display'][$view_mode]['type'] = $formatter_type;
$formatter = field_info_formatter_types($formatter_type);
$instance['display'][$view_mode]['module'] = $formatter['module'];
$instance['display'][$view_mode]['settings'] = $settings;
// Base button element for the various formatter settings actions.
$base_button = array(
'#submit' => array('field_ui_formatter_settings_submit'),
'#ajax' => array(
'callback' => 'field_ui_formatter_settings_js',
'wrapper' => 'field-display-overview-wrapper',
'effect' => 'fade',
),
'#field_name' => $name,
);
if ($form_state['formatter_settings_edit'] == $name) {
// We are currently editing this field's formatter settings. Display the
// settings form and submit buttons.
$table[$name]['settings_edit_form'] = array();
$additions = module_invoke($formatter['module'], 'field_formatter_settings_form', $field, $instance, $view_mode, $form, $form_state);
if (is_array($additions)) {
$table[$name]['settings_edit_form'] = array(
'#type' => 'container',
'#attributes' => array('class' => array('field-formatter-settings-edit-form')),
);
$table[$name]['settings_edit_form']['label'] = array(
'#markup' => t('Format settings:') . ' <span class="formatter-name">' . $formatter['label'] . '</span>',
);
$table[$name]['settings_edit_form']['settings'] = $additions;
$table[$name]['settings_edit_form']['actions'] = array('#type' => 'actions');
$table[$name]['settings_edit_form']['actions']['save_settings'] = $base_button + array(
'#type' => 'submit',
'#name' => $name . '_formatter_settings_update',
'#value' => t('Update'),
'#op' => 'update',
);
$table[$name]['settings_edit_form']['actions']['cancel_settings'] = $base_button + array(
'#type' => 'submit',
'#name' => $name . '_formatter_settings_cancel',
'#value' => t('Cancel'),
'#op' => 'cancel',
// Do not check errors for the 'Cancel' button.
'#limit_validation_errors' => array(),
);
$table[$name]['#settings_editing'] = TRUE;
// When formatter is changed, cancel the currently edited settings. The
// select 'formatter type' input is hidden in editing mode, so this only
// happens is the row is dragged into the 'hidden' section.
$table[$name]['type']['#ajax']['trigger_as'] = array('name' => $name . '_formatter_settings_cancel');
}
}
else {
// Display a summary of the current formatter settings.
$summary = module_invoke($formatter['module'], 'field_formatter_settings_summary', $field, $instance, $view_mode);
$table[$name]['settings_summary'] = array();
$table[$name]['settings_edit'] = array();
if ($summary) {
$table[$name]['settings_summary'] = array(
'#markup' => '<div class="field-formatter-summary">' . $summary . '</div>',
);
$table[$name]['settings_edit'] = $base_button + array(
'#type' => 'image_button',
'#name' => $name . '_formatter_settings_edit',
'#src' => 'misc/configure.png',
'#attributes' => array('class' => array('field-formatter-settings-edit'), 'alt' => t('Edit')),
'#op' => 'edit',
// Do not check errors for the 'Edit' button.
'#limit_validation_errors' => array(),
'#prefix' => '<div class="field-formatter-settings-edit-wrapper">',
'#suffix' => '</div>',
);
}
}
$table['#field_rows'][] = $name;
// Collect default formatters for the JS script.
@ -796,8 +901,11 @@ function field_ui_display_overview_form($form, &$form_state, $entity_type, $bund
'#options' => $extra_visibility_options,
'#default_value' => $display['visible'] ? 'visible' : 'hidden',
);
$table[$name]['settings_summary'] = array();
$table[$name]['settings_edit'] = array();
$table['#field_rows'][] = $name;
}
$form['settings'] = $table;
// Custom display settings.
@ -834,11 +942,73 @@ function field_ui_display_overview_form($form, &$form_state, $entity_type, $bund
$form['#attached']['js'][] = drupal_get_path('module', 'field_ui') . '/field_ui.js';
$form['#attached']['css'][] = drupal_get_path('module', 'field_ui') . '/field_ui.css';
drupal_add_js(array('fieldDefaultFormatters' => $default_formatters), 'setting');
return $form;
}
/**
* Form submit handler for the formatter settings buttons.
*/
function field_ui_formatter_settings_submit($form, &$form_state) {
$trigger = $form_state['triggering_element'];
$field_name = $trigger['#field_name'];
$op = $trigger['#op'];
switch ($op) {
case 'edit':
// Store the field whose settings are currently being edited.
$form_state['formatter_settings_edit'] = $field_name;
break;
case 'update':
// Store the saved settings.
$values = $form_state['values']['settings'][$field_name]['settings_edit_form']['settings'];
$form_state['formatter_settings'][$field_name] = $values;
// Fall-through to the 'cancel' case.
case 'cancel':
// Unset the field as being currently edited.
$form_state['formatter_settings_edit'] = NULL;
break;
}
$form_state['rebuild'] = TRUE;
}
/**
* AJAX handler for the formatter settings buttons.
*/
function field_ui_formatter_settings_js($form, &$form_state) {
$trigger = $form_state['triggering_element'];
$field_name = $trigger['#field_name'];
$op = $trigger['#op'];
// Apply the AJAX effect to updated elements.
switch ($op) {
case 'change_type':
$updated = array('settings_summary');
break;
case 'edit':
$updated = array('settings_edit_form');
break;
case 'update':
case 'cancel':
$updated = array('type', 'settings_summary', 'settings_edit');
break;
}
foreach ($updated as $key) {
$element = &$form['settings'][$field_name][$key];
$element['#prefix'] = '<div class="ajax-new-content">' . (isset($element['#prefix']) ? $element['#prefix'] : '');
$element['#suffix'] = (isset($element['#suffix']) ? $element['#suffix'] : '') . '</div>';
}
return $form['settings'];
}
/**
* Theme preprocess function for field_ui-display-overview-table.tpl.php.
*/
@ -867,17 +1037,15 @@ function template_preprocess_field_ui_display_overview_table(&$vars) {
$row = new stdClass();
foreach (element_children($element) as $child) {
if (array_key_exists('label', $element[$child])) {
$row->{$child} = new stdClass();
$row->{$child}->label = drupal_render($element[$child]['label']);
$row->{$child}->type = drupal_render($element[$child]['type']);
}
else {
$row->{$child} = drupal_render($element[$child]);
}
$row->{$child} = drupal_render($element[$child]);
}
$row->settings_class = (!empty($element['#settings_class']) ? $element['#settings_class'] : '');
$row->class = 'draggable';
if (isset($element['#settings_editing'])) {
$row->class .= ' field-formatter-settings-editing';
}
$row->label_class = 'label-field';
$row->id = 'row-' . strtr($key, '_', '-');
$rows[$visibility][] = $row;
}
}
@ -897,7 +1065,29 @@ function field_ui_display_overview_form_submit($form, &$form_state) {
// Save data for 'regular' fields.
foreach ($form['#fields'] as $field_name) {
$instance = field_info_instance($entity_type, $field_name, $bundle);
$instance['display'][$view_mode] = $form_values['settings'][$field_name];
$values = $form_values['settings'][$field_name];
// Get formatter settings. They lie either directly in submitted form
// values (if the whole form was submitted while some formatter
// settings were being edited), or have been persisted in
// $form_state.
$settings = $instance['display'][$view_mode]['settings'];
if (isset($values['settings_edit_form']['settings'])) {
$settings = $values['settings_edit_form']['settings'];
}
elseif (isset($form_state['formatter_settings'][$field_name])) {
$settings = $form_state['formatter_settings'][$field_name];
}
// Only save settings actually used by the selected formatter.
$default_settings = field_info_formatter_settings($values['type']);
$settings = array_intersect_key($settings, $default_settings);
$instance['display'][$view_mode] = array(
'label' => $values['label'],
'type' => $values['type'],
'weight' => $values['weight'],
'settings' => $settings,
);
field_update_instance($instance);
}

View File

@ -131,6 +131,71 @@ function hook_field_widget_settings_form($field, $instance) {
return $form;
}
/**
* Returns form elements for a formatter's settings.
*
* @param $field
* The field structure being configured.
* @param $instance
* The instance structure being configured.
* @param $view_mode
* The view mode being configured.
* @param $form
* The (entire) configuration form array, which will usually have no use here.
* @param $form_state
* The form state of the (entire) configuration form.
*
* @return
* The form elements for the formatter settings.
*/
function hook_field_formatter_settings_form($field, $instance, $view_mode, $form, &$form_state) {
$display = $instance['display'][$view_mode];
$settings = $display['settings'];
$element = array();
if ($display['type'] == 'text_trimmed' || $display['type'] == 'text_summary_or_trimmed') {
$element['trim_length'] = array(
'#title' => t('Length'),
'#type' => 'textfield',
'#size' => 20,
'#default_value' => $settings['trim_length'],
'#element_validate' => array('_element_validate_integer_positive'),
'#required' => TRUE,
);
}
return $element;
}
/**
* Returns a short summary for the current formatter settings of an instance.
*
* @param $field
* The field structure.
* @param $instance
* The instance structure.
* @param $view_mode
* The view mode for which a settings summary is requested.
*
* @return
* A string containing a short summary of the formatter settings.
*/
function hook_field_formatter_settings_summary($field, $instance, $view_mode) {
$display = $instance['display'][$view_mode];
$settings = $display['settings'];
$summary = '';
if ($display['type'] == 'text_trimmed' || $display['type'] == 'text_summary_or_trimmed') {
$summary = t('Length: @chars chars', array('@chars' => $settings['trim_length']));
}
return $summary;
}
/**
* @} End of "ingroup field_ui_field_type"
*/

View File

@ -15,10 +15,37 @@
padding-bottom: .5em;
}
/* Manage display */
/* 'Manage display' overview */
.field-display-overview tr.region-title td {
font-weight: bold;
}
.field-display-overview tr.region-populated {
display: none;
}
.field-display-overview .field-formatter-summary-cell {
line-height: 1em;
}
.field-display-overview .field-formatter-summary {
float: left;
font-size: 0.9em;
}
.field-display-overview td.field-formatter-summary-cell span.warning {
display: block;
float: left;
margin-right: .5em;
}
.field-display-overview .field-formatter-settings-edit-wrapper {
float: right;
}
.field-display-overview .field-formatter-settings-edit {
float: right;
}
.field-display-overview tr.field-formatter-settings-editing td {
vertical-align: top;
}
.field-display-overview tr.field-formatter-settings-editing .field-formatter-type {
display: none;
}
.field-display-overview .field-formatter-settings-edit-form .formatter-name{
font-weight: bold;
}

View File

@ -134,6 +134,8 @@ Drupal.behaviors.fieldManageDisplayDrag = {
var value = 'hidden';
}
$select.val(value);
// Fire AJAX update of formatter settings.
$select.change();
}
$select.removeData('noUpdate');
}

View File

@ -940,6 +940,28 @@ div.add-or-remove-shortcuts {
border: #ccc 1px solid;
}
/* Field UI */
.field-display-overview input.field-formatter-settings-edit {
margin: 0;
padding: 1px 8px;
}
.field-display-overview tr.field-formatter-settings-changed {
background: #FFFFBB;
}
.field-display-overview tr.drag {
background: #FFEE77;
}
.field-display-overview tr.field-formatter-settings-editing {
background: #D5E9F2;
}
.field-display-overview .field-formatter-settings-edit-form .form-item {
margin: 10px 0;
}
.field-display-overview .field-formatter-settings-edit-form .form-submit {
margin-bottom: 0;
}
/* Recent content block */
#dashboard div#block-node-recent div.content {
padding: 0;