diff options
author | Dries Buytaert <dries@buytaert.net> | 2010-05-23 19:10:23 +0000 |
---|---|---|
committer | Dries Buytaert <dries@buytaert.net> | 2010-05-23 19:10:23 +0000 |
commit | 5ff0c0d3c7757038af8ab95f5386a9fec1aa1b10 (patch) | |
tree | 96c318263445fe4df0b3d23be923f6caaefdface /modules/field_ui | |
parent | 5d4fa6f72511d4a3948d5527f9202d6cd2aa137f (diff) | |
download | brdo-5ff0c0d3c7757038af8ab95f5386a9fec1aa1b10.tar.gz brdo-5ff0c0d3c7757038af8ab95f5386a9fec1aa1b10.tar.bz2 |
- Patch #553298 by yched, te-brian, chx, sun: redesign the 'Manage Display' screen.
Diffstat (limited to 'modules/field_ui')
-rw-r--r-- | modules/field_ui/field_ui.admin.inc | 267 | ||||
-rw-r--r-- | modules/field_ui/field_ui.css | 7 | ||||
-rw-r--r-- | modules/field_ui/field_ui.js | 139 | ||||
-rw-r--r-- | modules/field_ui/field_ui.module | 200 |
4 files changed, 406 insertions, 207 deletions
diff --git a/modules/field_ui/field_ui.admin.inc b/modules/field_ui/field_ui.admin.inc index 6be92ee59..2ede71962 100644 --- a/modules/field_ui/field_ui.admin.inc +++ b/modules/field_ui/field_ui.admin.inc @@ -83,7 +83,7 @@ function field_ui_field_overview_form($form, &$form_state, $entity_type, $bundle $field_types = field_info_field_types(); $widget_types = field_info_widget_types(); - $extra = field_extra_fields($entity_type, $bundle); + $extra_fields = field_extra_fields($entity_type, $bundle, 'form'); // Store each default weight so that we can add the 'add new' rows after them. $weights = array(); @@ -93,7 +93,7 @@ function field_ui_field_overview_form($form, &$form_state, $entity_type, $bundle '#entity_type' => $entity_type, '#bundle' => $bundle, '#fields' => array_keys($instances), - '#extra' => array_keys($extra), + '#extra' => array_keys($extra_fields), '#field_rows' => array(), ); @@ -155,17 +155,17 @@ function field_ui_field_overview_form($form, &$form_state, $entity_type, $bundle } // Non-field elements. - foreach ($extra as $name => $label) { - $weight = $extra[$name]['weight']; + foreach ($extra_fields as $name => $extra_field) { + $weight = $extra_field['weight']; $form[$name] = array( 'label' => array( - '#markup' => t($extra[$name]['label']), + '#markup' => check_plain($extra_field['label']), ), 'name' => array( '#markup' => $name, ), 'description' => array( - '#markup' => isset($extra[$name]['description']) ? $extra[$name]['description'] : '', + '#markup' => isset($extra_field['description']) ? $extra_field['description'] : '', ), 'weight' => array( '#type' => 'textfield', @@ -173,10 +173,10 @@ function field_ui_field_overview_form($form, &$form_state, $entity_type, $bundle '#size' => 3, ), 'edit' => array( - '#markup' => isset($extra[$name]['edit']) ? $extra[$name]['edit'] : '', + '#markup' => isset($extra_field['edit']) ? $extra_field['edit'] : '', ), 'delete' => array( - '#markup' => isset($extra[$name]['delete']) ? $extra[$name]['delete'] : '', + '#markup' => isset($extra_field['delete']) ? $extra_field['delete'] : '', ), 'hidden_name' => array( '#type' => 'hidden', @@ -464,8 +464,9 @@ function field_ui_field_overview_form_submit($form, &$form_state) { $bundle = $form['#bundle']; $admin_path = _field_ui_bundle_admin_path($entity_type, $bundle); + $bundle_settings = field_bundle_settings($entity_type, $bundle); + // Update field weights. - $extra = array(); foreach ($form_values as $key => $values) { if (in_array($key, $form['#fields'])) { $instance = field_read_instance($entity_type, $key, $bundle); @@ -476,13 +477,11 @@ function field_ui_field_overview_form_submit($form, &$form_state) { field_update_instance($instance); } elseif (in_array($key, $form['#extra'])) { - $extra[$key] = $values['weight']; + $bundle_settings['extra_fields']['form'][$key]['weight'] = $values['weight']; } } - $extra_weights = variable_get('field_extra_weights', array()); - $extra_weights[$entity_type][$bundle] = $extra; - variable_set('field_extra_weights', $extra_weights); + field_bundle_settings($entity_type, $bundle, $bundle_settings); $destinations = array(); @@ -563,12 +562,9 @@ function field_ui_field_overview_form_submit($form, &$form_state) { } /** - * Menu callback; presents a listing of fields display settings for a bundle. - * - * This form includes form widgets to select which fields appear in teaser and - * full view modes, and how the field labels should be rendered. + * Menu callback; presents field display settings for a given view mode. */ -function field_ui_display_overview_form($form, &$form_state, $entity_type, $bundle, $view_modes_selector = 'basic') { +function field_ui_display_overview_form($form, &$form_state, $entity_type, $bundle, $view_mode) { $bundle = field_extract_bundle($entity_type, $bundle); field_ui_inactive_message($entity_type, $bundle); @@ -577,14 +573,14 @@ function field_ui_display_overview_form($form, &$form_state, $entity_type, $bund // Gather type information. $instances = field_info_instances($entity_type, $bundle); $field_types = field_info_field_types(); - $view_modes = field_ui_view_modes_tabs($entity_type, $view_modes_selector); + $extra_fields = field_extra_fields($entity_type, $bundle, 'display'); $form += array( - '#tree' => TRUE, '#entity_type' => $entity_type, '#bundle' => $bundle, + '#view_mode' => $view_mode, '#fields' => array_keys($instances), - '#contexts' => $view_modes_selector, + '#extra' => array_keys($extra_fields), ); if (empty($instances)) { @@ -592,85 +588,165 @@ function field_ui_display_overview_form($form, &$form_state, $entity_type, $bund return $form; } - // Fields. - $label_options = array( + $table = array( + '#theme' => 'field_ui_display_overview_table', + '#field_rows' => array(), + '#tree' => TRUE, + ); + + $field_label_options = array( 'above' => t('Above'), 'inline' => t('Inline'), 'hidden' => t('<Hidden>'), ); + $extra_visibility_options = array( + 'visible' => t('Visible'), + 'hidden' => t('Hidden'), + ); + foreach ($instances as $name => $instance) { - $field = field_info_field($instance['field_name']); - $weight = $instance['widget']['weight']; + $display = $instance['display'][$view_mode]; - $form[$name] = array( - 'human_name' => array('#markup' => check_plain($instance['label'])), - 'weight' => array('#type' => 'value', '#value' => $weight), + $table[$name]['human_name'] = array( + '#markup' => check_plain($instance['label']), ); - $defaults = $instance['display']; + $table[$name]['weight'] = array( + '#type' => 'textfield', + '#default_value' => $display['weight'], + '#size' => 3, + ); + $table[$name]['hidden_name'] = array( + '#type' => 'hidden', + '#default_value' => $name, + ); + $table[$name]['label'] = array( + '#type' => 'select', + '#options' => $field_label_options, + '#default_value' => $display['label'], + ); + $field = field_info_field($instance['field_name']); $formatter_options = field_ui_formatter_options($field['type']); $formatter_options['hidden'] = t('<Hidden>'); - foreach ($view_modes as $view_mode) { - $display = isset($instance['display'][$view_mode]) ? $instance['display'][$view_mode] : $instance['display']['full']; - $form[$name][$view_mode]['label'] = array( - '#type' => 'select', - '#options' => $label_options, - '#default_value' => $display['label'], - ); - $form[$name][$view_mode]['type'] = array( - '#type' => 'select', - '#options' => $formatter_options, - '#default_value' => $display['type'], - ); + $table[$name]['type'] = array( + '#type' => 'select', + '#options' => $formatter_options, + '#default_value' => $display['type'], + ); + $table['#field_rows'][] = $name; + + // Collect default formatters for the JS script. + $field_type_info = field_info_field_types($field['type']); + $default_formatters[$name] = $field_type_info['default_formatter']; + } + + // Non-field elements. + foreach ($extra_fields as $name => $extra_field) { + $display = $extra_field['display'][$view_mode]; + $table[$name]['human_name'] = array( + '#markup' => check_plain($extra_field['label']), + ); + $table[$name]['weight'] = array( + '#type' => 'textfield', + '#default_value' => $display['weight'], + '#size' => 3, + ); + $table[$name]['hidden_name'] = array( + '#type' => 'hidden', + '#default_value' => $name, + ); + $table[$name]['type'] = array( + '#type' => 'select', + '#options' => $extra_visibility_options, + '#default_value' => $display['visible'] ? 'visible' : 'hidden', + ); + $table['#field_rows'][] = $name; + } + $form['settings'] = $table; + + // Custom display settings. + if ($view_mode == 'default') { + $form['modes'] = array( + '#type' => 'fieldset', + '#title' => t('Custom display settings'), + '#collapsible' => TRUE, + '#collapsed' => TRUE, + ); + // Collect options and default values for the 'Custom display settings' + // checkboxes. + $options = array(); + $default = array(); + $entity_info = entity_get_info($entity_type); + $view_modes = $entity_info['view modes']; + $view_mode_settings = field_view_mode_settings($entity_type, $bundle); + foreach ($view_modes as $view_mode_name => $view_mode_info) { + $options[$view_mode_name] = $view_mode_info['label']; + if (!empty($view_mode_settings[$view_mode_name]['custom_settings'])) { + $default[] = $view_mode_name; + } } + $form['modes']['view_modes_custom'] = array( + '#type' => 'checkboxes', + '#title' => t('Use custom display settings for the following contexts'), + '#options' => $options, + '#default_value' => $default, + ); } $form['actions'] = array('#type' => 'actions'); $form['actions']['submit'] = array('#type' => 'submit', '#value' => t('Save')); + + $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; } /** - * Theme preprocess function for field_ui-display-overview-form.tpl.php. + * Theme preprocess function for field_ui-display-overview-table.tpl.php. */ -function template_preprocess_field_ui_display_overview_form(&$vars) { - $form = &$vars['form']; +function template_preprocess_field_ui_display_overview_table(&$vars) { + $elements = &$vars['elements']; - $contexts_selector = $form['#contexts']; - $view_modes = field_ui_view_modes_tabs($form['#entity_type'], $contexts_selector); - $entity_info = entity_get_info($form['#entity_type']); - $view_modes_info = $entity_info['view modes']; - $vars['contexts'] = array(); - foreach ($view_modes as $view_mode) { - $vars['contexts'][$view_mode] = $view_modes_info[$view_mode]['label']; - } + $rows = array( + 'visible' => array(), + 'hidden' => array(), + ); - $order = _field_ui_overview_order($form, $form['#fields']); - if (empty($order)) { - $vars['rows'] = array(); - $vars['submit'] = ''; - return; - } - $rows = array(); - foreach ($order as $key) { - $element = &$form[$key]; - $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]); + if (!empty($elements['#field_rows'])) { + drupal_add_tabledrag('field-display-overview', 'order', 'sibling', 'field-weight'); + + $order = _field_ui_overview_order($elements, $elements['#field_rows']); + foreach ($order as $key) { + $element = &$elements[$key]; + $visibility = $element['type']['#value'] == 'hidden' ? 'hidden' : 'visible'; + + // Add target classes for the tabledrag behavior. + $element['weight']['#attributes']['class'][] = 'field-weight'; + $element['hidden_name']['#attributes']['class'][] = 'field-name'; + $element['type']['#attributes']['class'][] = 'field-formatter-type'; + $element['type']['#attributes']['class'][] = "field-display-$visibility"; + $element['type']['#attributes']['class'][] = "field-name-$key"; + + $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->class = 'draggable'; + $row->label_class = 'label-field'; + $rows[$visibility][] = $row; } - $row->label_class = 'label-field'; - $rows[] = $row; } $vars['rows'] = $rows; - $vars['submit'] = drupal_render_children($form); } /** @@ -678,17 +754,46 @@ function template_preprocess_field_ui_display_overview_form(&$vars) { */ function field_ui_display_overview_form_submit($form, &$form_state) { $form_values = $form_state['values']; - foreach ($form_values as $key => $values) { - if (in_array($key, $form['#fields'])) { - $instance = field_info_instance($form['#entity_type'], $key, $form['#bundle']); - foreach ($instance['display'] as $view_mode => $display) { - if (isset($values[$view_mode])) { - $instance['display'][$view_mode] = array_merge($instance['display'][$view_mode], $values[$view_mode]); - } + $entity_type = $form['#entity_type']; + $bundle = $form['#bundle']; + $view_mode = $form['#view_mode']; + + // 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]; + field_update_instance($instance); + } + + // Get current bundle settings. + $bundle_settings = field_bundle_settings($entity_type, $bundle); + + // Save data for 'extra' fields. + foreach ($form['#extra'] as $name) { + $bundle_settings['extra_fields']['display'][$name][$view_mode] = array( + 'weight' => $form_values['settings'][$name]['weight'], + 'visible' => $form_values['settings'][$name]['type'] == 'visible', + ); + } + + // Save view modes data. + if ($view_mode == 'default') { + $entity_info = entity_get_info($entity_type); + foreach ($form_values['view_modes_custom'] as $view_mode_name => $value) { + // Display a message for each view mode newly configured to use custom + // settings. + if (!empty($value) && empty($bundle_settings['view_modes'][$view_mode_name]['custom_settings'])) { + $view_mode_label = $entity_info['view modes'][$view_mode_name]['label']; + $path = _field_ui_bundle_admin_path($entity_type, $bundle) . "/display/$view_mode_name"; + drupal_set_message(t('The %view_mode mode now uses custom display settings. You might want to <a href="@url">configure them</a>.', array('%view_mode' => $view_mode_label, '@url' => url($path)))); } - field_update_instance($instance); + $bundle_settings['view_modes'][$view_mode_name]['custom_settings'] = !empty($value); } } + + // Save updated bundle settings. + field_bundle_settings($entity_type, $bundle, $bundle_settings); + drupal_set_message(t('Your settings have been saved.')); } diff --git a/modules/field_ui/field_ui.css b/modules/field_ui/field_ui.css index 2cc52736b..43d9b78f6 100644 --- a/modules/field_ui/field_ui.css +++ b/modules/field_ui/field_ui.css @@ -16,3 +16,10 @@ padding-bottom: .5em; } +/* Manage display */ +.field-display-overview tr.region-title td { + font-weight: bold; +} +.field-display-overview tr.region-populated { + display: none; +} diff --git a/modules/field_ui/field_ui.js b/modules/field_ui/field_ui.js index b8b8e484b..02b8b79ce 100644 --- a/modules/field_ui/field_ui.js +++ b/modules/field_ui/field_ui.js @@ -81,4 +81,143 @@ jQuery.fn.fieldPopulateOptions = function (options, selected) { }); }; +/** + * Moves a field in the display settings table from visible to hidden. + * + * This behavior is dependent on the tableDrag behavior, since it uses the + * objects initialized in that behavior to update the row. + */ +Drupal.behaviors.fieldManageDisplayDrag = { + attach: function (context, settings) { + // tableDrag is required for this behavior. + if (!$('table.field-display-overview', context).length || typeof Drupal.tableDrag == 'undefined') { + return; + } + + var defaultFormatters = Drupal.settings.fieldDefaultFormatters; + var tableDrag = Drupal.tableDrag['field-display-overview']; + + // Add a handler for when a row is swapped, update empty regions. + tableDrag.row.prototype.onSwap = function (swappedRow) { + checkEmptyRegions(this.table, this); + }; + + // Add a handler to update the formatter selector when a row is dropped in + // or out of the 'Hidden' section. + tableDrag.onDrop = function () { + var dragObject = this; + var regionRow = $(dragObject.rowObject.element).prevAll('tr.region-message').get(0); + var visibility = regionRow.className.replace(/([^ ]+[ ]+)*region-([^ ]+)-message([ ]+[^ ]+)*/, '$2'); + + // Update the 'format' selector if the visibility changed. + var $select = $('select.field-formatter-type', dragObject.rowObject.element); + var oldVisibility = $select[0].className.replace(/([^ ]+[ ]+)*field-display-([^ ]+)([ ]+[^ ]+)*/, '$2'); + if (visibility != oldVisibility) { + $select.removeClass('field-display-' + oldVisibility).addClass('field-display-' + visibility); + + // Update the selected formatter if coming from an actual drag. + if (!$select.data('noUpdate')) { + if (visibility == 'visible') { + // Restore the formatter back to the previously selected one if + // available, or to the default formatter. + var value = $select.data('oldFormatter'); + if (typeof value == 'undefined') { + // Extract field name from the name of the select. + var fieldName = $select[0].className.match(/\bfield-name-(\S+)\b/)[1].replace('-', '_'); + // Pseudo-fields do not have an entry in the defaultFormatters + // array, we just return to 'visible' for those. + value = (fieldName in defaultFormatters) ? defaultFormatters[fieldName] : 'visible'; + } + $select.data('oldFormatter', value); + } + else { + var value = 'hidden'; + } + $select.val(value); + } + $select.removeData('noUpdate'); + } + }; + + // Add the behavior to each formatter select list. + $('select.field-formatter-type', context).once('field-formatter-type', function () { + // Initialize 'previously selected formatter' as the incoming value. + if ($(this).val() != 'hidden') { + $(this).data('oldFormatter', $(this).val()); + } + + // Add change listener. + $(this).change(function (event) { + var $select = $(this); + var value = $select.val(); + + // Keep track of the last selected formatter. + if (value != 'hidden') { + $select.data('oldFormatter', value); + } + + var visibility = (value == 'hidden') ? 'hidden' : 'visible'; + var oldVisibility = $select[0].className.replace(/([^ ]+[ ]+)*field-display-([^ ]+)([ ]+[^ ]+)*/, '$2'); + if (visibility != oldVisibility) { + // Prevent the onDrop handler from overriding the selected option. + $select.data('noUpdate', true); + + // Make our new row and select field. + var $row = $(this).parents('tr:first'); + var $table = $(this).parents('table'); + var tableDrag = Drupal.tableDrag[$table.attr('id')]; + tableDrag.rowObject = new tableDrag.row($row); + + // Move the row at the bottom of the new section. + if (visibility == 'hidden') { + $('tr:last', tableDrag.table).after($row); + } + else { + $('tr.region-title-hidden', tableDrag.table).before($row); + } + + // Manually update weights and restripe. + tableDrag.updateFields($row.get(0)); + tableDrag.rowObject.changed = true; + if (tableDrag.oldRowElement) { + $(tableDrag.oldRowElement).removeClass('drag-previous'); + } + tableDrag.oldRowElement = $row.get(0); + tableDrag.restripeTable(); + tableDrag.rowObject.markChanged(); + tableDrag.oldRowElement = $row; + $row.addClass('drag-previous'); + + // Modify empty regions with added or removed fields. + checkEmptyRegions($table, tableDrag.rowObject); + } + + // Remove focus from selectbox. + $select.get(0).blur(); + }); + }); + + var checkEmptyRegions = function ($table, rowObject) { + $('tr.region-message', $table).each(function () { + // If the dragged row is in this region, but above the message row, swap + // it down one space. + if ($(this).prev('tr').get(0) == rowObject.element) { + // Prevent a recursion problem when using the keyboard to move rows up. + if ((rowObject.method != 'keyboard' || rowObject.direction == 'down')) { + rowObject.swap('after', this); + } + } + // This region has become empty. + if ($(this).next('tr').is(':not(.draggable)') || $(this).next('tr').length == 0) { + $(this).removeClass('region-populated').addClass('region-empty'); + } + // This region has become populated. + else if ($(this).is('.region-empty')) { + $(this).removeClass('region-empty').addClass('region-populated'); + } + }); + }; + } +}; + })(jQuery); diff --git a/modules/field_ui/field_ui.module b/modules/field_ui/field_ui.module index 3bb5cd886..470abe6d7 100644 --- a/modules/field_ui/field_ui.module +++ b/modules/field_ui/field_ui.module @@ -49,6 +49,24 @@ function field_ui_help($path, $arg) { } /** + * Implements hook_theme(). + */ +function field_ui_theme() { + return array( + 'field_ui_field_overview_form' => array( + 'render element' => 'form', + 'file' => 'field_ui.admin.inc', + 'template' => 'field_ui-field-overview-form', + ), + 'field_ui_display_overview_table' => array( + 'render element' => 'elements', + 'file' => 'field_ui.admin.inc', + 'template' => 'field_ui-display-overview-table', + ), + ); +} + +/** * Implements hook_menu(). */ function field_ui_menu() { @@ -66,10 +84,11 @@ function field_ui_menu() { if (defined('MAINTENANCE_MODE')) { return $items; } + // Create tabs for all possible bundles. - foreach (entity_get_info() as $entity_type => $info) { - if ($info['fieldable']) { - foreach ($info['bundles'] as $bundle_name => $bundle_info) { + foreach (entity_get_info() as $entity_type => $entity_info) { + if ($entity_info['fieldable']) { + foreach ($entity_info['bundles'] as $bundle_name => $bundle_info) { if (isset($bundle_info['admin'])) { // Extract path information from the bundle. $path = $bundle_info['admin']['path']; @@ -92,7 +111,12 @@ function field_ui_menu() { // items below. $field_position = count(explode('/', $path)) + 1; + // Extract access information, providing defaults. $access = array_intersect_key($bundle_info['admin'], drupal_map_assoc(array('access callback', 'access arguments'))); + $access += array( + 'access callback' => 'user_access', + 'access arguments' => array('administer site configuration'), + ); $items["$path/fields"] = array( 'title' => 'Manage fields', @@ -145,24 +169,38 @@ function field_ui_menu() { 'file' => 'field_ui.admin.inc', ) + $access; - // 'Manage display' tab and context secondary tabs. + // 'Manage display' tab. $items["$path/display"] = array( 'title' => 'Manage display', 'page callback' => 'drupal_get_form', - 'page arguments' => array('field_ui_display_overview_form', $entity_type, $bundle_arg), + 'page arguments' => array('field_ui_display_overview_form', $entity_type, $bundle_arg, 'default'), 'type' => MENU_LOCAL_TASK, 'weight' => 2, 'file' => 'field_ui.admin.inc', ) + $access; - $tabs = field_ui_view_modes_tabs($entity_type); - foreach ($tabs as $key => $tab) { - $items["$path/display/$key"] = array( - 'title' => $tab['title'], - 'page arguments' => array('field_ui_display_overview_form', $entity_type, $bundle_arg, $key), - 'type' => $key == 'basic' ? MENU_DEFAULT_LOCAL_TASK : MENU_LOCAL_TASK, - 'weight' => $key == 'basic' ? 0 : 1, + + // View modes secondary tabs. + // The same base $path for the menu item (with a placeholder) can be + // used for all bundles of a given entity type; but depending on + // administrator settings, each bundle has a different set of view + // modes available for customisation. So we define menu items for all + // view modes, and use an access callback to determine which ones are + // actually visible for a given bundle. + $weight = 0; + $view_modes = array('default' => array('label' => t('Default'))) + $entity_info['view modes']; + foreach ($view_modes as $view_mode => $view_mode_info) { + $items["$path/display/$view_mode"] = array( + 'title' => $view_mode_info['label'], + 'page arguments' => array('field_ui_display_overview_form', $entity_type, $bundle_arg, $view_mode), + // The access callback needs to check both the current 'custom + // display' setting for the view mode, and the overall access + // rules for the bundle admin pages. + 'access callback' => '_field_ui_view_mode_menu_access', + 'access arguments' => array_merge(array($entity_type, $bundle_arg, $view_mode, $access['access callback']), $access['access arguments']), + 'type' => ($view_mode == 'default' ? MENU_DEFAULT_LOCAL_TASK : MENU_LOCAL_TASK), + 'weight' => ($view_mode == 'default' ? -10 : $weight++), 'file' => 'field_ui.admin.inc', - ) + $access; + ); } } } @@ -219,100 +257,35 @@ function field_ui_menu_title($instance) { } /** - * Implements hook_theme(). + * Menu access callback for the 'view mode display settings' pages. */ -function field_ui_theme() { - return array( - 'field_ui_field_overview_form' => array( - 'render element' => 'form', - 'file' => 'field_ui.admin.inc', - 'template' => 'field_ui-field-overview-form', - ), - 'field_ui_display_overview_form' => array( - 'render element' => 'form', - 'file' => 'field_ui.admin.inc', - 'template' => 'field_ui-display-overview-form', - ), - ); -} +function _field_ui_view_mode_menu_access($entity_type, $bundle, $view_mode, $access_callback) { + // First, determine visibility according to the 'use custom display' + // setting for the view mode. + $bundle = field_extract_bundle($entity_type, $bundle); + $view_mode_settings = field_view_mode_settings($entity_type, $bundle); + $visibility = ($view_mode == 'default') || !empty($view_mode_settings[$view_mode]['custom_settings']); -/** - * Returns information about tab groups for view modes on an entity type. - * - * On the 'Manage display' page, an administrator can manage the display of - * fields for each view mode for an entity type. The view modes are organized - * into tabs. This function returns the list of entity types to display on - * each tab, as well as the titles of the tabs. - * - * @param $entity_type - * The type of entity to return tab information for. - * @param $tab_selector - * If not NULL, return only information for this particular tab; if NULL, - * return all tab information. - * - * @return - * Array of information about the tabs to display. The keys are internal-use - * tab names and the values are arrays of tab information, with the following - * elements: - * - 'title': Human-readable title of the tab. - * - 'view modes': Array of view modes for this entity type that should - * be displayed on this tab. - * - * @see hook_field_ui_view_modes_tabs() - * - * @todo Remove this completely and use vertical tabs? - */ -function field_ui_view_modes_tabs($entity_type, $tab_selector = NULL) { - $info = &drupal_static(__FUNCTION__); - - if (!isset($info[$entity_type])) { - $info[$entity_type] = module_invoke_all('field_ui_view_modes_tabs', $entity_type); - // Filter out inactive modes. - $entity_info = entity_get_info($entity_type); - foreach ($info[$entity_type] as $tab => $values) { - $modes = array(); - foreach ($info[$entity_type][$tab]['view modes'] as $mode) { - if (isset($entity_info['view modes'][$mode])) { - $modes[] = $mode; - } - } - if ($modes) { - $info[$entity_type][$tab]['view modes'] = $modes; + // Then, determine access according to the $access parameter. This duplicates + // part of _menu_check_access(). + if ($visibility) { + // Grab the variable 'access arguments' part. + $args = array_slice(func_get_args(), 4); + $callback = empty($access_callback) ? 0 : trim($access_callback); + if (is_numeric($callback)) { + return (bool) $callback; + } + else { + // As call_user_func_array() is quite slow and user_access is a very + // common callback, it is worth making a special case for it. + if ($access_callback == 'user_access') { + return (count($args) == 1) ? user_access($args[0]) : user_access($args[0], $args[1]); } - else { - unset($info[$entity_type][$tab]); + elseif (function_exists($access_callback)) { + return call_user_func_array($access_callback, $args); } } } - if ($tab_selector) { - return isset($info[$entity_type][$tab_selector]) ? $info[$entity_type][$tab_selector]['view modes'] : array(); - } - return $info[$entity_type]; -} - -/** - * Implements hook_field_ui_view_modes_tabs() on behalf of other core modules. - */ -function field_ui_field_ui_view_modes_tabs() { - $modes = array( - 'basic' => array( - 'title' => t('Basic'), - 'view modes' => array('teaser', 'full'), - ), - 'rss' => array( - 'title' => t('RSS'), - 'view modes' => array('rss'), - ), - 'print' => array( - 'title' => t('Print'), - 'view modes' => array('print'), - ), - 'search' => array( - 'title' => t('Search'), - 'view modes' => array('search_index', 'search_result'), - ), - ); - return $modes; } /** @@ -325,31 +298,6 @@ function field_ui_field_attach_create_bundle($entity_type, $bundle) { } /** - * Implements hook_field_attach_rename_bundle(). - */ -function field_ui_field_attach_rename_bundle($entity_type, $bundle_old, $bundle_new) { - if ($bundle_old !== $bundle_new) { - $extra_weights = variable_get('field_extra_weights', array()); - if (isset($info[$entity_type][$bundle_old])) { - $extra_weights[$entity_type][$bundle_new] = $extra_weights[$entity_type][$bundle_old]; - unset($extra_weights[$entity_type][$bundle_old]); - variable_set('field_extra_weights', $extra_weights); - } - } -} - -/** - * Implements hook_field_attach_delete_bundle(). - */ -function field_ui_field_attach_delete_bundle($entity_type, $bundle) { - $extra_weights = variable_get('field_extra_weights', array()); - if (isset($extra_weights[$entity_type][$bundle])) { - unset($extra_weights[$entity_type][$bundle]); - variable_set('field_extra_weights', $extra_weights); - } -} - -/** * Helper function to create the right administration path for a bundle. */ function _field_ui_bundle_admin_path($entity_type, $bundle_name) { |