Form Summaries

The form summaries system in Ubercart 2.x is an extension of the core Drupal Forms API. It allows modules to automatically build form summaries based on data in the actual form array. In Ubercart, these summaries are most notably used on configuration overview pages. Using the form summaries system, contributed modules can represent their forms and form elements added to core settings forms by simply accommodating the summaries system. The system works through the Forms API by defining new attributes you can add to form element arrays. When a module wants to build a summary of a single form element, an entire form, or a set of forms located on pages beneath a specific menu path, the summaries system will load up the form array in question and generated a summary for each element in a form based on these attributes. Summary data is rendered in an array compatible with the theme_item_list() function, though the system also includes a theme function to render summaries as displayed on the configuration overview pages. Pay attention to the fact that a form summary does not recursively walk through every level of a form array. It will typically attempt to summarize all the top level elements of the form, though by default it also summarizes child elements of fieldsets. You can set the #summary callback as described below on any element in an array to use summarize_form() so that it generates a summary of the elements beneath it.

Forms API attributes:

These attributes are prefixed with # like other FAPI element attributes. Summaries can be defined in your forms or altered in through hook_form_alter().

#summary

This should be the basic summary text. With no other options, this text will be displayed in a summary using the format of #title: #summary. Example:
<?php
 
// Example from uc_cart.admin.inc function uc_cart_cart_settings_form().
 
$form['general']['uc_minimum_subtotal'] = array(
   
'#type' => 'textfield',
   
'#title' => t('Minimum order subtotal'),
   
'#description' => t('Optionally specify a minimum allowed subtotal for a cart to proceed to checkout.'),
   
'#summary' => uc_currency_format(variable_get('uc_minimum_subtotal', 0)),
   
'#default_value' => variable_get('uc_minimum_subtotal', 0),
    ...
  );
?>

#summary callback

The function the form element array gets passed to generate the summary. Most summaries won't need to set this and can simply use the default callback summarize_element(). Here are three examples where it makes sense to define and use your own summary callback.
  1. First, for fieldsets, the default behavior is for the summary to be represented as the title of the fieldset with child element summaries nested beneath it: If you don't want to list the title with nested child elements, you can use the summarize_form() function. This will add a summary of the fieldset's child elements in line with other elements on the form summary:
    <?php
     
    // Example from uc_cart.admin.inc function uc_cart_cart_settings_form().
     
    $form['general'] = array(
       
    '#type' => 'fieldset',
       
    '#title' => t('General cart settings'),
       
    '#summary callback' => 'summarize_form',
      );
    ?>
  2. Second, some elements have summarize functions defined in summaries.inc that may be called directly using element specific arguments.
    <?php
     
    // This function is defined in summaries.inc for use by modules...
      /**
       * Returns the correct summary string for a checkbox element based on its
       *   current value.
       *
       * @param $true
       *   The summary string to use if the checkbox has been checked.
       * @param $false
       *   The summary string to use if the checkbox has not been checked.
       * @return
       *   The correct supplied string based on the current value of the checkbox.
       */
     
    function summarize_checkbox($form, $true, $false) {
        if (
    $form['#default_value']) {
          return
    $true;
        }
        else {
          return
    $false;
        }
      }

     
    // Example from uc_cart.admin.inc function uc_cart_checkout_settings_form().
     
    $form['completion']['uc_new_customer_email'] = array(
       
    '#type' => 'checkbox',
       
    '#title' => t('Send new customers a separate e-mail with their account details.'),
       
    '#summary callback' => 'summarize_checkbox',
       
    '#summary arguments' => array(
         
    t('Anonymous customers are e-mailed user details.'),
         
    t('Anonymous customers are not e-mailed user details.')
        ),
       
    '#default_value' => variable_get('uc_new_customer_email', TRUE),
      );
    ?>
  3. Third, you can summarize an entire form or fieldset with a replacement function when it doesn't make sense or is impossible to try and construct a summary out of child elements. Your callback should expect to receive the element array for the part of the form being summarized as its first argument.
    <?php
     
    // Example from uc_cart.admin.inc function uc_cart_cart_panes_form().
     
    $form['panes'] = array(
       
    '#theme' => 'uc_pane_sort_table',
       
    '#pane_prefix' => 'uc_cap',
       
    '#summary callback' => '_uc_cart_panes_summarize',
       
    '#summary arguments' => array($panes),
      );

     
    /**
       * Summarizes cart and checkout panes.
       *
       * @param $form
       *   The form passed from the summarizer
       * @param $panes
       *   Any array of cart/checkout panes
       * @return
       *   An array of summary information
       *
       * Although this function is called 'cart_panes', it also operates on
       * checkout panes, which are structured the same way.
       */
     
    function _uc_cart_panes_summarize($form, $panes) {
       
    $items = array();

        foreach (
    $panes as $pane) {
         
    $items[] = t('@title is @enabled.', array('@title' => $pane['title'], '@enabled' => $pane['enabled'] ? t('enabled') : t('disabled')));
        }

        return
    $items;
      }
    ?>

#summary arguments

This should be an array of arguments to pass on to the summary callback. This is useful when passing info to a custom callback or to pass additional arguments to default callbacks. In the example below, I'm passing FALSE as an argument to the default element summarizing function. This means I should display the contents of #summary as the full summary and not include the element's #title. The default summary callback summarize_element() from summaries.inc is used in the example below to simply display the #summary text as a summary for the whole fieldset.
<?php
 
// Example from uc_store.admin.inc function uc_country_formats_form().
 
$form['instructions'] = array(
   
'#type' => 'fieldset',
   
'#title' => t('Address variables instructions'),
   
'#collapsible' => TRUE,
   
'#collapsed' => TRUE,
   
'#summary' => 'Tweak the address formatting for a specific country.',
   
'#summary arguments' => array(FALSE),
  );
?>

Helper functions:

The core module summaries.inc (found in uc_store/includes) defines several helper functions for you to use when generating your summary overview. For example, if you want to embed a form summary somewhere, you can directly call summarize_form() and pass in the form array to receive back an item list array of summary text. Even more useful is the function summarize_child_form_pages() which will generate summaries for every page beneath a particular path on the Drupal site that uses drupal_get_form() as the page callback. The output of this function may be themed through theme_summary_overview() to create overview pages like Ubercart uses for its configuration overview pages. The theme function automatically includes some CSS classes and JS that will enhance these summary overviews. A short code example using these two functions to create the checkout settings overview:
<?php
 
// Displays an overview of the checkout settings.
 
function uc_cart_checkout_settings_overview() {
   
// Theme all the pages beneath this path into summary overviews.
   
return theme('summary_overview', summarize_child_form_pages('admin/store/settings/checkout/edit'));
  }
?>
See the code comments for more information on the parameters to pass to these functions.