Rearranging subfields with the Address Field module Is there a way to rearrange the fields within the widget with a specific hook? Should I use hook_form_alter()?

To be more specific, I want to put the country field below the zip-code field when using the Address Field module.
I have two solutions for it:


hook_field_widget_form_alter() 
Ctools plugin


Solution 1. hook_field_widget_form_alter().

/**
 * Implements hook_field_widget_form_alter().
 */
function MYMODULE_field_widget_form_alter(&amp;$element, $form_state, $context) {
  if(!empty($element['#addressfield'])) {
    $element['country']['#weight'] = 100;
  }
}


Use $element and $context arrays and implement own IF statement. You can find all the information about the field and user here.

Solution 2. Ctools plugin

It's possible with ctools plugins. Review addressfield/plugins/format/ or https://drupal.org/project/addressfield_vn as an example.

Just add your custom plugin with addressfield alter in 5 steps:

Step 1: Create MYMODULE/plugins/format/ folders structure.

Step 2: Add next code to your MYMODULE.module file:

/**
 * Implements hook_ctools_plugin_directory().
 */
function MYMODULE_ctools_plugin_directory($module, $plugin) {
  if ($module == 'addressfield') {
    return 'plugins/' . $plugin;
  }
}

/**
 * Implements hook_ctools_plugin_type().
 */
function MYMODULE_ctools_plugin_type() {
  $plugins['format'] = array(
    'load themes' =&gt; TRUE,
  );
  return $plugins;
}


Step 3: Add file with alter code. E.g.: MYMODULE/plugins/format/address-alter.inc:



/**
 * @file
 * Move country field to the very end.
 */

$plugin = array(
  'title' =&gt; t('Alter addressfield'),
  'format callback' =&gt; 'MYMODULE_format_address_alter_country',
  'type' =&gt; 'address',
  'weight' =&gt; -80,
);

/**
 * Format callback.
 *
 * @see CALLBACK_addressfield_format_callback()
 */
function MYMODULE_format_address_alter_country(&amp;$format, $address, $context = array()) {
  // Move country field to the very end.
  $format['country']['#weight'] = 100;
}


Step 4: drush cc all

Step 5: Enable your plugin for addressfield in customer profile fields settings. E.g. at /admin/commerce/customer-profiles/types/billing/fields/commerce_customer_address

In the current example all the alter code will be inside the MYMODULE_format_address_alter_country() function. Just play with weights of your fields and you'll get the form rearranged.