Submitted by Damien on
Tags:
I ran into a problem recently where, on the checkout form, a Drupal 10 site running Commerce wanted to have the addresses always put the customer's name before the company name.
After digging into it I first opened a support request for the Addressing library from Commerce Guys / Centarro. After a little more digging I worked out a pull request that changed the address formats for all countries to have the customer's name before the organization.
However, one of the maintainers informed me that this was actually incorrect, that some countries have an official postal format that places the organization name first, and this is the order used to decide how the address fields show. Which makes complete sense, and I appreciate them following each country's format.
That said, my US-based client still wanted the customer's name to show before their organization name during checkout.
So I worked out a different way using the AddressFormatEvent event suggested by the Commerce maintainer.
Add this to the services.yml file of a module or profile in your site:
services:
mymodule.address_subscriber:
class: Drupal\mymodule\EventSubscriber\AddressSubscriber
tags:
- { name: event_subscriber }
(replace "mymodule" with the name of the module, and make sure there's only one line that starts with "services:")
Then create the file "src/EventSubscriber/AddressSubscriber.php":
< ?php
namespace Drupal\mymodule\EventSubscriber;
use Drupal\address\Event\AddressFormatEvent;
use Drupal\address\Event\AddressEvents;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
/**
* Logic for interacting with the address system..
*/
class AddressSubscriber implements EventSubscriberInterface {
/**
* {@inheritdoc}
*/
public static function getSubscribedEvents() {
$events = [
AddressEvents::ADDRESS_FORMAT => 'formatAddress',
];
return $events;
}
/**
* Move the organization to after the name fields.
*
* @param \Drupal\address\Event\AddressFormatEvent $event
* The address format event.
*/
public function formatAddress(AddressFormatEvent $event) {
$definition = $event->getDefinition();
$replacements = [
"%organization\n%givenName %familyName\n" => "%givenName %familyName\n%organization\n",
"%organization\n%familyName %givenName %additionalName\n" => "%familyName %givenName %additionalName\n%organization\n",
];
foreach ($replacements as $from => $to) {
if (strpos($definition['format'], $from) !== FALSE) {
$definition['format'] = str_replace($from, $to, $definition['format']);
$event->setDefinition($definition);
break;
}
}
}
}
?>Rebuild the caches, and you'll now see that all addresses for countries like Australia, Austria, etc show the first & last name fields before the organization field.

