Address
4 min read
Stores a structured address as an object using an international format (V1).
The field renders multiple inputs (street, city, state, postal code, country) and saves a single structured value, including a pre-built formatted string for display or search.
Use Cases #
- Collect shipping or billing-style addresses
- Store contact or location addresses for directories, CPTs, or users
- Save addresses in a structured format for integrations (ERP/CRM/SAP)
- Normalize country values using ISO2 codes
- Provide a formatted address string for display or search
Field Preview #
A multi-line address form UI:
- Street address (line 1)
- Optional street line 2
- City
- Optional state / province
- Optional postal code
- Country dropdown (ISO2)
How to Use #
- Add the Address field to a Field Group.
- (Optional) Set Default country (ISO2) (example
MX). - Choose which optional inputs should be visible (street 2, state, postal code).
- Choose which inputs are required (street 1, city, country).
- Save the Field Group and edit a post (or render it in
acf_form). - No custom code is required.
Field Settings #
| Setting | Description | Default |
|---|---|---|
| Default country (ISO2) | ISO2 code used when no country is selected | Empty |
| Show optional fields | Controls optional inputs visibility (street 2, state, postal code) | All enabled |
| Required fields | Controls required validation rules (street 1, city, country) | street 1 + city + country |
Notes:
- Country values are stored as ISO2 codes (example
MX,US). - Country list is loaded from an internal JSON file (
countries.json).
Value & Storage #
Saved as: Post meta
Storage type: Structured array (object)
Return format: array (or empty array when missing/invalid)
| REST format: object | null |
Country format: ISO2 uppercase
Additional field: formatted is saved automatically
Saved structure:
street_1(string)street_2(string)city(string)state(string)postcode(string)country(string, ISO2)formatted(string, multi-line)
Important details:
- Hidden optional fields are saved as empty strings.
formattedis regenerated during save based on current settings and values.formattedis intended for display/search, not as a replacement for the structured fields.
Output Examples #
PHP (Get full address object) #
$address = get_field('my_address');
if (is_array($address)) {
echo nl2br(esc_html($address['formatted'] ?? ''));
}
PHP (Access individual parts) #
$address = get_field('my_address');
$city = is_array($address) ? ($address['city'] ?? '') : '';
$country = is_array($address) ? ($address['country'] ?? '') : '';
echo esc_html($city . ', ' . $country);
Twig #
{% set address = fn('get_field', 'my_address') %}
{{ address.formatted|default('') }}
Compatibility #
- Repeaters
- Flexible Content
- Options Pages
- Frontend forms (acf_form)
- REST API (schema, formatting, validation)
- Multisite
Hooks (Developer) #
Hooks Summary #
| Hook | Type | Purpose |
|---|---|---|
| custom_fields_booster_address_defaults | Filter | Modify default settings and placeholders. |
| custom_fields_booster_address_supports | Filter | Modify ACF support flags. |
| custom_fields_booster_address_before_settings | Action | Run logic before rendering settings UI. |
| custom_fields_booster_address_after_settings | Action | Run logic after rendering settings UI. |
| custom_fields_booster_address_before_enqueue | Action | Run logic before enqueuing assets. |
| custom_fields_booster_address_after_enqueue | Action | Run logic after enqueuing assets. |
| custom_fields_booster_address_before_render | Action | Run logic before rendering UI. |
| custom_fields_booster_address_after_render | Action | Run logic after rendering UI. |
| custom_fields_booster_address_update_value | Filter | Modify the value before saving. |
| custom_fields_booster_address_load_value | Filter | Modify the value after loading. |
| custom_fields_booster_address_validate_value | Filter | Modify validation result. |
| custom_fields_booster_address_format_value | Filter | Modify value returned by get_field(). |
Filters #
Defaults #
Filter: custom_fields_booster_address_defaults
Purpose: Override default placeholders, required flags, and visible fields.
When: You want consistent defaults across all Address fields.
add_filter('custom_fields_booster_address_defaults', function ($defaults) {
$defaults['default_country'] = 'MX';
$defaults['require_country'] = 1;
$defaults['show_postcode'] = 0;
return $defaults;
});
Supports #
Filter: custom_fields_booster_address_supports
Purpose: Control ACF supports such as required or escaping behavior.
When: Your project needs different support flags.
add_filter('custom_fields_booster_address_supports', function ($supports) {
$supports['required'] = false;
return $supports;
});
Update Value #
Filter: custom_fields_booster_address_update_value
Purpose: Modify the sanitized structured address before it is saved.
When: You need normalization, enrichment, or compatibility transformations.
add_filter('custom_fields_booster_address_update_value', function ($out, $post_id, $field) {
if (!empty($out['country'])) {
$out['country'] = strtolower($out['country']);
}
return $out;
}, 10, 3);
Load Value #
Filter: custom_fields_booster_address_load_value
Purpose: Modify the value after loading from storage.
When: You want to normalize missing keys or apply defaults on load.
add_filter('custom_fields_booster_address_load_value', function ($value, $post_id, $field) {
return is_array($value) ? $value : array();
}, 10, 3);
Validate Value #
Filter: custom_fields_booster_address_validate_value
Purpose: Modify the validation result.
When: You need custom validation logic.
add_filter('custom_fields_booster_address_validate_value', function ($valid, $value, $field, $input) {
return $valid;
}, 10, 4);
Format Value (Return) #
Filter: custom_fields_booster_address_format_value
Purpose: Modify value returned by get_field() and REST output formatting.
When: You want to normalize missing keys or add computed keys.
add_filter('custom_fields_booster_address_format_value', function ($value, $post_id, $field) {
$value = is_array($value) ? $value : array();
$value += array(
'street_1' => '',
'street_2' => '',
'city' => '',
'state' => '',
'postcode' => '',
'country' => '',
'formatted' => '',
);
return $value;
}, 10, 3);
Actions #
Before Render #
Action: custom_fields_booster_address_before_render
Runs before rendering the field UI and provides the countries dataset.
add_action('custom_fields_booster_address_before_render', function ($field, $countries) {
// Pre-render logic.
}, 10, 2);
After Render #
Action: custom_fields_booster_address_after_render
Runs after rendering the field UI and provides the countries dataset.
add_action('custom_fields_booster_address_after_render', function ($field, $countries) {
// Post-render logic.
}, 10, 2);
Assets #
This field enqueues styles whenever the input is rendered (admin and frontend via acf_form()):
admin/css/cfb-field-address.css
REST API #
| Schema: object | null |
Properties: street_1, street_2, city, state, postcode, country, formatted
Notes: formatted is included in REST output when available.
Example REST output:
{
"my_address": {
"street_1": "Av. Siempre Viva 742",
"street_2": "Depto 4B",
"city": "Merida",
"state": "Yucatan",
"postcode": "97000",
"country": "MX",
"formatted": "Av. Siempre Viva 742\nDepto 4B\nMerida, Yucatan, 97000\nMX"
}
}
REST Validation #
nullis allowed.- Non-array values are rejected with a validation error message.
Security & Escaping #
- Values are sanitized on save using
sanitize_text_field(). - Country codes are normalized to uppercase.
- Output should be escaped in templates (
esc_html,nl2br, etc.). escaping_htmlsupport is set to false to avoid unwanted transformations in structured values.
Notes / Limitations #
- This field stores a structured value, not a single string.
formattedis generated at save time and depends on visibility settings.- Hidden optional fields are saved as empty strings.
- Country list depends on the internal
countries.jsondataset and must contain ISO2 codes.
Changelog #
- 1.0.0 — Initial release